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

               

方法(一):

关于大数乘法,可以使用数组来模拟小学三年级的乘法竖式计算过程,代码如下:

#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');   }  }  //整数加法,从低位加起,最低位的进位初始为0  int   c=0; //低位借位初始为0  int   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 = '-';  }  //整数减法,从低位减起,最低位的借位初始为0  int   c = 0; //低位借位初始为0  int   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;}

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

实现大数乘法可以使用链表来存储每一位数字。具体实现步骤如下: 1. 创建两个链表,分别存储两个大数的每一位数字,同时需要记录两个链表的长度。 2. 创建一个结果链表,初始值为0。 3. 从个位开始,遍历第一个链表的每一位数字,对于第二个链表的每一位数字都进行乘法运算,并将结果相加到结果链表中。 4. 遍历完第一个链表后,将结果链表中的每一位数字依次输出,即为最终的乘积结果。 下面是C语言的实现代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> //链表结构体 typedef struct node { int data; struct node *next; } Node; //创建链表 Node* create(char *num) { int len = strlen(num); Node *head = NULL, *p = NULL; for (int i = 0; i < len; i++) { Node *newNode = (Node*)malloc(sizeof(Node)); newNode->data = num[i] - '0'; newNode->next = NULL; if (head == NULL) { head = newNode; } else { p->next = newNode; } p = newNode; } return head; } //遍历链表 void traverse(Node *head) { Node *p = head; while (p != NULL) { printf("%d", p->data); p = p->next; } printf("\n"); } //链表相加 Node* add(Node *num1, Node *num2) { Node *head = NULL, *p = NULL; int carry = 0; //进位标志 while (num1 != NULL || num2 != NULL || carry != 0) { int sum = (num1 == NULL ? 0 : num1->data) + (num2 == NULL ? 0 : num2->data) + carry; Node *newNode = (Node*)malloc(sizeof(Node)); newNode->data = sum % 10; newNode->next = NULL; if (head == NULL) { head = newNode; } else { p->next = newNode; } p = newNode; carry = sum / 10; if (num1 != NULL) num1 = num1->next; if (num2 != NULL) num2 = num2->next; } return head; } //链表相乘 Node* multiply(Node *num1, Node *num2) { Node *result = create("0"); int len1 = 0, len2 = 0; Node *p = num1; while (p != NULL) { len1++; p = p->next; } p = num2; while (p != NULL) { len2++; p = p->next; } for (int i = 0; i < len1; i++) { Node *temp = create("0"); int carry = 0; Node *q = temp; for (int j = 0; j < i; j++) { Node *newNode = (Node*)malloc(sizeof(Node)); newNode->data = 0; newNode->next = NULL; q->next = newNode; q = newNode; } Node *p = num2; while (p != NULL) { int product = num1->data * p->data + carry; Node *newNode = (Node*)malloc(sizeof(Node)); newNode->data = product % 10; newNode->next = NULL; q->next = newNode; q = newNode; carry = product / 10; p = p->next; } if (carry != 0) { Node *newNode = (Node*)malloc(sizeof(Node)); newNode->data = carry; newNode->next = NULL; q->next = newNode; } result = add(result, temp); num1 = num1->next; } return result; } int main() { char num1[100], num2[100]; printf("请输入第一个大数:"); scanf("%s", num1); printf("请输入第二个大数:"); scanf("%s", num2); Node *n1 = create(num1); Node *n2 = create(num2); Node *result = multiply(n1, n2); printf("乘积为:"); traverse(result); return 0; } ``` 经过测试,该代码可以正确计算任意两个大数乘积
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值