0

所以我正在开发一个类“bignum”来处理任何大小的整数。问题是我做了两个不同的函数来乘以 bignums。一种是标准乘法,另一种是基于 karatsuba 算法。我有一个小程序来对我的实现进行测试,这样我就可以判断它是否工作。到目前为止,使用标准乘法,一切都运行得很好,但是当我切换到 Karatsuba 乘法时,一旦输入开始很长,我的程序就会因为堆栈溢出而因分段错误而崩溃。然而,这似乎不是条目有多大的问题,因为有更大的输入可以正确计算,尽管其中一些确实会崩溃。如果有人可以看一下并给我一些有关如何继续的线索,我将不胜感激。

Stack overflow in thread #1: can't grow stack to 0x1ffe801000

在这里,我发布了最小的可重现示例。我尽可能多地取出代码。

主要的:

#include "bignum.h"

int main()
{
    bignum result;

    while(cin >> result)
        cout << result << endl;

    return 0;
}

bignum.cc 类:

#include "bignum.h"

bignum abs(const bignum &n)
{
    bignum c = n;
    c.sign = 0;

    return c;
}

void remove_zeros(bignum &n)
{   
    if(n == 0)
        n = 0;

    else if(n.digits[0] == 0 && n.size > 1)
    {   
        size_t zeros = 1;

        while(n.digits[zeros] == 0)
            zeros++;

        n.size -= zeros;

        short_t *aux = new short_t[n.size];

        for(size_t i = 0; i < n.size; i++)
            aux[i] = n.digits[i + zeros];

        delete[] n.digits;

        n.digits = new short_t[n.size];

        for(size_t i = 0; i < n.size; i++)
            n.digits[i] = aux[i];

        delete[] aux;
    }
}

bool size_even(const bignum &n)
{
    if(n.size % 2 || n.size == 1)
        return false;

    return true;
}

bignum sum(const bignum &a, const bignum &b, const short_t &s)
{   
    size_t size = 0;
    size_t aux_a = 0;
    size_t aux_b = 0;

    if(a.size >= b.size)
    {
        size = a.size + 1;
        aux_a = a.size - b.size;
    }
    else
    {
        size = b.size + 1;
        aux_b = b.size - a.size;
    }

    bignum c(size);
    c.sign = s;

    for(size_t i = c.size - 1; i < c.size; i--)
    {   
        if(i - aux_b - 1 < a.size)
            c.digits[i] += a.digits[i - aux_b - 1];

        if(i - aux_a - 1 < b.size)
            c.digits[i] += b.digits[i - aux_a - 1];

        if(c.digits[i] > 9)
        {
            c.digits[i] -= 10;
            c.digits[i - 1]++;
        }   
    }
    remove_zeros(c);
    return c;
}

bignum subtraction(const bignum &a, const bignum &b)
{   
    short_t bigger = 0;
    short_t count = 0;
    size_t size = 0;
    size_t diff = 0;
    short aux = 0;

    size = max(a.size, b.size);
    diff = size - min(a.size, b.size);
    bignum c(size);

    if(abs(a) == abs(b))
        return c = 0;
    else if(abs(b) > abs(a))
        bigger++;

    if(bigger && b.sign && !a.sign)
        c.sign = 1;
    else if(!bigger && a.sign && !b.sign)   
        c.sign = 1;
    else if(bigger && !b.sign && !a.sign)
        c.sign = 1;
    else if(!bigger && a.sign && b.sign)
        c.sign = 1;
        
    for(size_t i = size - 1; i < size; i--)
    {   
        if(bigger)
        {
            if(i - diff < a.size)
                aux = b.digits[i] - a.digits[i - diff];
            else
                aux = b.digits[i];
        }
        else
        {
            if(i - diff < b.size)
                aux = a.digits[i] - b.digits[i - diff];
            else
                aux = a.digits[i];
        }
        if(count)
        {
            aux--;
            count--;
        }
        if(aux < 0)
        {
            aux += 10;
            count++;
        }
        c.digits[i] = aux;
    }

    remove_zeros(c);

    if(c == 0)
        c.sign = 0;

    return c; 
}

