题解 | #Powerful Calculator#

Powerful Calculator

https://www.nowcoder.com/practice/6bc1dd2ee0ce4257821531719b8d1c83

//一个题把大数加法,大数减法,大数乘法全考了给我说这是入门题...
#include "stdio.h"
#include "string"
#include "algorithm"
using namespace std;

string addString(string num1,string num2){
    int length = num1.size()>num2.size()?num1.size():num2.size();//length为最长数字串长度
    while (num1.size() < length)
        num1 = "0" + num1;
    while (num2.size() < length)
        num2 = "0" + num2;
    int carry = 0;
    string num3 = "";int temp;//num3为最终计算出的字符串,temp为中间变量
    for (int i = length-1; i >= 0; --i) {
        temp = num1[i]-'0'+num2[i]-'0'+carry;
        if (temp > 9){
            carry = 1;
            num3 += temp-10+'0';
        } else{
            carry = 0;
            num3 += temp+'0';
        }
    }
    if (carry == 1)//最后还有判断是否有进位
        num3 += "1";
    reverse(num3.begin(),num3.end());
    return num3;
}
/*
 * 大数减法思路:先判断被减数和减数的长度,若为被减数长则结果为正,否则为负。若而这长度相等,
 * 则判断哪个数大,不然最后再处理负号会很麻烦。其他的思想就和加法很像了,有个借位的变量,从低位开始
 */
string subString(string num1,string num2){//num1为被减数,num2为减数
    bool flag;//true为正,false为负
    int length1 = num1.size();
    int length2 = num2.size();
    int length;
    if(length1 > length2){//存储长数字串长度且被减数永远是大数
        flag = true;
        length = length1;
    }
    else if (length1 < length2){
        flag = false;
        length = length2;
        swap(num1,num2);
    }
    else{
        int i;
        for (i = 0; i < length1; ++i) {
            if (num1[i] > num2[i]){//num1大
                flag = true;
                length = length1;
                break;
            } else if (num1[i] < num2[i]){//num2大
                flag = false;
                length = length2;
                swap(num1,num2);
                break;
            }
        }
        if (i == length1)
            return "0";
    }//上述为判断减法结果的正负
    while (num1.size() < length)
        num1 = "0" + num1;
    while (num2.size() < length)
        num2 = "0" + num2;
    int borrow = 0;int temp;string num3;
    for (int i = length-1; i >= 0; --i) {
        temp = (num1[i]-'0')-(num2[i]-'0')-borrow;
        if (temp < 0){
            borrow = 1;
            temp += 10;
            num3 += temp + '0';
        } else{
            borrow = 0;
            num3 += temp + '0';
        }
    }
    int i = num3.size()-1;
    while (num3[i] == '0')//消除前导0
        --i;
    num3 = num3.substr(0,i+1);
    reverse(num3.begin(),num3.end());
    if(flag)
        return num3;
    else
        return "-"+num3;
}

string multiString(string num1,string num2){//
    int num3[810] = {0};
    reverse(num1.begin(),num1.end());
    reverse(num2.begin(),num2.end());//为了方便先颠倒过来
    int length1 = num1.size();
    int length2 = num2.size();
    int temp;
    for (int i = 0; i < length1; ++i) {//num3低字节存储地位,所以num3记得颠倒
        for (int j = 0; j < length2; ++j) {
            temp = (num1[i]-'0')*(num2[j]-'0');
            num3[i+j] += temp;
        }
    }
    for (int i = 0; i < 810; ++i) {
        if (num3[i] > 9){
            temp = (num3[i] - num3[i]%10)/10;
            num3[i] = num3[i]%10;
            num3[i+1] += temp;
        }
    }
    int i = 809;
    while (num3[i] == 0)
        --i;//消除前导0,i+1为长度
    string str = "";
    for (int j = 0; j < i+1; ++j) {
        str += num3[j]+'0';
    }
    reverse(str.begin(),str.end());
    return str;
}

int main(){
    char buf1[410],buf2[410];
    string str1,str2;
    while (scanf("%s",buf1)!=EOF){
        scanf("%s",buf2);
        str1 = buf1;str2 = buf2;
        printf("%s\n", addString(str1,str2).c_str());
        printf("%s\n", subString(str1,str2).c_str());
        printf("%s\n", multiString(str1,str2).c_str());
    }
}

全部评论

相关推荐

11-08 16:53
门头沟学院 C++
投票
滑模小马达:第三个如果是qfqc感觉还行,我签的qfkj搞电机的,违约金也很高,但公司感觉还可以,听说之前开过一个试用转正的应届生,仅供参考。
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务