逐行扫描字符串,按“后面是数字且前面不是数字”的规则识别负号并提取所有整数求和。
OJ: luogu
题目 ID: P6051
难度:普及-
标签:字符串模拟
日期: 2026-06-19 10:38
题意
给出若干行字符串,每行中可能夹杂着一些整数。
要求对每一行分别求出其中所有整数的和;如果某一行没有整数,就不输出这一行。
思路
这题最关键的是判断 - 是负号还是分隔符。
最直接的教学版写法如下:
cpp
// brute.cpp:逐字符扫描每一行,识别其中的整数并求和,作为教学版和对拍基准程序。
#include <bits/stdc++.h>
using namespace std;
bool is_digit_char(char ch) {
return ch >= '0' && ch <= '9';
}
// 只有“-后面紧跟数字,且前面不是数字”时,才把它看成负号。
bool is_negative_sign(const string &s, int i) {
if (s[i] != '-') {
return false;
}
if (i + 1 >= (int) s.size() || !is_digit_char(s[i + 1])) {
return false;
}
if (i > 0 && is_digit_char(s[i - 1])) {
return false;
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string line;
while (getline(cin, line)) {
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
long long sum = 0;
bool has_number = false;
int n = (int) line.size();
int i = 0;
while (i < n) {
if (is_digit_char(line[i]) || is_negative_sign(line, i)) {
int sign = 1;
if (line[i] == '-') {
sign = -1;
i++;
}
long long value = 0;
while (i < n && is_digit_char(line[i])) {
value = value * 10 + (line[i] - '0');
i++;
}
sum += sign * value;
has_number = true;
}
else {
i++;
}
}
if (has_number) {
cout << sum << '\n';
}
}
return 0;
}一个 - 只有在下面这种情况下才算负号:
- 后面紧跟数字;
- 前面不是数字。
于是我们逐行扫描字符串:
- 如果当前位置是数字,开始读一个正整数;
- 如果当前位置是合法负号,开始读一个负整数;
- 读完后加入当前行总和。
扫描结束时,如果这行至少出现过一个整数,就输出总和。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
bool is_digit_char(char ch) {
return ch >= '0' && ch <= '9';
}
bool is_negative_sign(const string &s, int i) {
if (s[i] != '-') {
return false;
}
if (i + 1 >= (int) s.size() || !is_digit_char(s[i + 1])) {
return false;
}
if (i > 0 && is_digit_char(s[i - 1])) {
return false;
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string line;
while (getline(cin, line)) {
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
long long sum = 0;
bool has_number = false;
int n = (int) line.size();
int i = 0;
while (i < n) {
if (is_digit_char(line[i]) || is_negative_sign(line, i)) {
int sign = 1;
if (line[i] == '-') {
sign = -1;
i++;
}
long long value = 0;
while (i < n && is_digit_char(line[i])) {
value = value * 10 + (line[i] - '0');
i++;
}
sum += sign * value;
has_number = true;
}
else {
i++;
}
}
if (has_number) {
cout << sum << '\n';
}
}
return 0;
}复杂度
- 时间复杂度:
, n为总字符数 - 空间复杂度:
(不计输入存储)
总结
这题是典型的字符串提取整数问题。
关键不是加法本身,而是把整数边界和负号规则判断准确。