bignum reduce(const bignum &n, const size_t &from, const size_t &to)
{   
    if(to <= from)
    {
        bignum c = 0;
        return c; 
    }
    else
    {
        bignum c(to - from);
    
        for(size_t i = 0; i < c.size; i++)
        {       
            if(from + i < to)
                c.digits[i] = n.digits[from + i];
        }

        // En caso de que haya agarrado solo ceros
        if(c.digits[0] == 0 && c.size != 1)
        {
            for(size_t i = 0; i < c.size; i++)
                if(c.digits[i] != 0)
                    return c;

            return c = 0;
        }
        return c;
    }
}

bignum enlarge(const bignum &n, const size_t &zeros)
{   
    bignum c(n.size + zeros);

    if(!zeros)
        c = n;
    else
    {
        for(size_t i = 0; i < n.size; i++)
            c.digits[i] = n.digits[i];
    }
    return c;
}

void add_zeros(bignum &n, const ssize_t &zeros)
{
    if(zeros > 0)
    {
        short_t *aux = new short_t[n.size];

        for(size_t i = 0; i < n.size; i++)
            aux[i] = n.digits[i];

        delete[] n.digits;
        n.digits = new short_t[n.size += zeros];

        for(size_t i = 0; i < n.size; i++)
        {
            if(i < n.size - zeros)
                n.digits[i] = aux[i];
            else
                n.digits[i] = 0;
        }
        delete[] aux;
    }
    else if(zeros < 0)
    {
        short_t *aux = new short_t[n.size + zeros];

        for(size_t i = 0; i < n.size + zeros; i++)
            aux[i] = n.digits[i];

        delete[] n.digits;
        n.digits = new short_t[n.size += zeros];

        for(size_t i = 0; i < n.size; i++)
                n.digits[i] = aux[i];
        
        delete[] aux;   
    }
}

bignum karatsuba(const bignum &a, const bignum &b)
{   
    bignum a_ = abs(a);
    bignum b_ = abs(b);
    bignum c;

    // Casos base
    if(a_ == 0 || b_ == 0)
        return c = 0;

    if(a_.size < 2 || b_.size < 2)
        {   
            c = mult_rec(a_, b_);

            if(a.sign != b.sign)
                c.sign = 1;

            return c;
        }

    size_t diff = max(a_.size, b_.size) - min(a_.size, b_.size);

    if(!diff)
    {   
        if(!size_even(a_.size) && !size_even(b_.size))
        {
            add_zeros(a_, 1);
            add_zeros(b_, 1);
            diff += 2;
        }
    }
    else if(a_.size > b_.size)
    {   
        if(!size_even(a_.size))
        {   
            add_zeros(a_, 1);
            add_zeros(b_, diff + 1);
            diff += 2;
        }
        else
            add_zeros(b_, diff);
    }
    else if(b_.size > a_.size)
    {   
        if(!size_even(b_.size))
        {   
            add_zeros(b_, 1);
            add_zeros(a_, diff + 1);
            diff += 2;
        }
        else
            add_zeros(a_, diff);
    }

    size_t n = a_.size; 
    size_t m = n / 2;

    bignum x = karatsuba(reduce(a_, 0, m), reduce(b_, 0, m));
    bignum y = karatsuba(reduce(a_, m, a_.size), reduce(b_, m, b_.size));
    bignum z = karatsuba(reduce(a_, 0, m) + reduce(a_, m, a_.size), 
               reduce(b_, 0, m) + reduce(b_, m, b_.size)) - x - y;

    add_zeros(x, n);
    add_zeros(z, m);

    c = x + y + z;

    if(diff)
        add_zeros(c, -diff);

    if(a.sign != b.sign)
        c.sign = 1;

    return c;
}

bignum mult_rec(const bignum &a, const bignum &b)
{   
    bignum c;

    if(a == 0 || b == 0)
        return c = 0;

    if(a == 1)  
        return c = b;

    if(b == 1)
        return c = a;
    
    return c = mult_rec(a, b - 1) + a;
}

