日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

任意长度的两个大数的乘法

發布時間:2024/7/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 任意长度的两个大数的乘法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

方法(一):

關于大數乘法,可以使用數組來模擬小學三年級的乘法豎式計算過程,代碼如下:

#include "iostream" #include "string" using namespace std; int main(void) {char str1[1000],str2[1000];int i,j,len1,len2,len;bool flag=false;cout<<"任意兩個大數的乘法(用數組來模擬小學三年級的乘法豎式計算過程):"<<endl;cout<<"請輸入被乘數:";gets(str1);cout<<"請輸入乘數:";gets(str2);len1=strlen(str1);len2=strlen(str2);int *a=new int[len1];int *b=new int[len2];len=len1*len2+1;int *result= new int[len];for(i=0;i<len;i++)result[i]=0;for(i=0;i<len1;i++) //將字符串轉換為整數,并倒置過來a[i]=str1[len1-1-i]-'0';for(i=0;i<len2;i++)b[i]=str2[len2-1-i]-'0';for(i=0;i<len1;i++) //用數組來模擬小學三年級的乘法豎式計算過程{for(j=0;j<len2;j++)result[i+j]+=a[i]*b[j];}for(i=0;i<len;i++) //處理進位的情況{if(result[i]>9){result[i+1]+=result[i]/10;result[i]%=10;}}cout<<"兩個大整數相乘的結果為:";for(i=len-1;i>=0;i--){if(flag)cout<<result[i];else if(result[i]!=0){cout<<result[i];flag=true;}}cout<<endl;delete []a;delete []b;delete []result;system("pause");return 0; }

方法(二):關于大數乘法,可以使用大整數乘法的分治方法:

設X和Y都是n位的整數,現在要計算它們的乘積XY。如果
**利用小學所學的方法,將每兩個一位數都進行相乘,最后
**再相加,效率比較低下,乘法需要n^2次。分治的方法可以
**減少乘法的次數,設X被分成2部分A和B,即X=A*10^(n/2)+B
**Y也同樣處理,即Y=C*10^(n/2)+D.
**那么,XY=(A*10^(n/2)+B)*(C*10^(n/2)+D)
?????????????? =AC*10^n+(AD+BC)*10^(n/2)+BD ------>(1)
**AD和BC可以利用AC和BD來表示,AD+BC=(A-B)*(D-C)+AC+BD --->(2)
**這樣(1)的乘法次數由4次減少到3次。

**最后的運算效率會有所提高。

***以上出自?? 計算機算法設計與分析(王曉東) *******/

代碼如下:

