无数次面对这样的问题,两个长度是几千甚至上万的字符串相加或相减,输出结果。这次专门练习写一遍。
校赛ACM时候就卡在这种题上了,不然就能AC七道题了!!
1.两个大数相加的函数比相减的简单些,不用考虑结果会不会是负数的问题。接收到两个字符串和一个要存储和的目标字符串,先反转两个字符串,后以较长字符串为目标,挨个加到存储和的字符串。当当前长度小于短串的时候,每一位再加上短串的对应位,当前位相加后超过9则进位。长度超出短串后,加上长串对应位的同时也要判断当前位有没有超过9。结束后注意判断一下和有没有超出长串的长度(可能会进位),用字符串结束标志'\0'结束目标字符串即可,反转目标字符串后结束函数。
void BigNumAdd(char* a, char* b, char* str)
{
if (strlen(a)<strlen(b))
{
BigNumAdd(b, a, str);
return;
}
reverse(a), reverse(b);
for (int i = 0; i <= strlen(a); i++)
str[i] = '0';
for (int i = 0; i<strlen(a); i++)
{
str[i] += a[i] - '0';
if (i<strlen(b))
{
int num = str[i] - '0' + b[i] - '0';
if (num>9)
{
str[i] = num - 10 + '0';
str[i + 1]++;
}
else
{
str[i] = num + '0';
}
}
else
{
if (str[i]>'9')
{
str[i] -= 10;
str[i + 1]++;
}
}
}
if (str[strlen(a)] > '0')
str[strlen(a) + 1] = 0;
else
str[strlen(a)] = 0;
reverse(str);
}
a和b是相加的两个字符串,str是目标字符串(存储和)
void reverse(char* str)
{
int ind = strlen(str) - 1;
int ins = 0;
while (ins<ind)
{
char ch = str[ind];
str[ind] = str[ins];
str[ins] = ch;
ind--, ins++;
}
return;
}
这是用到的反转字符串函数,头尾开始交换,直到中间碰头结束。
2.两个大数相减先考虑的是两数大小问题,只有大数减小数才不会出现负数的情况。我先判断两字符串长度,如果两字符串长度相同再逐位判断大小,长度不满足被减数大于减数则交换被减数和减数,并用返回值来表示此次减法运算是否结果为负。减数和被减数相同则直接赋值目标字符串0,并结束函数。
满足被减数大于减数后,反转两字符串。和大数相加的思路相同,从低位开始逐位判断相减后有没有小于0,如果小于则将高位减一。没有减数后也要逐位判断有没有出现小于0的数。最后要注意的是,高位可能若干位因为被减或借位成0,所以遍历找到第一个不为0的高位。将上一位赋值'\0'结束字符串,反转后完成大数相减。
int BigNumSub(char*a, char* b, char* str)
{
int i = 0;
int j = 0;
while (1)
{
if (strlen(a)<strlen(b))
{
BigNumSub(b, a, str);
return 1;
}
if (strlen(a)>strlen(b))
break;
else
{
if (a[i]<b[j])
{
BigNumSub(b, a, str);
return 1;
}
if (a[i]>b[j])
break;
else
{
if (i == strlen(a))
{
str[0] = '0';
str[1] = 0;
return 0;
}
i++, j++;
}
}
}
reverse(a), reverse(b);
for (int i = 0; i <= strlen(a); i++)
str[i] = '0';
for (int i = 0; i<strlen(a); i++)
{
str[i] += a[i] - '0';
if (i<strlen(b))
{
int num = str[i] - b[i];
if (num<0)
{
str[i] = num + 10 + '0';
str[i + 1]--;
}
else
{
str[i] = num + '0';
}
}
else
{
if (str[i]<'0')
{
str[i] = '9';
str[i + 1]--;
}
}
}
int st = strlen(a) - 1;
while (str[st] == '0')
st--;
str[st + 1] = 0;
reverse(str);
return 0;
}
a是被减数字符串,b是减数字符串,str是目标字符串。返回值非0表示结果为负数,为0则为正数或0。
所用到的反转字符串函数同上。
之后再写大数乘法、除法、开方?