C - 如果长度不同,则将 2 个字符串中的数字加在一起
Posted
技术标签:
【中文标题】C - 如果长度不同,则将 2 个字符串中的数字加在一起【英文标题】:C - Adding the numbers in 2 strings together if a different length 【发布时间】:2013-05-21 01:20:16 【问题描述】:如果我有两个字符串:
a = "1234"
b = "4321"
我可以像这样将这两个数字相加:
for(i=0; i<width-1; i++)
sum = (a[width-2-i]-48) + (b[width-2-i]-48) + carry;
carry = 0;
if(sum > 9)
carry = 1;
sum-=10;
answer[i] = sum+48;
if(carry) answer[i++] = carry+48;
answer[i]= 0;
然后反转它(宽度等于strlen(a))。
如果出现以下情况,我怎么能做同样的事情?
a = "12345"
b = "4321"
我需要重新分配内存吗?还是什么?
(顺便说一句 - the problem I'm trying to solve 使用了许多 50 位数字,所以我理解 strtoul 或 strtoull 是不可能的。Here's my code so far。)
【问题讨论】:
您可以在较小的数字前加上 0,使其长度与较大的数字相等。 【参考方案1】:int getcharval(const char *s, int idx)
if (idx < strlen(s))
return s[strlen(s) - idx - 1] - 48;
return 0;
void add()
const char *a = "1234";
const char *b = "13210";
char answer[256];
int i, wa=strlen(a), wb=strlen(b), width, sum, carry;
width = wa > wb ? wa : wb;
for(i=0; i<width; i++)
char ca = getcharval(a, i);
char cb = getcharval(b, i);
printf("%d %d\n", ca, cb);
sum = ca + cb + carry;
carry = 0;
if(sum > 9)
carry = 1;
sum-=10;
answer[i] = sum+48;
if(carry) answer[i++] = carry+48;
answer[i]= 0;
for (i = 0; i < strlen(answer) / 2; i++)
char t = answer[i];
answer[i] = answer[strlen(answer) - i - 1];
answer[strlen(answer) - i - 1] = t;
printf("%s\n", answer);
【讨论】:
【参考方案2】:如果你坚持使用“小学加法”,找到两个字符串的长度,前进到它们的末端,然后向后移动,直到较短的字符串的长度用完。然后继续只移入较长的字符串,假设较短的字符串的剩余数字为零:
12345
04321
您需要一直移动到较长字符串的开头,并在那里处理进位。请注意,无论如何您都需要分配一个新结果,因为添加两个N
-digit 数字可能会由于进位而导致N+1
-digit 数字。
【讨论】:
除了这个添加之外,还有更有效的方法吗?无需创建一些新的“数据类型”或结构.. @jaska 不幸的是,C 没有为任意精度数学提供太多结构。不过,您可以为它找到许多预构建的库。 谢谢。我正在努力让普通 C 变得更舒服,不要让自己太轻松:)) bis spader【参考方案3】:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define c2d(c) (c-'0')
#define d2c(c) (c+'0')
char* add(const char *a, const char *b, char *ans)
int alen, blen;
int i, carry=0;
char *wk;
char *awk=strdup(a);
char *bwk=strdup(b);
alen=strlen(strrev(awk));
blen=strlen(strrev(bwk));
if(alen<blen)
alen ^= blen;blen ^= alen;alen ^= blen;//swap
wk = awk ; awk = bwk ; bwk = wk;
ans[alen+1]=ans[alen]='\0';
for(i=0;i<alen;++i)
int sum = c2d(awk[i])+(i<blen ? c2d(bwk[i]): 0)+carry;
ans[i] = d2c(sum % 10);
carry = sum / 10;
if(carry)
ans[i++]='1';
free(awk);
free(bwk);
return strrev(ans);
int main()
const char *a="12345";
const char *b="4321";
char ans[6];
printf("%s+%s=%s\n", a, b, add(a,b, ans));
return 0;
【讨论】:
【参考方案4】:引用自C - Adding the numbers in 2 strings together if a different length 回答,我写了一个更易读的代码:
void str_reverse(char *beg, char *end)
if(!beg || !end)return;
char cTmp;
while(beg < end)
cTmp = *beg;
*beg++ = *end;
*end-- = cTmp;
#define c2d(c) (c - '0')
#define d2c(d) (d + '0')
void str_add(const char* s1, const char* s2, char* s_ret)
int s1_len = strlen(s1);
int s2_len = strlen(s2);
int max_len = s1_len;
int min_len = s2_len;
const char *ps_max = s1;
const char *ps_min = s2;
if(s2_len > s1_len)
ps_min = s1;min_len = s1_len;
ps_max = s2;max_len = s2_len;
int carry = 0;
int i, j = 0;
for (i = max_len - 1; i >= 0; --i)
// this wrong-prone
int idx = (i - max_len + min_len) >=0 ? (i - max_len + min_len) : -1;
int sum = c2d(ps_max[i]) + (idx >=0 ? c2d(ps_min[idx]) : 0) + carry;
carry = sum / 10;
sum = sum % 10;
s_ret[j++] = d2c(sum);
if(carry)s_ret[j] = '1';
str_reverse(s_ret, s_ret + strlen(s_ret) - 1);
测试代码如下:
void test_str_str_add()
char s1[] = "123";
char s2[] = "456";
char s3[10] = '\0';
str_add(s1, s2, s3);
std::cout<<s3<<std::endl;
char s4[] = "456789";
char s5[10] = '\0';
str_add(s1, s4, s5);
std::cout<<s5<<std::endl;
char s7[] = "99999";
char s8[] = "21";
char s9[10] = '\0';
str_add(s7, s8, s9);
std::cout<<s9<<std::endl;
输出:
579
456912
100020
【讨论】:
【参考方案5】:int num(char x,int len)
if(len <0)
return 0;
return ((x=='1') ? 1 : (x=='2') ? 2 : (x=='3') ? 3 : (x=='4') ? 4 : (x=='5') ? 5 : (x=='6') ? 6 : (x=='7') ? 7 : (x=='8') ? 8 : 9);
int main()
int result[100];
int i=0;
char num1[] = "123456789123456789";
char num2[] = "1234567811111111111111111111";
int carry = 0;
int l1= strlen(num1)-1;
int l2 = strlen(num2)-1;
int result1;
while(1)
if(l1 < 0 && l2 <0 && carry == 0)
break;
result1 = num(num1[l1],l1) + num(num2[l2],l2);
l1--;
l2--;
if(carry>0)
result1 +=carry;
carry = 0;
carry = result1 / 10;
result[i] = (result1 % 10);
i++;
i--;
printf("\n");
while(i>=0)
printf("%d",result[i]);
i--;
【讨论】:
请在您的代码中添加一些注释行:)以上是关于C - 如果长度不同,则将 2 个字符串中的数字加在一起的主要内容,如果未能解决你的问题,请参考以下文章