华中科技大学 2010 a+b

来源:互联网 发布:淘宝超级会员消费多少 编辑:程序博客网 时间:2024/04/28 13:42

题目:
        实现一个加法器,使其能够输出a+b的值(a和b的位数不超过1000位)。

思路:
        a和b输入字符串中,并从低到高位以9个字符为一段,对字符串进行分段,然后分别转成整数。a和b对应的整数段相加后,再把结果转成字符串,相连并输出。
        <为什么用9字符为一段?int型最大的数为10位数(2147483647),两个10位数相加可能超过2147483647,导致溢出。 而两个9位数相加则不会溢出,所以采用9字符分段。>

学习与体会:

1.<climits>或<limits.h>头文件,可查看基本数据类型的最大最小值,例:cout<<INT_MAX<<endl。

2.动态分配撤销数组语法:int *intA=new int[dA]; delete [] intA。

3.char*strncpy(char* cc,const char* a,int n);
   作用:把a地址开始的连续n个字符,赋给cc指针所在连续空间。
   头文件:<cstring>或<string.h>
   注意:赋值后,不会自动加'\0'。

   int atoi(const char *str);
   作用:字符串转成整数。
   头文件:<cstdlib>或<stdlib.h>。

   int sprintf(char *a,const char *format,[argument]);
   作用:把格式化的数据写入字符串a中,返回字符串长度。会在末尾自动加'\0'。
   注意:可用它完成int转化成字符串的功能。
//例子:
char cc[20];int a=11111;char b='g';cout<<sprintf(cc,"%d love %c",a,b)<<endl;  cout<<cc<<endl;    
//输出:1211111 love g

   itoa():int转换成字符串。
   有的平台不支持,被抛弃,所以换用sprintf()函数最好。
4.for(i=0;i<5 && dA!=10;i++):会判断"i<5 && dA!=10"的真假;
    for(i=0;a+=a , dA!=10;i++):会执行"a+=a",并判断"dA!=10"的真假。
5.char*可以和string相加,但结果只能赋给string。也只允许char*赋给string,而不能反过来。<因为string对=和+都有重载>。


#include <iostream>#include <stdio.h>#include <cstring>#include <cstdlib>#include <string>using namespace std;int main(){string a,b;                                                                                     //两个相加数string Zero[10]={"","0","00","000","0000","00000","000000","0000000","00000000","000000000",};  //整数转回字符串时,填充成9字符串int lenA,lenB;                                                                                  //a,b位数int dA,dB;                                                                                      //分段段数int i,j;char cc[10];                                                                                    //字符串段(9个字符)while(cin>>a>>b){                         //输入两个相加数lenA=a.length();                            //求a,b字符串长度lenB=b.length();if(lenA<=9 && lenB<=9)                      //长度都小于9,则不用分段,直接转整数相加cout<<atoi(a.c_str())+atoi(b.c_str())<<endl;else{                                       //长度不都小于9,要分段dA=lenA/9+(lenA%9?1:0);                       //求a和b分段段数dB=lenB/9+(lenB%9?1:0);int *intA=new int[dA];                        //申请int数组int *intB=new int[dB];memset(intA,0,dA*sizeof(int));                //int数组清0memset(intB,0,dB*sizeof(int));for(i=1;i<dA;i++){                            //把a的分段字符串转成整数,存入intAstrncpy(cc,&a[lenA-i*9],9);                     //strncpy():某地址开始的几个字符,赋给某字符指针cc[9]='\0';intA[dA-i]=atoi(cc);                            //atoi():字符串转成int}strncpy(cc,&a[0],lenA-(dA-1)*9);cc[lenA-(dA-1)*9]='\0';intA[0]=atoi(cc);for(i=1;i<dB;i++){                            //把b的分段字符串转成整数,存入intBstrncpy(cc,&b[lenB-i*9],9);cc[9]='\0';intB[dB-i]=atoi(cc);}strncpy(cc,&b[0],lenB-(dB-1)*9);cc[lenB-(dB-1)*9]='\0';intB[0]=atoi(cc);int pub=dA<dB?dA:dB;                          //求公有的段数,和私有段数int pri=dA<dB?(dB-pub):(dA-pub);int jinwei=0;                                 //进位if(dA>dB){                                    //a的段数大于b的段数,则和存入intA[]for(i=1;i<=pub;i++){                           //处理共有段intA[dA-i]=intB[dB-i]+intA[dA-i]+jinwei;if(intA[dA-i]>=1000000000){                      //有进位intA[dA-i]-=1000000000;jinwei=1;}else                                             //无进位jinwei=0;}for(i=pri-1;i>=0 && jinwei!=0;i--){            //处理私有段,一旦进位为0,则不用再处理下去intA[i]+=jinwei;if(intA[i]>=1000000000){intA[i]-=1000000000;jinwei=1;}elsejinwei=0;}                                               //把int段转成长度为9的字符串,并重新连接输出a=jinwei==1?"1":"";                            //jinwei=1:则要最高位多输出一个1memset(cc,'\0',10*sizeof(char));sprintf(cc,"%d",intA[0]);                      //sprintf():把数据转成字符串,赋给字符指针a+=cc;for(i=1;i<dA;i++){sprintf(cc,"%d",intA[i]);j=strlen(cc);a=a+Zero[9-j]+cc;}cout<<a<<endl;                                 //输出结果}else{                                         //a的段数不大于b的段数,则和存入intB[]for(i=1;i<=pub;i++){                           //处理共有段intB[dB-i]=intA[dA-i]+intB[dB-i]+jinwei;if(intB[dB-i]>=1000000000){                      //有进位intB[dB-i]-=1000000000;jinwei=1;}else                                             //无进位jinwei=0;}for(i=pri-1;i>=0;i--){                         //处理私有段,一旦进位为0,则不用再处理下去intB[i]+=jinwei;if(intB[i]>=1000000000){intB[i]-=1000000000;jinwei=1;}else{jinwei=0;break;}}                                                               //把int段转成长度为9的字符串,并重新连接输出b=jinwei==1?"1":"";                            //jinwei=1:则要最高位多输出一个1memset(cc,'\0',10*sizeof(char));//b+=itoa(intB[0],cc,10);sprintf(cc,"%d",intB[0]);b+=cc;for(i=1;i<dB;i++){//itoa(intB[i],cc,10);sprintf(cc,"%d",intB[i]);j=strlen(cc);b=b+Zero[9-j]+cc;}cout<<b<<endl;                                 //输出结果}delete [] intA;                               //删除动态申请的intA和intBdelete [] intB;}}return 0;}


1 0
原创粉丝点击