【问题标题】:Extracting integer values from string elements and adding up从字符串元素中提取整数值并相加
【发布时间】:2012-11-08 08:48:12
【问题描述】:

我有以下几行代码:

vector<string> c;
string a;
for(int i=0;i<4;i++){
   cin>>a;
   c.push_back(a);
}

如果我提供以下输入:

120$,132$,435$,534$

如何分别提取整数值并将它们相加得到总值?

【问题讨论】:

标签: c++ string extraction addition


【解决方案1】:

您可以使用例如std::getline 使用逗号自定义“行”分隔符,去掉字符串中的最后一个字符('$')并使用std::stoi 转换为整数:

std::vector<int> c;

for (int i = 0; i < 4; i++)
{
    std::string a;
    std::getline(std::cin, a, ',');

    a = a.substr(a.length() - 1);  // Remove trailing dollar sign

    c.push_back(std::stoi(a));
}

编辑:使用std::accumulate

int sum = std::accumulate(c.begin(), c.end(), 0);

编辑2:使用std::strtol而不是std::stoi

std::stoi 函数是最新的 C++ 标准 (C++11) 中的新功能,但尚未在所有标准库中都支持。然后你可以使用旧的 C 函数strtol:

c.push_back(int(std::strtol(a.c_str(), 0, 10)));

【讨论】:

  • 对我来说这听起来有点像滥用“行分隔符”。 (但对此的看法确实不同。)
  • 值得一提的是std::accumulate()来计算vector&lt;int&gt;的总和。
  • 你不需要去掉'$'str::stoi 会处理这个问题。
  • @Gorpik 但是输入格式需要$,您需要测试它是否存在,并且如果省略逗号,您还需要确保错误(例如,有些东西比如123$456)。处理输入通常很重要,因为用户可以做如此疯狂的事情。
  • @hmjd 很抱歉我是新手......但是你能告诉我如何申请累积
【解决方案2】:

您可以使用正则表达式和流:

#include <regex>
#include <iostream>
#include <sstream>

const std::string Input("120$,132$,435$,534$");

int main(int argc, char **argv)
{
    const std::regex r("[0-9]+");
    int Result = 0;

    for (std::sregex_iterator N(Input.begin(), Input.end(), r); N != std::sregex_iterator(); ++N)
    {
        std::stringstream SS(*N->begin());
        int Current = 0;
        SS >> Current;
        Result += Current;
        std::cout << Current << '\n';
    }

    std::cout << "Sum = " << Result;

    return 0;
}

输出:

120
132
435
534
Sum = 1221

如果您必须确保数字后跟 '$',则将正则表达式更改为:"[0-9]+\\$" stringstream 部分将忽略数字转换中的尾随 '$'

#include <regex>
#include <iostream>
#include <sstream>

const std::string Input("120$,132$,435$,534$,1,2,3");

int main(int argc, char **argv)
{
    const std::regex r("[0-9]+\\$");
    int Result = 0;

    for (std::sregex_iterator N(Input.begin(), Input.end(), r); N != std::sregex_iterator(); ++N)
    {
        std::stringstream SS(*N->begin());
        int Current = 0;
        SS >> Current;
        Result += Current;
        std::cout << Current << '\n';
    }

    std::cout << "Sum = " << Result;

    return 0;
}

输出:

120
132
435
534
Sum = 1221

【讨论】:

    【解决方案3】:

    如果输入不是太大(特别是如果它是单个 行),最简单的解决方案是将其全部打包成一个字符串,然后解析 那,创建一个std::istringstream 来转换每个数字 字段(或使用boost::lexical_cast&lt;&gt;,如果有一些奇怪的机会 适当的语义——通常在翻译一个 字符串转换为内置数字类型)。对于这么简单的事情,它是 但是,可以直接从流中读取:

    std::istream&
    ignoreDollar( std::istream& stream )
    {
        if ( stream.peek() == '$' ) {
            stream.get();
        }
        return stream;
    }
    
    std::istream&
    checkSeparator( std::istream& stream )
    {
        if ( stream.peek() == ',' ) {
            stream.get();
        } else {
            stream.setstate( std::ios_base::failbit );
        }
        return stream;
    }
    
    std::vector<int> values;
    int value;
    while ( std::cin >> value ) {
        values.push_back( value );
        std::cin >> ignoreDollar >> checkSeparator;
    }
    int sum = std::accumulate( values.begin(), values.end(), 0 );
    

    (在这种特殊情况下,只做所有事情可能会更简单 在while 循环中。操纵器是一种普遍有用的技术, 但是,并且可以在更广泛的上下文中使用。)

    【讨论】:

    • ...你能告诉我如何按照我想要的方式去做吗?假设使用向量我有字符串集合为 `123$ 324$ 453$ 545$ 现在我需要找到所有这些输入的总和。那我该怎么完成呢??
    • @ejjy 只需使用上述技术将字符串转换为数字,然后在数字上使用std::accumulate。 (您可能想要定义一个转换器对象,并在字符串向量上使用std::transform。)
    【解决方案4】:

    一个简单的版本:

    int getIntValue(const std::string& data)
    {
      stringstream ss(data);
      int i=0;
      ss >> i;
      return i;
    }
    
    int getSum(std::vector<std::string>& c)
    {
      int sum = 0;  
      for (auto m = c.begin(); m!= c.end(); ++m)
      {
        sum += getIntValue(*m);
      }
      return sum;
    }
    

    完成

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-04
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      • 2020-07-20
      相关资源
      最近更新 更多