我需要将整数从字符串保存为向量。
数字的定义:每个字符串的子字符串都完全由数字组成,子字符串的第一个字符前有一个空格,最后一个字符后有一个空格或标点符号,除非子字符串位于字符串的最开始或末尾(在这种情况下,不必在前面有空格或后面有空格或标点符号)。
EXAMPLE 1: "120 brave students, 35 failed, remaining 85..." Numbers: 120, 35, 85
EXAMPLE 2: "2PAC and U2 have class" Numbers: // there aren't any numbers
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
int CharToInt(int c) {
return abs('0' - c);
}
int MakeNumber(std::vector < int > temp) {
int num;
if (temp.size() == 1)
num = temp[0];
if (temp.size() == 2)
num = temp[0] * 10 + temp[1];
if (temp.size() == 3)
num = temp[0] * 100 + temp[1] * 10 + temp[2];
if (temp.size() == 4)
num = temp[0] * 1000 + temp[1] * 100 + temp[2] * 10 + temp[3];
return num;
}
std::vector < int > ExtractNumbers(std::string str) {
std::vector < int > a;
bool found_number;
std::vector < int > temp;
for (int i = 0; i < str.length(); i++) {
// skip spaces
found_number = false;
while (str[i] == ' ' && i < str.length())
i++;
// inside word
while (str[i] != ' ' && i < str.length()) {
while (str[i] >= '0' && str[i] <= '9' && i < str.length()) {
temp.push_back(CharToInt(str[i]));
i++;
found_number = true;
}
i++;
}
if (found_number)
a.push_back(MakeNumber(temp));
temp.clear();
}
return a;
}
int main() {
std::vector < int > a = ExtractNumbers("120 brave students, 35 failed, remaining 85...");
std::vector < int > b = ExtractNumbers("2PAC and U2 have class");
for (int i: a) std::cout << i << " ";
std::cout << std::endl;
for (int i: b) std::cout << i << " ";
return 0;
}
输出:120 35 85//✅
2 2//❌
你能帮我修改这个正确工作的例子2吗?如何检查号码前是否有空格,号码后是否有空格/标点符号?
makeNumber应该是
int MakeNumber(std::vector <int> temp) {
int num = 0;
for( int digit : temp){
num *= 10;
num += digit;
}
return num;
}
不会改变答案,但可以处理任何数字(假设它适合int类型)
你的要求,数字后面可以有标点符号,但不能有其他字符,所以它们被认为是一个数字,这使问题变得有点困难。
处理这个"解析规则"的一种方法是:是使用正则表达式。首先,我们将输入字符串拆分为单词(由空格包围),然后我们测试一个单词的数字要求是否满足。我们使用std::istringstream
从字符串中一次读取一个单词,而不是回到基本的基于字符的c风格解析代码。
最后,无论我们认为是什么数字,我们都用std::stoi()
来转换。
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <vector>
#include <cctype>
#include <regex>
using StringVector = std::vector<std::string>;
using I32Vector = std::vector<int32_t>;
static std::regex number_regex(R"(d+[.,:;!?]*)");
inline bool is_number(const std::string& s) {
std::cmatch m;
return std::regex_match(s.c_str(),m,number_regex);
}
I32Vector extract_numbers(const std::string& s) {
I32Vector result;
std::string word;
std::istringstream is{s};
while (!is.eof()) {
is >> word;
std::cout << "[" << word << "]";
if (is_number(word)) {
std::cout << " is a number.";
std::cout.flush();
result.push_back(std::stoi(word));
}
std::cout << std::endl;
}
return result;
}
std::ostream& operator<<(std::ostream& stream,
const I32Vector& v) {
if (v.empty())
stream << "()" << std::endl;
else {
stream << "(" << v[0];
for (size_t i = 1; i < v.size(); i++) {
stream << " " << v[i];
}
stream << ")" << std::endl;
}
return stream;
}
int main (int argc, const char* argv[]) {
StringVector test_strings{
"120 brave students, 35 failed, remaining 85...",
"2PAC and U2 have class",
"120 brave students, 35 failed,2 remaining 85..."
};
for (const auto& s : test_strings) {
I32Vector numbers = extract_numbers(s);
std::cout << s << " => " << numbers << std::endl;
}
return 0;
}
编译后产生的,例如使用clang++-13 -std=c++20 -o numbers numbers.cpp
:
120名勇敢的学生,35名失败,剩下85名……=比;(120 35 85)
2PAC和U2有class =>()
我找到了解决这个问题的方法。
#include <iostream>
#include <string>
#include <vector>
std::vector < int > extract_numbers(std::string s) {
std::vector < int > vek;
for (int i = 0; i < s.length(); i++) {
std::string word;
while (s[i] == ' ' && i < s.length()) i++;
while (s[i] != ' ' && i < s.length()) word += s[i++];
int j = 0;
while (word[j] >= '0' && word[j] <= '9') j++;
std::string spaces = ".,;!?";
for (int i = 0; i < spaces.size(); i++)
if (word[j] == spaces[i] || word[j] == ' ') {
vek.push_back(std::stoi(word));
break;
}
}
return vek;
}
int main() {
std::string s;
std::getline(std::cin, s);
for (int i: extract_numbers(s))
std::cout << i << " ";
return 0;
}