您的位置:首页 > 编程语言 > C语言/C++

笔试题汇集之大数处理篇(C/C++)

2015-07-28 10:06 351 查看
输入二个64位的十进制数,计算相乘之后的乘积。

答:以下代码为网上别人贴出的,输入任意位数十进制数(包括小数,负数)都可以得出正确结果。

思路是:将大数当作字符串进行处理,也就是将大数用10进制字符数组进行表示,然后模拟人们手工进行“竖式计算”的过程编写乘法。

#include<iostream.h>

#defineMAX100

intstr_num(charstr[])//计算字符串的长度,等效于strlen(str);

{

inti=0,num_str=0;

while(str[ i ]!=0)

{num_str++;

i++;

}

return(num_str);

}

voidplace(intnum_str,charstr[])//将字符串高低颠倒。

{

inttemp=0,i=0,j=0;

for(i=0,j=num_str-1;i<j;i++,j--)

{temp=str[j];

str[j]=str[ i ];

str[ i ]=temp;

}

}

voidtransition(unsignedinta[],charstr1[])//数字字符转化为数字。

{

inti=0;

while(str1[ i ]!=0)

{a[ i ]=str1[ i ]-'0';

i++;

}

}

voidmultiply_int(unsignedinta[],unsignedintb[],unsignedintc[])//大数相乘算法,入口为整形数组。

{

inti=0,j=0;

for(i=0;i<MAX;i++)

for(j=0;j<MAX;j++)

{

c[ i+j ]+=a[ i ]*b[ j ];

c[ i+j+1 ]+=c[ i+j ]/10;

c[ i+j ]%=10;

}

}

voidoutput(intsign,unsignedintc[],intquan)//数据输出。

{

intsign_temp=0,i=0;

cout<<"Theresultis:";

if(sign==1)

cout<<"-";

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

{

if(sign_temp==0)

{if(c[ i ]!=0)

sign_temp=1;

}

if(sign_temp==1)

{

if(i==quan-1)

cout<<".";

cout<<c[ i ];

c[ i ]=0;

}

}

cout<<endl;

}

voidmultiply_string(charstr1[],charstr2[],unsignedintc[])//大数相乘,入口为字符串。

{

unsignedinta[MAX]={0},b[MAX]={0};

intsign=0;

transition(a,str1);

transition(b,str2);

multiply_int(a,b,c);

}

intsign_comp(charstr1[],charstr2[])//符号判断,如果为负数将作相应处理。

{

inti=0,sign_num=0;

if(str1[0]==45)

{sign_num=!sign_num;

for(i=0;i<MAX-1;i++)

str1[ i ]=str1[ i+1 ];

}

if(str2[0]==45)

{sign_num=!sign_num;

for(i=0;i<MAX-1;i++)

str2[ i ]=str2[ i+1 ];

}

return(sign_num);

}

intformat(charstr[])//将输入的字符串进行格式化。以得到字符的一些标志信息和相应格式的新数据串。

{

intpoint=0,quan=0,i=0,j,k=0,sign_point=0,num_str=0;

num_str=str_num(str);

while(str[ i ]!=0)

{

if(str[ i ]<'0'||str[ i ]>'9')

if(str[ i ]!='.')

{cout<<"dataerror"<<endl;

return(-1);

}

else

{point++;

sign_point=i;

}

if(point>1)

{cout<<"dataerror"<<endl;

return(-1);

}

i++;

}

if(point==1)

{

for(j=sign_point;j<num_str;j++)

str[j]=str[j+1];

num_str--;

quan=num_str-sign_point;

}

place(num_str,str);

return(quan);

}

voidclear(charstr[])//清空函数。

{

inti;

for(i=0;i<MAX;i++)

{

str[ i ]=0;

}

}

voidmain(void)//主函数。

{

charstr1[MAX]={0},str2[MAX]={0};

intquan1=0,quan2=0,sign=0;

unsignedintc[MAX*2+1]={0};

do

{

cout<<"Pleaseinputthefirstnumber:";

cin>>str1;

cout<<"Pleaseinputthesecondnumber:";

cin>>str2;

sign=sign_comp(str1,str2);

quan1=format(str1);

quan2=format(str2);

if(quan1==-1||quan2==-1)

{

clear(str1);

clear(str2);

}

}while(quan1==-1||quan2==-1||str1[0]==0||str2[0]==0);

multiply_string(str1,str2,c);

output(sign,c,quan1+quan2);

}

-------------------------------------------------------------------------------------------------------------------------------------

下面的是大整数的运算.

#include<iostream>

using namespace std;

#define MAX 10000

struct Node{

int data;

Node *next;

};

void output(Node *head)

{

if(!head->next&&!head->data)return;

output(head->next);

cout<<head->data;

}

void Mul(char *a,char *b,intpos)

{

char *ap=a,*bp=b;

Node *head=0;

head=newNode;head->data=0,head->next=0; //

Node *p,*q=head,*p1;

int temp=0,temp1,bbit;

while(*bp) //若乘数不为空 ,继续.

{

p=q->next;p1=q;

bbit=*bp-48; //把当前位转为整型

while(*ap||temp) //若被乘数不空,继续

{

if(!p) //若要操作的结点为空,申请之

{

p=new Node;

p->data=0;

p->next=0;

p1->next=p;

}

if(*ap==0)temp1=temp;

else {temp1=(p1->data)+(*ap-48)*bbit+temp;ap++; }

p1->data=temp1%10; //留当前位

temp=temp1/10; //进位以int的形式留下.

p1=p;p=p->next; //被乘数到下一位

}

ap=a;bp++;q=q->next; //q进下一位

}

p=head;

output(p); //显示

cout<<endl;

while(head) //释放空间

{

p=head->next;

delete head;

head=p;

}

}

int main()

{

cout<<"请输入两个数"<<endl;

char test1[MAX],test2[MAX];

cin.getline(test1,MAX,'\n');

cin.getline(test2,MAX,'\n');

Mul(strrev(test1),strrev(test2));

system("PAUSE");

return 0;

}

//大数相乘

void Mul2(char* num1,int len1,

char*num2, int len2 {

int slen =len1+len2;

char* temp =(char*)malloc(slen);

char* s =(char*)malloc(slen);

int i, j;

int start;

//将第二个数的每一位与第一个数相乘并加到结果中

for(i=0;i<len2; ++i) {

memset(temp, 0, len1+len2);

start =slen-1-i;

//将第二个数的每一位与第一个数相乘

for(j=0;j<len1; ++j) {

temp[start-j] = num1[len1-1-j]*num2[len2-1-i];

}

//处理相乘后的结果,该进位的进位

for(j=start; j>=start-len1; --j) {

if(temp[j] >= 10) {

temp[j-1] += temp[j]/10;

temp[j] %= 10;

}

}

//将结果加到总结果中

for(j=start; j>=start-len1; --j) {

s[j]+= temp[j];

}

//处理总结果进位

for(j=start; j>=start-len1; --j) {

if(s[j] >= 10) {

}

}

}

for(i=0;i<slen; ++i) {

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

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: