简体   繁体   中英

SPOJ: Simple Arithmetics (ARITH) giving WA

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;
int bigger(int a,int b,int c)
{
    if(a>b)
    {
        if(c>a)
            return c;
        else
            return a;
    }
    else
    {
        int c1=0,c2=0,c0,b0;
        b0=b;
        c0=c;
        while(c0!=0)
        {
            c0/=10;
            c1++;
        }
        while(b0!=0)
        {
            b0/=10;
            c2++;
        }
        if(c1>c2)
            return c;
        else
            return b;
    }
}
int main()
{
    int i,n;
    cin>>n;
    for(i=0;i<n;i++)
    {
        int j,a,b,big,ans,dig,d,mult,dgit,m=0,ass;
        char ch;
        string res,str="";
        cin>>a>>ch>>b;
        if(ch=='+'||ch=='-')
        {
            if(ch=='+')
                ans=a+b;
            else if(ch=='-')
                ans=a-b;

            big=bigger(a,b,ans);
            d=big;
            dig=0;
            while(d!=0)
            {
                d/=10;
                dig++;
            }
            string abc="";
            if(ch=='+')
                abc.append("+");
            else
                abc.append("-");
            string qrt;
            ostringstream oss;
            oss<<b;
            qrt=oss.str();
            abc.append(qrt);
            cout<<setw(dig);
            cout<<a<<"\n";
            if(b==big)
                cout<<setw(dig+1);
            else
                cout<<setw(dig);
            cout<<abc;
            cout<<"\n";
            int k=0;
            if(b==big)
                k--;
            for(;k<dig;k++)
                cout<<'-';
            cout<<'\n';
            if(b==big)
                cout<<setw(dig+1);
            else
                cout<<setw(dig);
            cout<<ans;
        }

        else if(ch=='*')
        {
            ans=a*b;
            mult=b;
            big=bigger(a,b,ans);
            d=big;
            dig=0;
            while(d!=0)
            {
                d/=10;
                dig++;
            }
            if(b==big)dig++;
            cout<<setw(dig);
            cout<<a<<'\n';
            cout<<setw(0);
            string abc="";
            cout<<setw(dig);
            abc.append("*");
            string qrt;
            ostringstream oss;
            oss<<b;
            qrt=oss.str();
            abc.append(qrt);
            cout<<abc;
            cout<<'\n';
            d=bigger(a,b,a*(b%10));
            ass=0;
            while(d!=0)
            {
                d/=10;
                ass++;
            }
            if(a>b)
                for(int k=0;k<ass;k++)
                    str.append("-");
            else
                for(int k=0;k<=ass;k++)
                    str.append("-");
            cout<<setw(dig)<<str;
            cout<<'\n';
            while(mult!=0)
            {
                dgit=mult%10;
                mult/=10;
                ostringstream os;
                os<< dgit*a;
                res= os.str();
                for(int q=0;q<m;q++)
                {
                   res.append(" ");
                }
                cout<<setw(dig);
                cout<<res<<'\n';
                m++;
            }
            if(ans!=dgit*a)
            {
                for(int k=0;k<dig;k++)
                    cout<<'-';
                cout<<'\n'<<setw(dig)<<ans<<'\n';
            }

        }

    }
}

This code is giving wa but I can't find incorrect test cases. Could anyone explain the number of dashes required? Maybe more test cases. Sorry for the badly written code. Wrote it in a hurry. Here's the question http://www.spoj.com/problems/ARITH/

Some problems with you code:

  • You are using int to storage the numbers of the expressions, in the problem description clearly state that would be some test case with numbers up to 500 digits, this kind of digits could not be storage in any integer or floating point type of C++.

This king of problem are principal targeting to submit a solution that storage the digits in some custom way. For example making a std::vector<unsigned char> where every element of the vector is a digit of the number.

Performing + and - is trivial, do it as you do in papel, one variable for the carry, another to storage the result (ex: other std::vector<unsigned char> ). The dashes could be easily calculated by the size of the container of the operands (case of - ) and the result (case of + ). With one loop through all the digits of operand1 and operand2 assuming 0 when no digit exist, the job is done.

Performing the * is more tricky but not much, you need some storage for the intermediary result (ex: std::vector<std::vector<unsigned char>> , an array of digits storage). And perform the product of one digits at a time with all the other operand as you in paper, using a carry variable. In this case the count of dashes the size of the result vector.

Some sample code (Tested in GCC 4.9.0 with C++11):

#include <iostream>
#include <vector>

typedef std::vector<unsigned char> digit_storage_t;

void print(const digit_storage_t& operand1, unsigned int dashes) {
    while (dashes > operand1.size()) {
        std::cout << " ";
        dashes--;
    }

    for (auto d : operand1)
        std::cout << static_cast<unsigned int>(d);
}

void print(char operation, const digit_storage_t& operand2, unsigned int dashes) {
    std::cout << operation;
    while (dashes > operand2.size()) {
        std::cout << " ";
        dashes--;
    }

    for (auto d : operand2)
        std::cout << static_cast<unsigned int>(d);
}

void print_dashes(unsigned int dashes) {
    while (dashes > 0) {
        std::cout << "=";
        dashes--;
    }
}

void add(const digit_storage_t& operand1, const digit_storage_t& operand2, digit_storage_t& result) {
    result.clear();
    result.resize(std::max(operand1.size(), operand2.size()) + 1);

    unsigned int current_digit_result_idx = result.size() - 1;
    int carry = 0;

    auto current_digit_operand1 = operand1.rbegin();
    auto current_digit_operand2 = operand2.rbegin();
    while (current_digit_operand1 != operand1.rend() ||
           current_digit_operand2 != operand2.rend()) {
        int oper1 = 0, oper2 = 0;
        if (current_digit_operand1 != operand1.rend())
            oper1 = *current_digit_operand1;
        if (current_digit_operand2 != operand2.rend())
            oper2 = *current_digit_operand2;

        result[current_digit_result_idx] = (oper1 + oper2 + carry) % 10;
        carry = (oper1 + oper2 + carry) / 10;

        current_digit_result_idx--;
        current_digit_operand1++;
        current_digit_operand2++;
    }

    if (current_digit_result_idx == 0)
        result.erase(result.begin());
}

int main() {
    unsigned int expresion_count = 0;
    std::cin >> expresion_count;
    std::string line;
    std::getline(std::cin, line);
    for (unsigned int i = 0; i < expresion_count; i++) {
        std::getline(std::cin, line);

        digit_storage_t operand1;
        digit_storage_t operand2;
        digit_storage_t* actual_operand = &operand1;
        char operation = '\0';
        for (auto c : line) {
            if (c == '+' || c == '-' || c == '*') {
                operation = c;
                actual_operand = &operand2;
            } else {
                actual_operand->push_back(c - '0');
            }
        }

        switch (operation) {
            case '+': {
                digit_storage_t result;
                add(operand1, operand2, result);

                unsigned int dashes = result.size();
                print(operand1, dashes + 1);
                std::cout << std::endl;
                print(operation, operand2, dashes);
                std::cout << std::endl;
                print_dashes(dashes + 1);
                std::cout << std::endl;
                print(result, dashes + 1);
                std::cout << std::endl;
                break;
            }
            case '-': {
                // digit_storage_t result;
                // sustract(operand1, operand2, result);
                break;
            }
            case '*': {
                // std::vector<digit_storage_t> result;
                // product(operand1, operand2, result);
                break;
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM