问题1:超大数相加
这里超大数表示已经超出int、long、long long 范围的数字,所以不能简单的相加。此时就要用字符串,把输入的内容储存在字符串中,通过字符与数字之间的关系计算结果。
思路:
1.输入xxxx+xxxxxx,已‘+’分割成两个子串。
2.逆序两个子串,末位变成首位对齐,按位相加,大于10则向后位进一。
3.需要考虑到两个数长度不同的情况。
4.再把最后的结果逆序输出,就得到了最终正向相加的结果
代码如下:
#include <stdio.h>
#include <string.h>
void reverse(char *s,int len);
char * addLargeNumber(char *s1,char *s2);
int main(int argc, char const *argv[])
{
char str[100];
int len[10];//截取的每个子串的长度
scanf("%s",str);
char *sep = "+-*/";
char *p = strtok(str,sep);
char *s = p;
char *k = p;
len[0] = strlen(p);
reverse(p, len[0]);
puts(p);
while(1)
{
s = strtok(NULL, sep);
if (s == NULL)
{
break;
}
len[1] = strlen(s);
reverse(s,len[1]);
puts(s);
k = s;//
}
printf("access to addLargeNumber\n");
p = addLargeNumber(p,k);
len[2] = strlen(p);
reverse(p,len[2]);
puts(p);
return 0;
}
//反转一个字符串
void reverse(char *s,int len)
{
char temp;
int i;
for(i = 0;i<len/2;i++)
{
temp = s[i];
s[i] = s[len-1-i];
s[len-1-i] = temp;
}
}
//接收两个字符串,把长度小的加到长度大的串上,返回相加后的串
char * addLargeNumber(char *s1,char *s2)
{
char *p = s1;
char *q = s2;
char k;
int i;
printf("子串1的长度=%lu 子串2的长度=%lu\n", strlen(p),strlen(q));
int len = strlen(q);
//确保p指向长度较长的串。确保len的值为较小的串的长度。
if (strlen(s1)<strlen(s2))
{
len = strlen(p);
q = s2;
p = s1;
}
int difflen = strlen(p)-strlen(q);//两个子串长度的差值。
//printf("len = %d difflen = %d\n",len ,difflen);
for (i = 0; i <len; ++i)
{
int a = p[i] + q[i] -96;
//printf("a = %d\n", a);
if (a>=10)
{
k = a -10+ 48;
p[i+1] += 1;
}
else
{
k = a + 48;
}
//printf("k = %c\n", k);
p[i] = k;
printf("p[%d] = %c\n", i,p[i]);
}
//解决较长串后一位如果被进位的情况。例如:1379+128(假设两个已逆序的串)或者15999+148
for(i = 0;i<difflen;i++)
{
if (p[len+i] == 58)
{
p[len+i] -= 10;
if (i == difflen-1)
{//当i指向最后一个有效数字时,并且当前位是‘:’,则将其后一位赋为结束符
p[len+i+1] = 49;//这种是赋值符号,是将'1'赋给p[i]。对比下面的运算符
p[len+difflen+1] = 0;
}
else
{
p[len+i+1] += 1;//这种是运算符,是将p[i]的ASCII码加1.
}
printf("p[%d] = %c\n",len+i,p[len+i] );
}
else
{
break;
}
}
printf("相加之后的串长度= %lu\n", strlen(p));
puts(p);
return p;
}
问题2:超大数除以一个int整数,求余数
#include <stdio.h>
#include <string.h>
int modBigNumber(char * s,int modNumber);
int main(int argc, char const *argv[])
{
/*超大整数除以一个int型整数,求余*/
char *strs = "14689";
int p = 4;
int result = modBigNumber(strs,p);
printf("%d\n", result);
return 0;
}
int modBigNumber(char * s,int modNumber){
printf("字符串:%s\n", s);
long sum = 0;
//将“14689”看成多项式相加的和,即1*10^5+4*10^4+6*10^3+8*10^2+9*10^1,每一项如果看成X,Y,Z
///结合一些模运算的性质来考虑,比如,对多个数字的相加再求模和先对中间部分结果求模再相加后面的数再求模的结果是一样的
//即 (X+Y+Z)modP =((X+Y)modP+ Z)modP = ((XmodP +Y)modP+Z)modP
//由此可以推出下面的代码:
for (int i = 0; i < strlen(s); ++i)
{
sum = sum*10 + s[i]-48;//这里要把每个字符的ASCII码减去48成为数字
printf("每个数:%ld\n", sum);
sum %= modNumber;
printf("余数:%ld\n", sum);
}
return sum;
}