bignum division(const bignum &a, const bignum &b, bignum &remainder)
{   
    bignum c;

    if(a == 0 || b > a)
        return c = 0;

    bignum aux = a - b;
    c = 1;

    while(1)
    {
        aux = aux - b;
        
        if(aux.sign)
        {   
            remainder = aux + b;
            break;
        }
        c = c + 1;
    }
    remove_zeros(c);
    return c;
}

bignum division_rec(const bignum &a, const bignum &b)
{   
    bignum remainder = 0;

    if(a.size < (b.size + 2))
        return division(a, b, remainder);

    return division_rec(reduce(a, b.size + 1, a.size) + (enlarge(remainder, a.size - b.size - 1)), b)
           + enlarge(division(reduce(a, 0, b.size + 1), b,remainder), a.size - b.size - 1);
}

bignum::bignum()
{   
    digits = NULL;
    size = 0;
    sign = 0;
}

bignum::bignum(const size_t &s)
{   
    if(s <= 0)
    {   
        digits = NULL;
        size = 0;
        sign = 0;
    }

    digits = new short_t[s];
    size = s;
    sign = 0;

    for (size_t i = 0; i < size; i++)
        digits[i] = 0;
}

bignum::bignum(const string &str, short_t s = 0)
{   
    string aux;
    size = str.size();
    digits = new short_t[size];

    for(size_t i = 0; i < size; i++)
    {
        aux = str[i]; 
        digits[i] = (short_t)stoi(aux);
    }
    sign = s;
}

bignum::bignum(const bignum &n)
{   
    if(!n.digits)
    {   
        digits = NULL;
        size = 0;
        sign = 0;
    }
    else
    {   
        digits = new short_t[n.size];
        size = n.size;
        sign = n.sign;

        for(size_t i = 0; i < size; i++)
             digits[i] = n.digits[i];
    }
}

bignum::bignum(const int &n)
{   
    if(n < 0)
        sign = 1;
    else
        sign = 0;

    string str = to_string(n);
    string aux;

    size = str.size()-sign;

    digits = new short_t[size];

    for(size_t i = 0; i < size; i++)
    {
        aux = str[i + sign];
        digits[i] = (short_t)stoi(aux);
    }
}

bignum& bignum::operator = (const bignum &right)
{   
    if(&right != this)
    {   
        delete[] digits;

        if(!right.digits)
        {   
            digits = NULL;
            size = 0;
            sign = 0;
        }

        else
        {   
            digits = new short_t[right.size];
            size = right.size;
            sign = right.sign;

            for(size_t i = 0; i < size; i++)
                digits[i] = right.digits[i];
        }
    }
    return *this;
}

bignum& bignum::operator = (const int &right)
{   
    bignum aux(to_string(right));

    return *this = aux;
}

bignum::~bignum() {delete[] digits;}

bignum operator + (const bignum &a, const bignum &b)
{   
    if(!a.sign && !b.sign)
        return sum(a, b, 0);

    if(!a.sign && b.sign)
        return subtraction(a, b);

    if(a.sign && !b.sign)
        return subtraction(a, b);

    return sum(a, b, 1);
}

bignum operator + (const bignum &a, const int &n)
{   
    return a + bignum(to_string(n));
}

bignum operator - (const bignum &a, const bignum &b)
{   
    if(!a.sign && !b.sign)
        return subtraction(a, b);

    if(!a.sign && b.sign)
        return sum(a, b, 0);

    if(a.sign && !b.sign)
        return sum(a, b, 1);

    return subtraction(a, b);
}

bignum operator - (const bignum &a, const int &n)
{   
    return a - bignum(to_string(n));
}

bignum operator * (const bignum &a, const bignum &b)
{   
    return karatsuba(a, b);
}

bignum operator / (const bignum &a, const bignum &b) 
{   
    bignum c;

    if(b == 0)
        return c;

    if(a == 0 || abs(b) > abs(a))
        return c = 0;

    if(abs(a) == abs(b))
    {
        if(a.sign != b.sign)
            return c = -1;
        
        return c = 1;
    }               

    if(abs(b) == 1)
    {
        c = abs(a);

        if(a.sign != b.sign)
            c.sign = 1;

        return c;
    } 

    c = division_rec(abs(a), abs(b));

    if(a.sign != b.sign)
        c.sign = 1;

    return c;
} 

