Content
输入一行字符串\(s\),提取出\(s\)中的所有数字(如果负号前后都有数字的话不算做负号而是间隔符)并输出它们的和。
数据范围:设第\(i\)行字符串中数字个数为\(cnt_i\),每个数字为\(num_{i,j}(j\in[1,cnt_i])\)。则\(|s|\leqslant1000,cnt_i\leqslant200,|num_{i,j}|\leqslant10^7,1\leqslant i\leqslant100\)。
Solution
字符串模拟题。
废话不说,我们来理一下思路:
首先,读入一行字符串。这里建议用\(\texttt{gets}\)读入一个字符数组(\(\texttt{char}\)类型)。
然后从第一个字符的下标开始,在线寻找是否有数字和负号。这时坑点就来了。
坑点1:如果负号前后都有数字,不算做后面数字的负号而是一个没用的间隔符。
判断完之后就开始记录数字了。这里和快读有些类似,设\(x=0,f=1\),其中\(x\)就是记录数字的,\(f\)就是判断正负的,这个大家应该都清楚。如果数字前面是负号(前提是判断完后是非间隔符),那么一开始\(f\)就是\(-1\)。然后往后推数字,并计入\(x\)中。最后总和直接加上\(x\times y\)就可以了。
这时又有坑点出现了:
坑点2:如果没有数字,什么都不要输出。
以下的代码中用的是一个\(\texttt{num}\)数组存储数字,并用\(\texttt{cnt}\)这个变量来记录数字个数。所以,如果是这样的话,那么字符串里没有数字,自然就意味着\(\texttt{cnt}\)这个变量等于0,就不用输出了,否则输出总和。
细节有点多,细细琢磨。
Code
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
char a[1007];
int main() {
while(gets(a)) {
int num[207] = {0}, sum = 0, n = strlen(a), cur = 0, cnt = 0;
while(cur < n) {
// printf("%c ", a[cur]);
if((a[cur] >= '0' && a[cur] <= '9') || (a[cur] == '-' && (a[cur + 1] >= '0' && a[cur + 1] <= '9') && (a[cur - 1] < '0' || a[cur - 1] > '9'))) {
int x = 0, f = 1;
if(a[cur] == '-') {f = -1; cur++;}
while(a[cur] >= '0' && a[cur] <= '9') {
x = x * 10 + (a[cur] - '0');
cur++;
// printf("%d\n", x);
}
num[++cnt] = x * f;
// printf("%d %d\n\n", num[cnt], cnt);
}
else cur++;
}
if(!cnt) continue;
for(int i = 1; i <= cnt; ++i)
sum += num[i];
printf("%d\n", sum);
}
return 0;
}