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

输入二个64位的十进制数,计算相乘之后的乘积。

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

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

#include <iostream.h>

#define MAX 100

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

{

  int i=0,num_str=0;

  while(str[ i ]!=0)

  {num_str++;

  i++;

  }

  return(num_str);

}

void place(int num_str,char str[]) //将字符串高低颠倒。

{

  int temp=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;

  }

}

void transition(unsigned int a[],char str1[]) //数字字符转化为数字。

{

  int i=0;

  while(str1[ i ]!=0)

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

  i++;

  }

}

void multiply_int(unsigned int a[],unsigned int b[],unsigned int c[]) //大数相乘算法,入口为整形数组。

{

  int i=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;

  }

}

void output(int sign,unsigned int c[],int quan) //数据输出。

{

  int sign_temp=0,i=0;

  cout<<"The result is: ";

  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;

}

void multiply_string(char str1[],char str2[],unsigned int c[]) //大数相乘,入口为字符串。

{

  unsigned int a[MAX]={0},b[MAX]={0};

  int sign=0;

  transition(a,str1);

  transition(b,str2);

  multiply_int(a,b,c);

}

int sign_comp(char str1[],char str2[]) //符号判断,如果为负数将作相应处理。

{

  int i=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);

}

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

{

  int point=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<<"data error"<<endl;

    return(-1);

    }

    else

    {point++;

    sign_point=i;

    }

    if(point>1)

    {cout<<"data error"<<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);

}

void clear(char str[]) //清空函数。

{

  int i;

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

  {

    str[ i ]=0;

  }

}

 

void main(void) //主函数。

{

  char str1[MAX]={0},str2[MAX]={0};

  int quan1=0,quan2=0,sign=0;

  unsigned int c[MAX*2+1]={0};

  do

  {

    cout<<"Please input the first number:";

    cin>>str1;

    cout<<"Please input the second number:";

    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]);

    }

}


你可能感兴趣的:(笔试题汇集之大数处理篇(C/C++))