ostream& operator << (ostream &os, bignum &n)
{   
    if(n.digits == NULL)
        return os;

    if(n.sign && n != 0)
        os << "-";

    for (size_t i = 0; i < n.size; i++)
        os << n.digits[i];

    delete[] n.digits;
    n.digits = NULL;

    return os;
}

istream& operator >> (istream &is, bignum &result)
{
    stack<char> operations;
    queue<string> output;
    string input;

    getline(is, input);

    if(input.empty())
        return is;

    for(size_t i = 0; i < input.size(); i++)
    {   
        if(isblank(input[i])){}
        else if(isdigit(input[i]))
        {   
            size_t pos = i++;
            size_t len = 1;
            while(isdigit(input[i]))
            {
                len++;
                i++;
            }
            i--;
            output.push(input.substr(pos, len));
        }
        else if(input[i] == '-')
        {
            size_t j = i;
            while(j != 0 && isblank(input[--j])){}

            if(isdigit(input[j]) || input[j] == ')')
            {
                if(!operations.empty())
                {
                    while(operations.top() == '-' || operations.top() == '+' || operations.top() == '*' || operations.top() == '/')
                        output.push(string{operations.pull()});
                }   
                
                operations.push(input[i]);
            }
            else
                output.push(string{"s"});
        }

        else if(input[i] == '+')
        {
            size_t j = i;
            while(j != 0 && isblank(input[--j])){}

            if(isdigit(input[j]) || input[j] == ')')
            {
                if(!operations.empty())
                {
                    while(operations.top() == '-' || operations.top() == '+' || operations.top() == '*' || operations.top() == '/')
                        output.push(string{operations.pull()});
                }

                operations.push(input[i]);
            }
        }

        else if(input[i] == '*' || input[i] == '/')
        {   
            if(!operations.empty())
            {
                while(operations.top() == '*' || operations.top() == '/')
                    output.push(string{operations.pull()});
            }

            operations.push(input[i]);
        }
        else if(input[i] == '(')
            operations.push(input[i]);
        else if(input[i] == ')')
        {
            if(operations.empty())
            {   
                cout << "Syntax Error" << endl;
                return is;
            }
            
            while(!operations.empty() && operations.top() != '(')
                output.push(string{operations.pull()});

            if(!operations.empty())
                operations.pull();
            else
            {   
                cout << "Syntax Error" << endl;
                return is;
            }
        }
    }

    if(!operations.empty())
    {
        if(operations.top() == '(' && output.empty())
        {
            cout << "Syntax Error" << endl;
            return is;
        }
        else
        {   
            if(output.empty())
            {
                cout << "Syntax Error" << endl;
                return is;
            }
            else
            {   
                while(!operations.empty())
                    output.push(string{operations.pull()});
            }
        }
    }
    string aux;
    short_t sign = 0;
    stack<bignum> numbers;

    while(!output.empty())
    {
        aux = output.pull();

        if(isdigit(aux[0]))
        {
            numbers.push(bignum(aux, sign));
            if(sign)
                sign--;
        }
        else if(aux[0] == 's')
            sign++;
        else if(numbers.length() < 2)
        {
            cout << "Syntax Error" << endl;
            return is;
        }
        else if(aux[0] == '+')
        {   
            result = numbers.pull();
            result = numbers.pull() + result;
            numbers.push(result);
        }
        else if(aux[0] == '-')
        {   
            result = numbers.pull();
            result = numbers.pull() - result;
            numbers.push(result);
        }
        else if(aux[0] == '*')
        {   
            result = numbers.pull();
            bignum auxiliar = numbers.pull();
            //result = numbers.pull() * result;
            result = auxiliar * result;
            numbers.push(result);
        }
        else if(aux[0] == '/')
        {   
            result = numbers.pull();
            result = numbers.pull() / result;
            numbers.push(result);
        }
    }

    if(!numbers.empty())
        result = numbers.pull();
    else
    {
        cout << "Syntax Error" << endl;
        return is;
    }

    return is;
}

