c面试题。实现任意长度的两个整数乘法--高手求救

Jack_Sun_Lnpu 2008-11-07 04:07:07
设计一个函数。实现任意长度的两个整数乘法,计算结果存储方式不限。
例如55555555555555555555555555555555555555555555×66666666666666666666666666666666666666666666。
请大侠帮忙。
...全文
1119 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
dooX8086 2010-10-12
  • 打赏
  • 举报
回复
昨天刚写了个,〜〜计算两个长正整数的积
http://topic.csdn.net/u/20101010/21/63634408-6ef9-4151-8f43-e2b8f6fda3a7.html
在9楼
kumanong 2010-10-12
  • 打赏
  • 举报
回复
看不懂
Rainqin123 2010-10-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wuyu637 的回复:]
#include <stdio.h>
#include <string.h>

int a[101], b[101], c[202];
int mul(int l1, int l2, int a1[101], int a2[101], int c[202])
{
int i, j;
int y;//进位

int x;//乘积

int z;//余数

……
[/Quote]


牛x,本人也有此想法,但我进过用模板写的,所以建议做成模板,能不能线性代数方式实现....???
赵4老师 2010-10-12
  • 打赏
  • 举报
回复
模拟小学三年级乘法竖式
太乙 2008-11-09
  • 打赏
  • 举报
回复
http://bbs.emath.ac.cn/tag-%B4%F3%CA%FD.html
qq675927952 2008-11-09
  • 打赏
  • 举报
回复
学习了,顶
qq675927952 2008-11-09
  • 打赏
  • 举报
回复
学习了,顶
qq675927952 2008-11-09
  • 打赏
  • 举报
回复
学习了,顶
  • 打赏
  • 举报
回复
使用数组来存储高位的数据。

给你个20的阶乘的例子自己看看

#include <iostream>
#include <stdlib.h>
int Func(int*,int);
int main(int argc, char *argv[])
{
int N;
int a[20]={1};
cout<<"请输入阶乘的大小,大于0且小于20:";
cin>>N;
if(N<=0||N>20)
cout<<"请输入正确的数字!";
Func(a,N);
cout<<"阶乘的结果为:" ;
for(int i=19;i>=0;i--)
{
cout<<a[i];
}
system("PAUSE");
return 0;
}
int Func(int *a,int N)
{
int b[20]={1};
for(int i=1;i<=N;i++)
{
b[0]=(a[0]*i)%10;
for(int j=1;j<20;j++)
{
b[j]=(a[j]*i+(a[j-1]*i)/10)%10;
}
for(int i=0;i<20;i++)
{
a[i]=b[i];
}
}
}
insmile 2008-11-09
  • 打赏
  • 举报
回复
比较
tlw112 2008-11-09
  • 打赏
  • 举报
回复
mark

1楼的网址 收藏

2楼 慢慢看

mark
cyr12 2008-11-09
  • 打赏
  • 举报
回复
我这有一个例子
支持1万位的乘法
/*
高精度乘法
输入:两行,每行表示一个非负整数(不超过10000位)
输出:两数的乘积。
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>

#define MAX 10001

int bigchenfa(int *sum, int *a, int *b, int lsum, int la, int lb)
{
int i, j, k;
memset(sum, 0, sizeof(sum));
lsum = 0;
for (i = 1; i <= la; i++)
/*用数组模拟运算*/
for (j = 1, lsum = i - 1; j <= lb; j++)
sum[++lsum] += b[j] *a[i];

for (i = 1; i <= lsum; i++)
/*进位处理*/
if (sum[i] >= 10)
{
if (sum[lsum] >= 10)
lsum++;
sum[i + 1] += sum[i] / 10;
sum[i] %= 10;
}

return lsum;
}


int main(void)
{
int a[MAX]={0},b[MAX]={0},sum[MAX*2]={0} ;
int la = 0, lb = 0, lsum = 0;
int i, j;
char sa[MAX], sb[MAX];
printf("输入两个相乘的数:\n");
scanf("%s %s", sa, sb);

la = strlen(sa);
lb = strlen(sb);

for (i = 1, j = la - 1; i <= la; i++, j--)
a[i] = sa[j] - '0';
for (i = 1, j = lb - 1; i <= lb; i++, j--)
b[i] = sb[j] - '0';

lsum = bigchenfa(sum, a, b, lsum, la, lb);

for (i = lsum; i >= 1; i--)


printf("%d", sum[i]);

printf(" ");

system("pause");

return 0;
}
Big鹏 2008-11-09
  • 打赏
  • 举报
回复

UP 2楼!

nk_ysg 2008-11-09
  • 打赏
  • 举报
回复
mark,正好想学习
hmsuccess 2008-11-09
  • 打赏
  • 举报
回复

/*******大整数乘法*********/
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()
{
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 << "2数相乘的积为: ";
for(list<char>::iterator iter=rs.begin(); iter!=rs.end(); ++iter)
{
cout << *iter;
}
cout <<endl;

return 0;
}
hmsuccess 2008-11-09
  • 打赏
  • 举报
回复
以供参考

******大整数乘法分治方法的简单描述:*************
**设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;
}

待续
hmsuccess 2008-11-09
  • 打赏
  • 举报
回复
学习,大数乘法(采用分治)
cyj626 2008-11-07
  • 打赏
  • 举报
回复
mark
Jack_Sun_Lnpu 2008-11-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lbh2001 的回复:]
大数乘法,建议看看
http://bbs.emath.ac.cn/
[/Quote]
谢谢大侠
wuyu637 2008-11-07
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <string.h>

int a[101], b[101], c[202];
int mul(int l1, int l2, int a1[101], int a2[101], int c[202])
{
int i, j;
int y;//进位

int x;//乘积

int z;//余数

int w;//乘积结果保存位置


memset((void *)&c[0], 0, sizeof(int));
for(i = 0; i < 101; i++){
for(j = 0; j < 101; j++){
x = a1[i] * a2[j];
z = x % 10;
y = x/10;
w = i + j;
c[w] += z;
c[w+1] += y + c[w]/10;
c[w] %= 10;
}
}

w = l1 + l2;
if(c[w-1] == 0){
w--;
}

return w;
}

int main(int argc, char **argv)
{
char str[101];
int i, pos, len1, len2;

if(fgets(str, 101, stdin) != NULL){
len1 = strlen(str);
for(i = 0; i < len1-1; i++){
a[i] = str[i] - 48;
}
}

if(fgets(str, 101, stdin) != NULL){
len2 = strlen(str);
for(i = 0; i < len2-1; i++){
b[i] = str[i] - 48;
}
}

pos = mul(len1-2, len2-2, a, b, c);
for(i = 0; i <= pos; i++){
printf("%d", c[i]);
}
printf("\n");

return 0;
}
加载更多回复(1)

70,014

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