将整数从字符串保存到向量
Save integers from string to vector
我需要将整数从字符串保存到向量。
数字的定义:每一个完全由数字组成的字符串子串,在该子串的第一个字符前有一个space,在最后一个字符后有一个space或标点符号,除非substring 位于字符串的开头或结尾(在这种情况下,前面不必有 space 或后面有 space 或标点符号)。
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;
}
OUTPUT:
120 35 85 // ✅
2 2 // ❌
你能帮我修改一下以使其在示例 2 中正常工作吗?
怎么查看号码前有space,号码后有space/punctuation?
makeNumber 应该是
int MakeNumber(std::vector <int> temp) {
int num = 0;
for( int digit : temp){
num *= 10;
num += digit;
}
return num;
}
不会更改答案,但可以处理任意数量的数字(假设它适合 int)
你的要求,数字后面可以有标点符号,但不能有其他字符,所以它们被认为是一个数字,这使得问题有点难。
解决此“解析规则”的一种方法是使用正则表达式。
首先,我们将输入字符串拆分为单词(由空格包围),然后
我们测试一个单词是否满足数量要求。
我们使用 std::istringstream
从字符串中一次读取一个单词,而不是回退到细节 C-style 基于字符的解析代码。
最后,无论我们考虑什么数字,我们都用 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 brave students, 35 failed, remaining 85... => (120 35 85)
2PAC and U2 have 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] == '[=10=]') {
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;
}
我需要将整数从字符串保存到向量。
数字的定义:每一个完全由数字组成的字符串子串,在该子串的第一个字符前有一个space,在最后一个字符后有一个space或标点符号,除非substring 位于字符串的开头或结尾(在这种情况下,前面不必有 space 或后面有 space 或标点符号)。
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;
}
OUTPUT:
120 35 85 // ✅
2 2 // ❌
你能帮我修改一下以使其在示例 2 中正常工作吗? 怎么查看号码前有space,号码后有space/punctuation?
makeNumber 应该是
int MakeNumber(std::vector <int> temp) {
int num = 0;
for( int digit : temp){
num *= 10;
num += digit;
}
return num;
}
不会更改答案,但可以处理任意数量的数字(假设它适合 int)
你的要求,数字后面可以有标点符号,但不能有其他字符,所以它们被认为是一个数字,这使得问题有点难。
解决此“解析规则”的一种方法是使用正则表达式。 首先,我们将输入字符串拆分为单词(由空格包围),然后 我们测试一个单词是否满足数量要求。
我们使用 std::istringstream
从字符串中一次读取一个单词,而不是回退到细节 C-style 基于字符的解析代码。
最后,无论我们考虑什么数字,我们都用 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 brave students, 35 failed, remaining 85... => (120 35 85)
2PAC and U2 have 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] == '[=10=]') {
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;
}