bool operator == (const bignum &a, const bignum &b)
{   
    if(a.size != b.size)
    {   
        for(size_t i = 0; i < a.size; i++)
        {
            if(a.digits[i] != 0)
                return false;
        }

        for(size_t i = 0; i < b.size; i++)
        {
            if(b.digits[i] != 0)
                return false;
        }

        return true;
    }

    if(a.sign != b.sign)
        return false;
    
    for (size_t i = 0; i < a.size; i++)
    {
        if (a.digits[i] != b.digits[i])
            return false;
    }       

    return true;        
}

bool operator == (const bignum &a, const int &b)
{
    bignum c(to_string(b));
    
    if(a == c)
        return true;

    return false;
}

bool operator != (const bignum &a, const bignum &b)
{
    if(a == b)
        return false;

    return true;        
}

bool operator != (const bignum &a, const int &n)
{
    bignum c(to_string(n));

    if(a != c)
        return true;

    return false;
}

bool operator > (const bignum &a, const bignum &b)
{
    if(a.size < b.size)
        return false;

    if(a.size > b.size)
        return true;

    if(!a.sign && b.sign)
        return true;

    if(a.sign && !b.sign)
        return false;   
    
    if(a == b)
        return false;

    for (size_t i = 0; i < a.size; i++)
    {
        if (a.digits[i] > b.digits[i])
            return true;

        else if(a.digits[i] < b.digits[i])
            return false;
    }       

    return false;       
}

bool operator < (const bignum &a, const bignum &b)
{
    if(a > b)
        return false;

    if(a == b)
        return false;       

    return true;        
}

bignum.h:

#include <iostream>
#include <cstring>
#include <string>

#include "queue.h"
#include "stack.h"

using namespace std;

class bignum
{
private:
    short_t *digits;
    short_t sign;
    size_t size;

    friend bignum abs(const bignum &);
    friend void remove_zeros(bignum &);
    friend void add_zeros(bignum &, const ssize_t &);
    friend bool size_even(const bignum &);
    friend bignum reduce(const bignum &, const size_t &, const size_t &);
    friend bignum enlarge(const bignum &, const size_t &);
    friend bignum sum(const bignum &, const bignum &, const short_t &);
    friend bignum subtraction(const bignum &, const bignum &);
    friend bignum karatsuba(const bignum &, const bignum &);
    friend bignum mult_rec(const bignum &, const bignum &);
    friend bignum division(const bignum &, const bignum &, bignum &);
    friend bignum division_rec(const bignum &, const bignum &);

public:
    bignum();
    bignum(const size_t &);
    bignum(const string &, short_t);
    bignum(const bignum &);
    bignum(const int &);
    bignum& operator = (const bignum &);
    bignum& operator = (const int &); 
    ~bignum();
    friend bignum operator+(const bignum &, const bignum &);
    friend bignum operator+(const bignum &, const int &); 
    friend bignum operator-(const bignum &, const bignum &); 
    friend bignum operator-(const bignum &, const int &); 
    friend bignum operator*(const bignum &, const bignum &); 
    friend bignum operator/(const bignum &, const bignum &); 
    friend ostream& operator<<(ostream &, bignum &); 
    friend istream& operator>>(istream &, bignum &); 
    friend bool operator==(const bignum &, const bignum &);
    friend bool operator==(const bignum &, const int &);
    friend bool operator!=(const bignum &, const bignum &);
    friend bool operator!=(const bignum &, const int &);
    friend bool operator<(const bignum &, const bignum &);
    friend bool operator>(const bignum &, const bignum &);
};

生成文件:

all: calc

calc: mre.o bignum.o 
    g++ -std=c++11 -Wall -pedantic -g3 mre.o bignum.o -o calc

mre.o: mre.cc bignum.h
    g++ -std=c++11 -Wall -pedantic -g3 -c mre.cc

bignum.o: bignum.cc bignum.h stack.h queue.h debug.h
    g++ -std=c++11 -Wall -pedantic -g3 -c bignum.cc

clean:
    $(RM) calc *.o

我使用的其他一些库,queue.h:

#ifndef _QUEUE_H_
#define _QUEUE_H_

#include <cstdlib>
#include <iostream>

#include "debug.h"
#include "stack.h"

