关于C语言实现两个大数相乘

woshidahuilang 2008-02-03 10:08:30
昨天天参加华为技术面试,最后一道题是实现两个30位大数相乘,想了半个小时没想出来,虽然过了,但是感觉很丢脸。哪位大虾知道C语言中一般不定长大数相乘应该以什么思路去解决?提供个思路就行谢谢各位!
...全文
14095 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
hmhlbhljhf4 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 的回复:]

引用 41 楼 的回复:

void multiply(char* a,char* b,char* c)
{
int i,j,ca,cb,*s;
ca=strlen(a);
cb=strlen(b);
s=(int*)malloc(sizeof(int)*(ca+cb)); //(ca + cb)

for (i=0;i<ca+cb;i……
[/Quote]

... 没仔细题目了。。"实现两个30位大数相乘"。 如果仅是30位的话,的确不会。
山治喜欢卓洛 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 的回复:]

引用 41 楼 的回复:

void multiply(char* a,char* b,char* c)
{
int i,j,ca,cb,*s;
ca=strlen(a);
cb=strlen(b);
s=(int*)malloc(sizeof(int)*(ca+cb)); //(ca + cb)

for (i=0;i<ca+cb;i……
[/Quote]
.如果不处理进位的话.
s[i+j+1] += (a[i]-'0')*(b[j]-'0');
是有些位存在大于10的数字,所以接下来得处理进位
hmhlbhljhf4 2012-08-03
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 的回复:]

void multiply(char* a,char* b,char* c)
{
int i,j,ca,cb,*s;
ca=strlen(a);
cb=strlen(b);
s=(int*)malloc(sizeof(int)*(ca+cb)); //(ca + cb)

for (i=0;i<ca+cb;i++)
s[i]……
[/Quote]

如果不处理进位的话.
s[i+j+1] += (a[i]-'0')*(b[j]-'0');
会超出int的最大范围吧?
jingnian1212 2012-06-18
  • 打赏
  • 举报
回复
MARK
tczhaodachuan 2012-03-22
  • 打赏
  • 举报
回复
不知道现在回复晚不晚。对于大数乘法,可以使用递归算法实现。不定长大数乘法用俩个数组char*存储。举个简单2位数乘法例子:A=A1A2,B=B1B2
AB 可以等于 (A1+A2)(B1+B2)=A1*B1*10^2+(A1B2+A2B1)*10+A2*B2
观察这个公式发现,其实是最左边的位数乘积和+混合乘积和+最右边的位数乘积和
可以定义函数MULTI(char X[], char Y[])返回值是俩个数乘积。伪代码如下,因为实际字符乘法与整数乘法答案不一样,前者用ASC转化。方便起见,请楼主先忽略字符乘法,假设与整数乘法一致。
char MULTI(char X[], char Y[])
{
int n=max(sizeof(X),sizeof(Y))
if n==1
return X*Y;
else
Xl=left part of X,Xr=right part of X //X=123, Xl=12, Xr=3
Yl=left part of Y, Yr=right part of Y //Y=23, Yl=2, Yr=3
char a=MULTI(Xl,Yl);
char b=MULTI(Xr,Yr);
char c=MULTI(Xl+Xr,Yl+Yr);
char result=a*10^n+(c-a-b)*10^(n/2)+b

}
建议楼主去看一下 divide and conquer 算法,正是此题的答案,我的邮箱是tczhaodachuan@gmail.com如果有问题可以给我发邮件,不知道这样解释清楚不清楚。
NarSo 2012-03-15
  • 打赏
  • 举报
回复
mark之,代码很简单。。。
david19800108 2012-03-13
  • 打赏
  • 举报
回复
void multiply(char* a,char* b,char* c)
{
int i,j,ca,cb,*s;
ca=strlen(a);
cb=strlen(b);
s=(int*)malloc(sizeof(int)*(ca+cb)); //(ca + cb)

for (i=0;i<ca+cb;i++)
s[i]=0; //必须有

//直接纵向求和,不处理进位
for (i=0;i<ca;i++)
{
for (j=0;j<cb;j++)
{
s[i+j+1] += (a[i]-'0')*(b[j]-'0'); //s[i+j+1] +=,
}
}

//对求和后的数处理进位
for (i=ca+cb-1;i>=0;i--)
{
if (s[i]>=10)
{
s[i-1]+=s[i]/10;
s[i]%=10;
}
}


i=0;
while (s[i]==0)
{
i++;
}

//保存结果到字符串
for (j=0;i<ca+cb;i++,j++)
{
c[j]=s[i]+'0';
}

c[j]='\0';
free(s);
}

很妙~
richieyaoyuan 2012-03-10
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 mopishv0 的回复:]

C/C++ code
# include<stdio.h>
# include<string.h>
# include<malloc.h>

void multiply(char* a,char* b,char* c)
{
int i,j,ca,cb,* s;
ca=strlen(a);
cb=strlen(b);
s=(int*)malloc(sizeof(i……
[/Quote]

挺好的,代码小巧可用。感谢!但有个小小问题。
应该在c[j] = '\0';之前加入以下这个判断,要不然乘积为0时不能正确输出结果到c中。

if(0 == j)
{
c[0] = '0';
j++;
}
  • 打赏
  • 举报
回复
可以用数组实现
int *newmuti(int *num1, int size1, int *num2, int size2)
{
int size = size1 + size2;
int *ret = new int[size];
memset(ret, 0, sizeof(int) * size);
int i = 0;
for (i = size1 -1; i >= 0; --i)
{
int k = size1 - i - 1;
for (int j = size2 - 1; j >= 0; --j)
{
ret[k++] += num1[i] * num2[j];
}
}

for (i = 0; i < size; i++)
{
if (ret[i] >= 10)
{
ret[i + 1] += ret[i] / 10;
ret[i] %= 10;
}
}

return ret;
}

int main(int argc, char* argv[])
{
int num1[5] = {2, 3, 7, 5, 6};//数字23756
int num2[6] = {3, 3, 2, 7, 9, 1};//数字332791

int *ret = newmuti(num1, 5, num2, 6);
int i = 0;
for(i = 10; i >= 0; i--)
{
cout << ret[i];
}
cout << endl;
delete []ret;
return 0;
}
caslina 2011-09-17
  • 打赏
  • 举报
回复
终于弄明白了,多谢楼上的分析
lspwushu 2011-07-28
  • 打赏
  • 举报
回复
有点用处~~~~~~~~~~~~~~~~~~~~~~~~~~~
啊超 2010-12-26
  • 打赏
  • 举报
回复
14楼的算法很清晰啊,太好了
我在看另一个大数相乘的程序的时候直接晕了,于是上网搜,就搜到这里了,看完之后豁然开朗!
jacquesgw 2010-10-16
  • 打赏
  • 举报
回复
学习一下。。。。。
chjunhua 2010-06-10
  • 打赏
  • 举报
回复
可以用高精度解决,将两个大数化成倒叙的数组就行了
gaorentaba 2010-06-10
  • 打赏
  • 举报
回复
三十位简单 三十二位的就恶心了 人给的提示是分成两个16位的 结果我扣了半天没搞定 觉得这个思路或许本来就有问题
qingfengbannixing 2010-04-22
  • 打赏
  • 举报
回复
用分治法http://www.comp.nus.edu.sg/~xujia/mirror/algorithm.myrice.com/problems/index.html?by_strategy/dynamic_programming.htm
看看应该会有所领悟的!!
linshao512 2010-04-09
  • 打赏
  • 举报
回复
有点难度
cmdhack 2010-01-08
  • 打赏
  • 举报
回复
Mark
astevena 2009-07-22
  • 打赏
  • 举报
回复
哇哈哈 第一次发代码 我今天刚写的
下面是头文件
//最后更新日期2009-7-22
//
//
//
///////////////////////////////////////////////////////////////
//此函数计算两个数字字符串乘积
//参数一 乘数
//参数二 被乘数
//参数三 乘积
//返回值 乘积长度
//备注 未做优化 模拟手算
int str_multiplication(char multiple[],char multiplicand[],char accumulate[]);
astevena 2009-07-22
  • 打赏
  • 举报
回复
#include "Mold Piece.h"
#include "StdAfx.h"
#include <stdio.h>
#include <string.h>
#define for if(0);else for

int str_multiplication(char multiple[],char multiplicand[],char accumulate[])
{
int i=0,j=0,m,n;
accumulate[0]='0';
accumulate[1]='0';
for (i=0;i<(int)strlen(multiple);i++)
{
for (j=0;j<(int)strlen(multiplicand);j++)
{
m=((int)(multiple[i]-48)*(int)(multiplicand[j]-48))%10; //个位
n=((int)(multiple[i]-48)*(int)(multiplicand[j]-48))/10; //十位
accumulate[i+j]=(char)(n+(int)accumulate[i+j]);
if (accumulate[i+j+1]=='\0')
{
accumulate[i+j+1]=char(m+48);
}
else
{
accumulate[i+j+1]=(char)(m+(int)accumulate[i+j+1]);
}
}
for (int x=i+strlen(multiplicand);x>0;x--)
{
if (accumulate[x]>'9')
{
accumulate[x]-=10;
accumulate[x-1]++;
}
}
}
accumulate[i+j+1]='\0';
if (accumulate[0]=='0')
{
for (i=0;i<strlen(accumulate);i++)
{
accumulate[i]=accumulate[i+1];
}
}
return strlen(accumulate);
}
加载更多回复(27)

70,014

社区成员

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

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