zoukankan      html  css  js  c++  java
  • 高精度问题之大数相加(原来就是用字符串相加,模拟手算这么简单!)

    解题心的: 就是基本的一对一模拟手算。。借助c++的string 不用逆序运算了。很方便的补0.  最后处理下前导0的问题。

    #include <iostream>
    #include <string>
    using namespace std;
    
    // 实现大数相加  结果存放在num中 
    
    void bigIntergerAdd(string &num, string add) {
        
        int goBit = 0; // 存放进位
        
        // 先交换下顺序  加数的位数要比较少
        if (num.length() < add.length()) {
        
            string tmp = num;
            num = add;
            add = tmp;
        } 
        
        string tmp (num.length() - add.length(), '0');
        add = tmp + add; 
        
        // 利用string的+号特性  不采用逆序相加法 
        int len1 = num.length(), len2 = add.length();
        for (int i = len1 -1 ; i>= 0; --i) {
            
            int tmp =  ((num[i] - '0') + (add[i] - '0') + goBit) ;
            
            num[i] = tmp% 10 + '0';
            
            goBit = tmp/10;
        }
    
        // 特殊情况处理
        if (goBit != 0) 
            num.insert(0, string(1, (char)goBit +'0')); 
    } 
    
    
    int main(int argc, char** argv) {
    
        string s1;
        string result;
        int i =0;
        while (cin>> s1) {
        
            if (s1 == "0") {
                
                cout<< result<< endl;
                break;
            } 
            
            if (i ==0) {
                
                i=1;
                result = s1;
            } else 
                bigIntergerAdd(result, s1);
            
            
        } 
        return 0;
    }

    参考:http://blog.csdn.net/wu5151/article/details/47100085

    ----------------------------------------------------------------------------------

    大数相乘:总的思路比较简单, 就是模拟手算。 用较短(或相等)长度的数的每一位与较长数一一相乘。要注意的是,相乘所得结果需要补0的细节 。然后就是单纯的大数相加。

    #include <iostream>
    #include <string>
    using namespace std; 
    
    // 大数相乘 
    
    string bigIntegerPlus(string res, string plusN) {
        
        string ret; 
        if (res.length()< plusN.length()) {
            
            string tmp = res;
            res = plusN;
            plusN = tmp; 
        }
        
        int len1 = res.length(), len2 = plusN.length();
        for (int i = len2-1; i>=0; --i ) {
            
            string tmp(len1, '0'); // 存放相乘的中间结果 
            int goBit =0;
            for (int j= len1-1; j >=0; --j) {
            
                int mid = (res[j] -'0') * (plusN[i] -'0') + goBit;
                tmp[j] = mid%10 + '0';
                goBit = mid /10;
            }
            if (goBit != 0) 
                tmp.insert(0, string(1,goBit +'0'));
            
            for (int m=0; m< len2 -1-i; ++m)
                tmp.push_back('0'); // 补位  
            
            // 相乘后就相加  大数相加
            if (i == len2-1)
                ret = tmp;
            else {
                
                int goBit2 =0; 
                string s(tmp.length() - ret.length() ,'0');
                ret = s + ret;
                for (int m = tmp.length()-1; m>=0; --m) {
                    
                    int mid = (tmp[m] -'0')+(ret[m] - '0')  + goBit2;
                    ret[m] = mid %10 +'0';
                    goBit2 = mid/ 10;    
                }
                
                if (goBit2 != 0) 
                    ret.insert(0, string(1,goBit +'0'));
            }     
        } 
    
        // 去掉前导0
        while (ret.length() >1 && ret[0] == '0')
            ret.erase(0,1);
         
        return ret;    
    }
    
    
    int main(int argc, char** argv) {
        
        string res, plusN;
        while (cin>> res>> plusN) {
            
            cout<< bigIntegerPlus(res, plusN)<< endl;
        }
        
        return 0;
    }

    参考:http://blog.csdn.net/wu5151/article/details/47099971

    ----------------------------------------------------------------------------------

    实现的是大数跟int类型的相除和求余,解题心得: 模拟手算的过程。需要注意的是。其中余数的存放要用long long存放比较好。因为如果采用int类型那么     rem = prem * 10/*向后退一位*/ + src[i] - '0';    这行代码可能会出现溢出问题。

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    void bigDivision(char *src, int num, char sign) {
        
        long long rem = 0; // 存放新余数 
        long long prem = 0; // 原余数
        char  res[10000] ="";
        bool flag = true;
        int k = 0;
        for (int i=0; i< strlen(src); ++i) {
            
            rem = prem * 10/*向后退一位*/ + src[i] - '0';
            if (rem / num >0 || rem ==0) {
                
                res[k++] = rem/ num + '0';
                prem = rem %num;
                flag = false;
            }  else {
                
                prem = rem;
                if (!flag)
                    res[k++] = '0';
            }
        }
        if (sign == '%') {
            
            cout<< prem<< endl;
            return;
        }
        
        for (int i =0; i< k; ++i) 
            cout<< res[i];
        cout<< endl;
    } 
    
    int main(int argc, char** argv) {
        
        char src[10000] = "";
        int num;
        char sign;
        while (scanf("%s %c %d", src, &sign, &num) != EOF) {
            
            bigDivision(src, num, sign);
        }
        
        return 0;
    }

    参考:http://blog.csdn.net/wu5151/article/details/47100165

    ----------------------------------------------------------------------------------

    高精度问题之大数求幂,解题思路: 因为做了大数相加 ,这题也就没什么好思考的。不同之处就是先去掉小数点,计算结果后在适当位置插入小数点即可。这个算法可以计算更大的数。但必须包含小数点。。。。。。

    #include <iostream>
    #include <string>
    using namespace std;
    
    // 求幂  思路: 先变成整数相乘   然后根据小数的位数 结合幂  算出小数点该结果字符串的位置 即可
    
    string bigIntegerPlus(string src, string num) {
        
        string tmp = src;
        for (int i =num.length() -1; i >= 0 ; --i) {
            
            string mid(tmp.length(),'0');
            int goBit =0;
            for (int j =  tmp.length()-1; j >= 0; --j) {
                
                int tm = goBit + (tmp[j] -'0')* (num[i] - '0');
                mid[j] = tm% 10 +'0';
                goBit = tm  /10;
            }
            
            for (int q = num.length()-1; q> i; --q) 
                mid.push_back('0');
            if (goBit != 0) 
                mid.insert(0, string(1, (char)goBit +'0'));
    
            // 加法运算
            if (i == num.length()-1)
                src = mid;
            else {
            
                goBit =0;
                string s(mid.length() - src.length(), '0');
                src = s + src;
                for (int j = mid.length()-1; j>=0; --j) {
                
                    int tm = (mid[j] - '0') +(src[j] - '0') + goBit;
                    src[j] = tm %10 + '0';
                    goBit = tm /10;
                }
    
                if (goBit !=0) 
                    src.insert(0, string(1, (char)goBit +'0'));
            }    
        }
        return src;
    }
    
    int main(int argc, char** argv) {
        
        string str;
        while ( getline(cin, str)) {
            
            // 分割出待积数 和 幂  以及小数点位置
            int i =0;
            int index = 0;// 小数位置
            int count = 0;//幂次数
            string num;
            while ( i< str.length()) {
                
                if ( str[i] != ' ') {
                
                    if (str[i] == '.')
                        index = i;
                    else
                        num.push_back(str[i]);
                    ++i;
                    continue;
                }
                while ( !isdigit(str[i])) 
                    ++i;
                
                if (i + 1 == str.length())
                    count = str[i] - '0';
                else 
                    count = (str[i] - '0') * 10 + str[i+1] - '0';        
                break;        
            }
            
            index = num.length() - index;
                
            string res = num;
            for (int i =0; i< count-1; ++i) {
            
                res = bigIntegerPlus( res, num);
            }
            index = index * count;
            
            res.insert(res.length() - index, string(".")); 
            
            while (res.length() >1 && res[0] == '0')
                res.erase(0, 1);
            
            for (int i =res.length()-1; i>=0; --i) {
                
                if (res[i] == '0' )
                    res.erase(i, i+1);
                else 
                    break;
            }
            cout<< res<< endl;    
        }
        
        return 0;
    }

    参考:http://blog.csdn.net/wu5151/article/details/47100327

  • 相关阅读:
    动态表单功能
    IDEA2019版Run Dashboard调出方案
    js页面传递参数为中文乱码问题解决方法
    layui 一行多列控件时使用table布局
    npm 安装包失败 --- 清除npm缓存
    解析数据库连接字符串 (将Data Source、Initial Catalog、User ID、Password取出)
    SQL SERVER 存储过程语法
    mvc5 跨域访问
    钟表
    MVC session过期如何处理跳转(转)
  • 原文地址:https://www.cnblogs.com/findumars/p/4684361.html
Copyright © 2011-2022 走看看