using namespace std;

typedef unsigned short short_t;

template <typename T>
class queue 
{
public:
    queue();
    queue(const queue &);
    queue &operator=(const queue &);
    ~queue();

    T pull();
    void pull(T &);
    void push(const T &);
    bool empty() const;
    size_t length() const;

private:
    stack<T> egress_;
    stack<T> ingress_;
};

template <typename T>

queue<T>::queue() {}

template<typename T>
queue<T>::queue(const queue &q)
    : egress_(q.egress_),
      ingress_(q.ingress_)
{
}

template<typename T>
queue<T> &queue<T>::operator=(const queue<T> &rhs)
{
    if (this != &rhs) {
        egress_ = rhs.egress_;
        ingress_ = rhs.ingress_;
    }

    return *this;
}

template<typename T>
queue<T>::~queue(){}

template<typename T>
T queue<T>::pull()
{
    if (egress_.empty()) {
        while (ingress_.empty() == false)
            egress_.push(ingress_.pull());
    }

    return egress_.pull();
}

template<typename T>
void queue<T>::pull(T &top)
{
    return this->pull();
}

template<typename T>
void queue<T>::push(const T &item)
{
    ingress_.push(item);
}

template<typename T>
bool queue<T>::empty() const
{
    return egress_.empty() && ingress_.empty() ? true : false;
}

template<typename T>
size_t queue<T>::length() const
{
    return egress_.length() + ingress_.length();
}

#endif

堆栈.h:

#ifndef _STACK_H_
#define _STACK_H_

#include <iostream>
#include <cstdlib>

#include "debug.h"

using namespace std;

template <typename T>
class stack
{
public:
    stack();
    stack(size_t);
    stack(const stack &);
    stack &operator=(const stack &);
    ~stack();

    T pull();
    T top();
    void pull(T &);
    void push(const T &);
    bool empty() const;
    size_t length() const;

private:
    void expand();
    void contract();
    
    size_t tos_;
    size_t len_;
    T *ptr_;
};

template<typename T>
stack<T>::stack() 
    : tos_(0), 
      len_(0), 
      ptr_(0)
{
}

template<typename T>
stack<T>::stack(size_t len) 
    : tos_(0), 
      len_(0), 
      ptr_(0)
{
    ptr_ = new T[len_ = len];
}

template<typename T>
stack<T>::stack(const stack &st)
    : tos_(0), 
      len_(0), 
      ptr_(0)
{
    ptr_ = new T[len_ = st.tos_];

    for (tos_ = 0; tos_ < st.tos_; ++tos_)
        ptr_[tos_] = st.ptr_[tos_];

    ASSERT(tos_ <= len_);
    ASSERT(tos_ == st.tos_);
}

template<typename T>
stack<T> & stack<T>::operator=(const stack<T> &rhs)
{
    if (this != &rhs) {
        if (rhs.tos_ > len_) {
            delete[] ptr_, len_ = 0;
            ptr_ = new T[len_ = rhs.tos_];
        }

        for (tos_ = 0; tos_ < rhs.tos_; ++tos_)
            ptr_[tos_] = rhs.ptr_[tos_];
    }

    ASSERT(tos_ <= len_);
    ASSERT(tos_ == rhs.tos_);

    return *this;
}

template<typename T>
stack<T>::~stack()
{   
    delete[] ptr_;
}

template<typename T>
T stack<T>::pull()
{   
    ASSERT(tos_ != 0);
    ASSERT(tos_ <= len_);
    ASSERT(ptr_ != NULL);

    return ptr_[--tos_];
}

template<typename T>
void stack<T>::pull(T &top)
{
    top = this->pull();
}

template<typename T>
T stack<T>::top()
{
    if(tos_ > 0)
        return ptr_[tos_ -1];

    return 0;
}

template<typename T>
void stack<T>::push(const T &top)
{   
    if (tos_ >= len_)
        expand();

    ptr_[tos_++] = top;
}

template<typename T>
bool stack<T>::empty() const
{
    return tos_ == 0 ? true : false;
}

template<typename T>
size_t stack<T>::length() const
{
    return tos_;
}

