目录
我们知道无论任何类型都有数字的最大范围,所以我们如果想要对于任何两个数都能够进行
四则运算,那么我们就可以运用一个字符串进行运算
字符串相加
char *reverse(char * s) { int len=strlen(s); int i=0; for(i=0;i<len/2;i++) { char c=s[i]; s[i]=s[len-1-i]; s[len-1-i]=c; } return s; } char * addStrings(char * num1, char * num2) { int i,n1,n2,now,cap; cap=0;//cap用来计算进位的,逢10进1,所以cap只有0或1 int len1=strlen(num1);//计算num1的长度 int len2=strlen(num2);//计算num2的长度 reverse(num1); reverse(num2); int max=len1>len2?len1:len2;//两个数相加,最大的可能长度就是,两者最大长度+1,要不然就是两者的最大值 char *c=(char *)malloc(sizeof(char)*(max+2));//我们把加后的数字存储到c里面,由于字符串的结束标志是‘\0’,所以我们开辟的时候多开辟一点 for(i=0;i<max;i++) { n1=i<len1?num1[i]-'0':0;//i<len1的话,数字都是可以的,到len的话num1后就没有数字了, n2=i<len2?num2[i]-'0':0;//同理 int now=n1+n2+cap;//now就是还没进位的数,每个位置数有可能是个两位数 cap=now/10;//cap处理进位 c[i]=(now%10)+'0';//%10就是现在的数+‘0’就是个字符了 } if(cap) { c[i]='1';//如果cap处理进位后变成了1,那么最高位进1 max++;//同时长度增长 } c[max]='\0';//最后要把最后一位变成‘\0’作为字符串的结束标志,与他反转无关,字符串结束就要加个‘\0’ reverse(c);//最后再把c给转过来 return c; }
字符串相乘
char *reverse(char *s) { int len=strlen(s); for(int i=0;i<len/2;i++) { char tmp=s[i]; s[i]=s[len-1-i]; s[len-1-i]=tmp; } return s; } char * multiply(char * num1, char * num2){ int i,j; int len1=strlen(num1); int len2=strlen(num2); int len=len1+len2;//字符串相乘的长度,最大是两个长度相加 int *mul=(int *)malloc(sizeof(int)*(len+5));//我们开辟一个相乘后的字符串数组,长度要多开辟一点,避免最后数组越界,多出来的部分我们可以在后面进行处理 char*ret=(char*)malloc(sizeof(char)*(len+5)); memset(mul,0,sizeof(int)*(len+5));//再memset里面,我们最好用sizeof(int)*计算数组的长度,而不用sizeof(mul), reverse(num1); reverse(num2); for(i=0;i<len1;i++) { for(j=0;j<len2;j++) { mul[i+j]+=(num1[i]-'0')*(num2[j]-'0');//根据竖式计算,第i位和第j位的数相乘会再第i+j位上,同时i+j位会有多个数字运算 } } for(i=0;i<len;i++)//因为mul我们多开辟了空间,所以他的长度可以到len而不越界 { mul[i+1]+=mul[i]/10;//第i+1位需要进位,是前一位/10出来的 mul[i]%=10;//每一位需要%10,才得出了真实的每一位 } //由于我们不知道相乘后的长度,所以我们要处理反转后的前导0 while(len>1&&mul[len-1]==0)//当len-1位是0是长度减减1 { len--; } //最后把数字转化成一个字符串 for(i=0;i<len;i++) { ret[i]=mul[i]+'0';//数字+‘0’就变成了一个字符 } ret[len]='\0';//把最后一位赋值为‘\0’,作为字符串的结束标志 reverse(ret);//把ret反转后就是运算后的结果 return ret; }
char *reverse(char *s) { int len=strlen(s); for(int i=0;i<len/2;i++) { char tmp=s[i]; s[i]=s[len-1-i]; s[len-1-i]=tmp; } return s; } char * addBinary(char * a, char * b) { int lena=strlen(a); int lenb=strlen(b); int maxlen=lena>lenb?lena:lenb; reverse(a); reverse(b); char *ret=(char*)malloc(sizeof(char)*(maxlen+2)); int av,bv,now,cap=0; int i=0; for(i=0;i<maxlen;i++) { av=(i<lena)?(a[i]-'0'):0; bv=(i<lenb)?(b[i]-'0'):0; now=av+bv+cap; cap=now/2; ret[i]=now%2+'0'; } if(cap) { ret[i]='1'; maxlen++; } ret[maxlen]='\0'; reverse(ret); return ret; }
千位分隔数
char * reverse(char*n)//逆序 { int len=strlen(n); for(int i=0;i<len/2;i++) { char tmp=n[i]; n[i]=n[len-1-i]; n[len-1-i]=tmp; } return n; } char * thousandSeparator(int n){ //首先先求出n是几位数 //将n转化为一个字符串 //记录字符串的长度 //把n逆序 //每三位就加个点,同时后面的位数往后挪,len++,要注意的是,加点之后,数组i对应的就变化了 ,要对这个点进行处理 //最后再逆序 int x=n; if(n==0)//当他为0的情况下,在计算长度时候不会进入计算,所以要单独拿出来写 { return "0"; } else { int len=0; while(n) { n/=10; len++;//记录他的长度 } int i=0; char*num=(char*)malloc(sizeof(char)*(len+(len-1)/3+4));//(len-1)是为了避免假如最后也是3位而多大的点,同时+4是为了让他不越界 for(i=0;i<len;i++) { if(x) { num[i]=x%10+'0'; x/=10; } } num[i]='\0';//'\0'作为字符串结束的标志,必须要写,不然是不合法的 int k=0;//因为每次加一个点,则num对应的下标所对应的元素就会发生变化 for(i=0;i<len-k;i++)//-k是为了保证每次移动他的下标对应的值不发生变换 { if(i>1&&i%3==0)// { int end=len; while(end>=i+k)//每次加点后i包含了点,所以也要往后挪 { num[end+1]=num[end];//遇到了就往后挪,空出位置给‘.’ end--; } len++; num[i+k]='.'; k++;//要先给i+k赋值才能++,否则i+k的值就变了 } } reverse(num); return num; } }