大整数的运算实现

 

在csdn看到有人提出关于大数加法的实现问题,想起在学数据结构时有个课程设计是“链表实现大整数的运算”,当时看到就畏惧,如今是跃跃欲试。便尝试去实现下,由于课本还托在楼管那,不了解具体的要求,就先用非链表形式实现之。STL中的string拿来用之,顺便熟悉下。后发觉比字符数组好用多了。对于内存管理应更透明,尽管动态地、随便用它。

 

在编程过程中,发觉写代码的正确率实在过低。有时尽管思想出来了,但是具体落实到编程上,却老是会有BUG。而其中问题往往是非逻辑性的,是些小毛病。有些甚至要添加大量的cout才得以调试成功。 希望多加练习,能花尽量少的时间,写出正确漂亮的代码!

 

关于大整数的运算,包括 +,-,*,/。其中大整数位数可以是max (int) 也即string容量。理所当然,先实现加减。+->->*>/。

其中除法实现最久了,起初用最简单的方法,循环减去除数,得出结果。单处理111111111111111111111111/1时,机子就卡那很久。太烂了!便想着换掉。后来用到手算时的思想。效率可以提高很多,至少可以基本满足要求:随便输入,都可较快得到结果。

望路过者有疑问或好的建议,可以交流一二,无比感激!

 

  1. //=========================== 
  2. //用string 处理大数的运算: +,-,*,/,... 
  3. //Input: num1 + num2 //需要有间隔
  4. //Ouput: result 
  5. // BY Kasmile
  6. #include <iostream> 
  7. #include <string> 
  8. using namespace std;
  9. string Operate(string a,string operation,string b);
  10. string Add(string a,string b);
  11. string Sub(string a,string b);
  12. bool Great(string a,string b);
  13. string Mul(string a,string b);
  14. string Div(string a,string b);
  15. int main()
  16. {   
  17.     string num1,num2;
  18.     string operation,result;
  19.     cout<<"please input the nums to compute... "<<endl;
  20.     cin>>num1>>operation>>num2;
  21.     
  22.     result = Operate(num1,operation,num2);
  23.     cout<<"The result is : "
  24.         <<result
  25.             <<endl;
  26.     return 0;
  27. }
  28. string Operate(string a,string operation,string b)
  29. {
  30.     char oper = operation[0];
  31.     switch(oper)
  32.     {
  33.     case '+':
  34.         return Add(a,b);
  35.         break;
  36.     case '-':
  37.         return Sub(a,b);
  38.         break;
  39.     case '*':
  40.         return Mul(a,b);
  41.         break;
  42.     case '/':
  43.         return Div(a,b);
  44.         break;
  45.     default:
  46.         cout<<"Error..."<<endl;
  47.     }
  48. }
  49. string Add(string a,string b)
  50. {//加法 
  51.     if(a.size() < b.size())
  52.     {//加数a 为字符串 较长 
  53.         a.swap(b);
  54.     }
  55.     int t = 0;//进位标志 
  56.     int i = a.size() - 1,j = b.size() - 1;
  57.     for(;i > j; j++)
  58.     {//先对齐位数 
  59.         b = "0" + b;
  60.     }
  61.     for(;i >= 0; i--,j--)
  62.     {//处理到a的位数 
  63.         int b1 = b[i] - 48;
  64.         int a1 = a[j] - 48;
  65.         a1 = a1 + b1 + t;
  66.         t = 0;  
  67.         a[j] = a1%10 + 48;
  68.         if(a1 > 9)
  69.         {
  70.             t = 1;
  71.         }   
  72.     } 
  73.     
  74.     return t? "1" + a: a;
  75. }
  76. bool Great(string a,string b)
  77. {//大小比较,a >= b 返回 true, a < b 返回false 
  78.     if(a.size() > b.size())
  79.         return true;
  80.     else 
  81.         if(a.size() < b.size())
  82.             return false;
  83.     else 
  84.     {
  85.         int i = 0;
  86.         for(; i < a.size() && (a[i] >= b[i]); i++)
  87.         {
  88.             if(a[i] > b[i])
  89.                 return true;    
  90.         }
  91.         if(i < a.size())
  92.             return false;
  93.         return true;        
  94.     }
  95. }
  96. string Sub(string a,string b)
  97. {//减法 
  98.     bool flag = 0;//正负标志 
  99.     if(!Great(a,b))
  100.     {//a总为较大数 
  101.         a.swap(b);
  102.         flag = 1;
  103.     }
  104.     int i = a.size() - 1,j = b.size() - 1;
  105.     for(;i > j; j++)
  106.     {//先对齐位数 
  107.         b = "0" + b;
  108.     }
  109.     int t = 0;//借位标志 
  110.     for(;i >= 0; i--,j--)
  111.     {//处理到a的位数 
  112.         int b1 = b[j] - 48;
  113.         int a1 = a[i] - 48 - t;
  114.         int d = a1 - b1;
  115.         t = 0;  
  116.         if(d < 0)
  117.         {
  118.             t = 1;
  119.             d = d + 10;         
  120.         }
  121.         b[j] =d + 48;
  122.     } 
  123.     string::iterator iter = b.begin();
  124.     for(; (iter + 1) != b.end() && (*iter == '0');)
  125.     {//删除无效的首位0,最后一位留着... 
  126.         b.erase(iter);//自动后移 
  127.     }       
  128.     return flag? "-" + b: b;
  129. }
  130. string Mul(string a,string b)
  131. {//乘法. 
  132.     int total = b.size() - 1;
  133.     string result;
  134.     for(int n = total; n >= 0; n--)
  135.     {//从b的个位数 开始...  
  136.         string temp = "0";
  137.         int add_num = b[n] - 48;
  138.         for(;add_num > 0; add_num--)
  139.         {//a累加add_num 次 
  140.             temp = Add(temp,a);
  141.         }
  142.         for(int i = 1; i <= total - n; i++)
  143.         {//补0 
  144.             temp += "0";
  145.         }
  146.         result = Add(temp,result);
  147.     }
  148.     return result;
  149. }
  150. /*
  151. string Div(string a,string b)
  152. {//除法,循环减去除数
  153.     string result = a;
  154.     string s = "0"; 
  155.     int num = 0;
  156.     for(;result != "0" && Great(result,b);)
  157.     {
  158.         result = Sub(result,b);
  159.         s = Add(s,"1");
  160.     }
  161.     return "商: "+s+" 余: "+result;
  162. }
  163. */
  164. string Div(string a,string b)
  165. {//除法通过模拟人工手算... 
  166.     string s = "0"
  167.     if(b == "0")
  168.     {
  169.         return "Error";
  170.     }
  171.     for(; a != "0" && Great(a,b);)
  172.     {
  173.         int b_size = b.size();
  174.         int a_size = a.size();
  175.         int a_b = a_size - b_size;//被除数 与 除数的位差 
  176.         string s_temp = "1";
  177.         string a_temp(a,0,b_size);
  178.         for(; !Great(a_temp,b);)
  179.         {//需要被除数的前几位,  11 / 2, 则需 被除数的前2位 
  180.             a_b--;
  181.             a_temp.push_back(a[b_size++]);
  182.         }
  183.         for(; Great(a_temp,Mul(b,s_temp));) 
  184.         {//如11 / 2 则 s_temp = 6 后退出。     
  185.             s_temp = Add(s_temp,"1");
  186.         }
  187.         s_temp = Sub(s_temp,"1");
  188.         for(; a_b > 0; a_b--)
  189.         {//补0 
  190.             s_temp = s_temp + "0";
  191.         }
  192.         a = Sub(a,Mul(b,s_temp));//剩余未除的数 
  193.         s = Add(s,s_temp);//商的结果 
  194.     }
  195.     return "商: "+ s +" 余: "+a;
  196. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值