#include "iostream" #include "list" #include "string" using namespace std;/*******大整數減法*********/ list<char> long_sub(list<char> clist1, list<char> clist2); /*******大整數加法*********/ list<char> long_add(list<char> clist1, list<char> clist2) {list<char> rs; //存放最后的結果//如果一個正,一個負,做兩數相減if ( *(clist1.begin()) == '-' && *(clist2.begin()) != '-' ){clist1.erase(clist1.begin()); //去掉符號位rs = long_sub(clist2, clist1);return rs;}//如果一個負,一個正,做兩數相減if ( *(clist1.begin()) != '-' && *(clist2.begin()) == '-' ){clist2.erase(clist2.begin()); //去掉符號位rs = long_sub(clist1, clist2);return rs;}if ( *(clist1.begin()) == '-' && *(clist2.begin()) == '-' ){clist1.erase(clist1.begin());clist2.erase(clist2.begin());rs = long_add(clist1,clist2);rs.push_front('-');return rs;}if ( *(clist1.begin()) != '-' && *(clist2.begin()) != '-' ){//首先保證兩數位數相同(填充0)int length1 = clist1.size();int length2 = clist2.size();if( length1 < length2 ){for(int i=0; i<(length2 -length1); ++i){clist1.push_front('0');}}else if ( length1 > length2 ){for(int i=0; i<(length1 -length2); ++i){clist2.push_front('0');}}//整數加法,從低位加起,最低位的進位初始為0int c=0; //低位借位初始為0int low; //減完后本位的數值list<char>::iterator iter1 = clist1.end();--iter1;list<char>::iterator iter2 = clist2.end();--iter2;for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2){int num1 = *iter1 -'0';int num2 = *iter2 -'0';low = (num1+num2+c)%10;c = (num1+num2+c)/10;rs.push_front(low+'0');}//雙方最高位相加的處理int num1 = *iter1 -'0';int num2 = *iter2 -'0';low = (num1+num2+c)%10;c = (num1+num2+c)/10;rs.push_front(low+'0');if ( c != 0 ){rs.push_front(c+'0');}return rs;}return rs; }/*******大整數減法*********/ list<char> long_sub(list<char> clist1, list<char> clist2) {list<char> rs; //存放最后的結果//如果一正一負相減,做相加if (*(clist1.begin()) != '-' && *(clist2.begin()) == '-' ){clist2.erase(clist2.begin()); //去掉符號位rs = long_add(clist1, clist2);return rs;}//如果一負一正相減,做相加(添符號)if ( *(clist1.begin()) == '-' && *(clist2.begin()) != '-' ){clist1.erase(clist1.begin()); //去掉符號位rs = long_add(clist1, clist2);rs.push_front('-');return rs;}//如果兩負相減,作相減if ( *(clist1.begin()) == '-' && *(clist2.begin()) == '-' ){clist1.erase(clist1.begin());clist2.erase(clist2.begin()); //去掉符號位rs = long_sub(clist2, clist1);return rs;}//如果兩正相減,做相減if ( *(clist1.begin()) != '-' && *(clist2.begin()) != '-' ){int sign = -1; //代表兩數相減結果的正負,如果最高位為'-'(ascii碼為45)表示負,否則表示正//首先保證加數位數相同(填充0)int length1 = clist1.size();int length2 = clist2.size();if( length1 < length2 ){sign = '-';for(int i=0; i<(length2 -length1); ++i){clist1.push_front('0');}}else if ( length1 > length2 ){for(int i=0; i<(length1 -length2); ++i){clist2.push_front('0');}}else if ( *(clist1.begin()) < *(clist2.begin()) ){sign = '-';}//整數減法,從低位減起,最低位的借位初始為0int c = 0; //低位借位初始為0int low; //減完后本位的數值list<char>::iterator iter1 = clist1.end();--iter1;list<char>::iterator iter2 = clist2.end();--iter2;if (sign != '-' ){for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2){int num1 = *iter1 -'0';int num2 = *iter2 -'0';int c_new = 0; //向高位的借位if ( num1 < num2+c ){c_new = 1;num1 = num1+10;}low = (num1-num2-c)%10;c = c_new;rs.push_front(low+'0');}//雙方最高位相減的處理int num1 = *iter1 -'0';int num2 = *iter2 -'0';low = (num1-num2-c)%10;if ( low != 0 ){rs.push_front(low+'0');}}else if ( sign == '-' ){for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2){int num1 = *iter1 -'0';int num2 = *iter2 -'0';int c_new = 0; //向高位的借位if ( num2 < num1+c ){c_new = 1;num2 = num2+10;}low = (num2-num1-c)%10;c = c_new;rs.push_front(low+'0');}//雙方最高位相減的處理int num1 = *iter1 -'0';int num2 = *iter2 -'0';low = (num2-num1-c)%10;if ( low != 0 ){rs.push_front(low+'0');}rs.push_front('-'); //最高位的'-'作為負數的標志}return rs;}return rs; } /*******大整數乘法*********/ list<char> long_mul(list<char> clist1, list<char> clist2) {list<char> rs; //保存最后的結果//遞歸出口if(clist1.size() == 1 && clist2.size() == 1) //兩個數都成1位了{int num1 = *(clist1.begin())-'0';int num2 = *(clist2.begin())-'0';int high = (num1*num2)/10; //積的高位int low = (num1*num2)%10; //積的低位if ( high != 0 ){rs.push_back(high+'0');}rs.push_back(low+'0');return rs;}if (clist1.size() == 1 && clist2.size() > 1){int sign = -1; //最后結果的正負標志,'-'(ascii碼為45)表示負,其他表示正char high_bit2 = *(clist2.begin()); //clist2的最高位if ( high_bit2 == '-' ){sign = '-'; //相乘結果為負clist2.erase(clist2.begin()); //去掉高位的'-'}int length2 = clist2.size(); //clist2的有效長度(去除'-'號后)if ( length2 > 1 ){//對clist2進行拆分list<char> clist2_1; //高位部分list<char> clist2_2; //低位部分int i;list<char>::iterator iter;for (i=0,iter=clist2.begin(); i<length2/2; ++i,++iter){clist2_1.push_back(*iter);}for(; iter != clist2.end(); ++iter){clist2_2.push_back(*iter);}list<char> rs1; //高位部分和clist1的積list<char> rs2; //低位部分和clist1的積rs1 = long_mul(clist1, clist2_1);rs2 = long_mul(clist1, clist2_2);//對高位積進行移位(末尾添0)for( i=0; i<clist2_2.size(); ++i ){rs1.push_back('0');}rs = long_add(rs1,rs2); //兩部分積相加if( sign == '-' ){rs.push_front('-');}}else{rs = long_mul(clist1, clist2);if ( sign == '-' ){rs.push_front('-'); //結果添上'-'號}}return rs;}if (clist1.size() >1 && clist2.size() == 1){int sign = -1; //最后結果的正負標志,'-'表示負,其他表示正char high_bit1 = *(clist1.begin()); //clist1的最高位if ( high_bit1 == '-' ){sign = '-'; //相乘結果為負clist1.erase(clist1.begin()); //去掉高位的'-'}int length1 = clist1.size(); //clist1的有效長度(去除'-'號后)if ( length1 > 1 ){//對clist1進行拆分list<char> clist1_1; //高位部分list<char> clist1_2; //低位部分int i;list<char>::iterator iter;for (i=0,iter=clist1.begin(); i<length1/2; ++i,++iter){clist1_1.push_back(*iter);}for(; iter != clist1.end(); ++iter){clist1_2.push_back(*iter);}list<char> rs1; //高位部分和clist2的積list<char> rs2; //低位部分和clist2的積rs1 = long_mul(clist1_1, clist2);rs2 = long_mul(clist1_2, clist2);//對高位積進行移位(末尾添0)for( i=0; i<clist1_2.size(); ++i ){rs1.push_back('0');}rs = long_add(rs1,rs2); //兩部分積相加if( sign == '-' ){rs.push_front('-');}}else{rs = long_mul(clist1, clist2);if ( sign == '-' ){rs.push_front('-'); //結果添上'-'號}}return rs;}if (clist1.size() >1 && clist2.size() > 1 ){int sign = -1; //最后結果的正負標志,'-'表示負,其他表示正char high_bit1 = *(clist1.begin()); //clist1的最高位char high_bit2 = *(clist2.begin()); //clist2的最高位if ( high_bit1 == '-' && high_bit2 != '-' ){sign = '-'; //相乘結果為負clist1.erase(clist1.begin()); //去掉高位的'-'}if ( high_bit1 != '-' && high_bit2 == '-' ){sign = '-'; //相乘結果為負clist2.erase(clist2.begin()); //去掉高位的'-'}if ( high_bit1 =='-' && high_bit2 == '-' ){clist1.erase(clist1.begin());clist2.erase(clist2.begin()); //去掉高位的'-'}int length1 = clist1.size(); //clist1的有效長度int length2 = clist2.size(); //clist2的有效長度if ( length1 == 1 || length2 == 1 ){rs = long_mul(clist1, clist2);if ( sign == '-' ){rs.push_front('-');}}else if ( length1 > 1 && length2 > 1 ){//對clist1和clist2分別進行劃分list<char> clist1_1; //clist1的高位部分list<char> clist1_2; //clist1的低位部分list<char> clist2_1; //clist2的高位部分list<char> clist2_2; //clist2的低位部分int i;list<char>::iterator iter;for(i=0,iter=clist1.begin(); i<length1/2; ++i,++iter){clist1_1.push_back(*iter);}for(; iter!=clist1.end(); ++iter){clist1_2.push_back(*iter);}for(i=0,iter=clist2.begin(); i<length2/2; ++i,++iter){clist2_1.push_back(*iter);}for(; iter!=clist2.end(); ++iter){clist2_2.push_back(*iter);}list<char> rs_hh; //兩個高位相乘的結果list<char> rs_ll; //兩個低位相乘的結果rs_hh = long_mul(clist1_1, clist2_1);//高位相乘結果移位(末尾添0)for(i=0; i<clist1_2.size()+clist2_2.size(); ++i){rs_hh.push_back('0');}rs_ll = long_mul(clist1_2, clist2_2);list<char> sub1_hl; //clist1的高位和低位部分的差list<char> sub2_lh; //clist2的低位和高位部分的差//兩個高位分別移位for(i=0; i<clist1_2.size(); ++i){clist1_1.push_back('0');}for(i=0; i<clist2_2.size(); ++i){clist2_1.push_back('0');}sub1_hl = long_sub(clist1_1, clist1_2);sub2_lh = long_sub(clist2_2, clist2_1);list<char> rs_sub1_sub2; //兩個差的乘積rs_sub1_sub2 = long_mul(sub1_hl, sub2_lh);//把幾個乘積的結果加起來list<char> tmp1 = long_add(rs_hh, rs_ll);list<char> tmp2 = long_add(tmp1, rs_sub1_sub2);list<char> tmp3 = long_add(tmp2, rs_hh);rs = long_add(tmp3, rs_ll);if ( sign == '-' ){rs.push_front('-');}}return rs;}return rs; }int main(void) {list<char> clist1;list<char> clist2;cout <<"請您輸入2個乘數: "<<endl;cout <<"請您輸入被乘數: ";int i;string str1;cin >> str1;for(i=0; i<str1.size(); ++i){if (str1[i] >= '0' && str1[i] <= '9' ){clist1.push_back(str1[i]);}else{cout <<"被乘數中的數字只能為0~9" <<endl;exit(1);}}cout <<"請您輸入乘數: ";string str2;cin >> str2;for(i=0; i<str2.size(); ++i){if ( str2[i] >= '0' && str2[i] <= '9' ){clist2.push_back(str2[i]);}else{cout <<"乘數中的數字只能為0~9" <<endl;exit(1);}}list<char> rs = long_mul(clist1,clist2);cout << "兩個大整數相乘的積為: ";for(list<char>::iterator iter=rs.begin(); iter!=rs.end(); ++iter){cout << *iter;}cout <<endl;system("pause");return 0; }

總結

以上是生活随笔為你收集整理的任意长度的两个大数的乘法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。