template<typename T>
void stack<T>::expand()
{
    size_t len;
    size_t tos;
    T *ptr = 0;

    if (len_ != 0)
        len = len_ << 1;
    else
        len = 1;

    ptr = new T[len];

    for (tos = 0; tos < tos_; ++tos)
        ptr[tos] = ptr_[tos];

    delete[] ptr_;

    tos_ = tos;
    len_ = len;
    ptr_ = ptr;

    ASSERT(tos_ < len_);
    ASSERT(ptr_ != NULL);
}

template<typename T>
void stack<T>::contract()
{
    std::abort();
}

#endif

调试.h:

#ifndef _DEBUG_H_
#define _DEBUG_H_

#ifdef DEBUG
#include <cstdlib>
#include <iostream>

#define ASSERT(expr)                                  \
    do {                                          \
        if (!(expr)) {                        \
            std::cerr << "assertion "     \
                      << (#expr)          \
                      << " failed :-\\ {" \
                      << __FUNCTION__     \
                      << "() "            \
                      << __FILE__         \
                      << ":"              \
                      << __LINE__         \
                      << "}"              \
                      << std::endl;       \
            std::abort();                 \
        }                                     \
    } while (0)
#else
#define ASSERT(expr) do {} while (0)
#endif

#endif

最后但并非最不重要的一点是,破坏程序的输入:

((((4)-(5) (((((3+9-(4) (-1)))-((4)-1-(-4) 0)))-((6+5 (0 )+(-5)) ((-4)-(-7) (-7) (-8))))+((((8) (0) (0)+3)+((-3) +6 8+(6)))-0+(-3))) ((1 (-8) (-6)-(-6)) ((((-2) (-4)-2 (- 5))+(-2) (4))-(((3)-(5)-(-4)+(-1)) (2)+(-5)))))) (((( 6)-(4) (3)-(9))+(((((-4) (-2) 0-(-6)) 1+(-7))-(1+(-3) ( -7) (-9)))-((((-3)-8+1-(-8)) (0+(8)+(0)+(-4))) 1+7))) +1 (3))) ((-3)+(4) ((((3+0+(-3)+(-1))) (((-1) (-2)+((0)- (-3)+(8)+(-7)))+(((-3)+(3)+(6)-8)+(1) (6))))-(-4) 8)(((8)-(-8) (((0)+(-9)+((3)+(0) (9) (-1)))-((4-(-9) 0 2) -((-6) (-8)-(-7) (4)))))-(((((6)+7+(-3) 5) ((9)+(1)-3* (5)))-(((-2)-(-1)-4-0)+((8)-6-(-3) (-3))))+0-(5)))) ))-((((((((8) (7)-(2)-(-9))+((9) (-8) (4)-0)))-(((5)+ (4) (4)+(3)) ((8) (-1)+6+8)))-((((-1)-(-9)+(9) (0))-(0 -(-2)+(-2)+(-3)))+(0) 0))+(-7)+(2)) (((1-(-4)-(((2)- (-7)-(-9) (-3))-(-7) (4)))+(((5+(4)-1+(-2))+((4)-(-7 )+(-6)-5))-((-2)+6+(0)+(-4))))+((((8+(-5)-(1)+(0)) -((4)+(-2) (-6)-0)) ((-9) (6)-((-4) 3+(-7)+0)))+((((-8) )+(-9)-(-5) 0) ((-7)(5)-(2)-(-5)))-4+(-6)))))+((-9)+(-8)+(2) (-4)))-((( (((-2)-(0)+(-1) (-4)) ((((-1) (7)-1 (-1))+(-3) (4)) (8)- 5))-((-7) (-9)-(((5 (2) (-4)-2) (2*(-8) (0)-8))+(((5)+( -3) (-4) (-9)) ((-2)-(-2)-2+(-9))))))+7+(4))+((-9)+5- (3+0+(((((-1)+(-2) (8) (-9))-((-5)-(-4)-(-3)-3)) (((- 7)+(-1)+(-3)+(-3)) 0 (3)))-((((0) (7)-(8)-(0)) (6+(-9) -0+(4)))-(5) (6)))))))

4

0 回答 0