将整数从字符串保存到向量

发布于 2025-01-24 18:44:16 字数 1869 浏览 1 评论 0原文

我需要将整数从字符串到向量。

数字的定义:每个字符串子字符串完全由数字组成,除非子字符串在字符串的开始或结尾处,否这种情况不必在前面,空间或标点符号的空间)。

示例1:“ 120名勇敢的学生,35个失败,剩下的85 ...”数字:120、35、85

示例2:“ 2pac和u2有class”号码://任何数字

#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吗? 在发现数字之后,如何检查是否有空间/标点符号?

I need to save integers from string to vector.

Definition of number: each of strings substrings which consists entirely of digits, with a space before the first character of that substring and a space or punctuation mark after the last character, unless the substring is at the very beginning or end of the string (in this case there does not have to be a space in front or space or punctuation behind).

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 // ❌

Could you help me to modify this to work correctly for the example 2?
How could I check if there is space before and space/punctuation after the number is found?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

始终不够 2025-01-31 18:44:16

该makeNumber应该

int MakeNumber(std::vector <int> temp) {
    int num = 0;
    for( int digit : temp){
        num *= 10;
        num += digit;
    }
    return num;
}

不更改答案,而应与任意数量的数字一起使用(假设它适合INT)

That makeNumber should be

int MakeNumber(std::vector <int> temp) {
    int num = 0;
    for( int digit : temp){
        num *= 10;
        num += digit;
    }
    return num;
}

doesnt change the answer but will work with any number of digits (assuming it fits in an int)

鹿! 2025-01-31 18:44:16

您的要求,数字可能会通过标点符号拖延,而不是通过其他角色拖延,因此它们被认为是一个数字,使问题更加困难。

解决此“解析规则”的一种方法是使用正则表达式。
首先,我们将输入字符串分为单词(被空间包围),然后
我们测试一个单词的数字要求是否满足。

我们使用std :: istringstream一次从字符串中读取一个单词,而不是回到基于C-Style的Nitty Gritty 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数字.cpp

120名勇敢的学生,35岁失败,剩余85 ... =&gt; (120 35 85)
2PAC和U2具有class =&gt; ()

Your requirement, that digits may be trailed by punctuation, but not by other characters, so they are considered a number, makes the problem a little bit harder.

One way to tackle this "parsing rule" is to use regular expressions.
First, we split the input string into words (surrounded by whitespace), then
we test if the number requirement is fulfilled for a word.

Instead of falling back to nitty gritty C-style character based parsing code, we use std::istringstream to read one word at a time from the string.

Finally, whatever we consider a number, we convert with 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;
}

which yields after compiling, e.g. with clang++-13 -std=c++20 -o numbers numbers.cpp:

120 brave students, 35 failed, remaining 85... => (120 35 85)
2PAC and U2 have class => ()

青衫儰鉨ミ守葔 2025-01-31 18:44:16

我找到了解决这个问题的方法。

#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] == '\0') {
        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;
}

I found a way to solve this.

#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] == '\0') {
        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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文