我必须找到给定字符串中数字的总和 例如,对于“ a11b3”,该金额将被退还14,因为(11 + 3 = 14) 我编写了以下代码,但是在任何情况下都不适合我,如何对其进行优化?
int SumStr(char* str)
{
int i, sum = 0, digit = 0;
while (*str)
{
digit = 0;
while (*str >= '0' && *str <= '9' && *str)
{
digit = digit * 10 + (*str - '0');
str++;
}
if (digit > 0)
sum += digit;
str++;
}
return sum;
}
答案 0 :(得分:2)
您可以使用指针在字符串中循环;找到数字后,可以将指针传递到strtol()
,以将字符串的其余部分转换为数字。 strtol()
函数接受一个指向要转换的字符串的初始部分的指针(一个char *
),以及一个指针的指针,该指针用于存储指向字符串其余部分的指针。被转换(char **
)。在这种情况下,可以为该结束指针指定str
的地址,以便在转换数字后,在转换的数字结束后恢复对数字的搜索。
请注意,strtol()
返回一个long
值。下面的sum_str()
函数返回一个long
。如果需要,您可以返回一个int
,但是如果最终的sum
值太大而不能容纳到int
中,则返回的值将取决于实现。
可以在求和循环中添加一些检测溢出的测试(这将是一个好主意)。没有为输入字符串中的负数提供任何条件(没有要求)。请注意,在输入字符串中允许负数的简单更改仅涉及测试'-'
字符和后跟数字:
if (isdigit(*str) || (*str == '-' && isdigit(*(str + 1)))) {
sum += strtol(str, &str, 10);
在将输入字符串提供给函数之前,可能应先对其进行验证。是否应该允许没有数字的字符串?是否应该允许在数字之间使用多个字符的字符串?是否应允许使用末位数为非数字的字符串?应该允许带小数点的字符串吗?这些问题的答案将使sum_str()
函数和对其进行调用的代码得以完善。在下面的代码中,不包含数字的字符串返回的总和为零,一个或多个非数字字符的组(包括小数点)用于分隔要求和的数字,最后一个数字之后的末尾字符将被忽略。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
long sum_str(char *str);
int main(void)
{
printf("%ld\n", sum_str("a11b3c-4"));
return 0;
}
long sum_str(char *str)
{
long sum = 0;
while(*str) {
if (isdigit(*str)) {
sum += strtol(str, &str, 10);
}
if (*str) { // don't increment if end of string reached
++str;
}
}
return sum;
}
程序输出:
14
答案 1 :(得分:1)
如何优化它?。我不确定以下内容将如何在速度或内存大小方面进行优化,但这确实使代码更简单,更易读:
以下使用isdigit()
函数和 ASCII values 来计数数字:
int main(void)
{
char buf[] = {"abc23jrt5"};//sum of integers: 23 + 5 = 28
int count = int SumStr(buf);
return 0;
}
//Edited to sum instances of numbers embedded in string.
//adjacent digits such as `11` in the string `avf11e5` are treated
//as the integer value `11`, not `1 + 1`.
int SumStr(char *buf)
{
int i = 0;
int sum = 0;
while( *buf != 0 )
{
i = 0;
while(isdigit(*buf))
{
i *= 10, i += *buf - '0';
if(*buf != 0) buf++;
}
sum += i;
if(*buf != 0) buf++;
}
return sum;
};
答案 2 :(得分:0)
您要多做str++
。
int SumStr(const char *str) { // added const
int sum = 0, digit = 0; // removed i
while (*str) {
digit = 0;
while (*str && *str >= '0' && *str <= '9') { // swapped order of conditions
digit = digit * 10 + (*str - '0');
str++;
}
if (digit > 0) sum += digit;
else str++; // added else
}
return sum;
}