c++ 如何提取字符串中的所有数字,其中数字中间夹杂着字母?

oknrviil  于 2023-02-20  发布在  其他
关注(0)|答案(3)|浏览(133)

如何循环遍历一个由数字和字母组成的字符串,并只向向量中添加数字?
例如,如果输入为:
电子385磅336英寸434磅26英寸26英寸52英寸
我想得到一个整型向量,如下所示:
数字= {385,336,434,26,2,6,5,2}
我得到的最好的方法是遍历该行并将所有数字相加,如下所示:

#include <bits/stdc++.h>

int main(){
    string f = "e385p336J434Y26C2Z6X5Z2";
    vector<int> f_numb; 
    string sum; 
    for (int i = 0; i < f.size(); ++i){
         if (('0' <= f[i]) && (f[i] <= '9')){
            sum += (f[i]);
            
             
         }
    }
    //std::cout << sum << std::endl; 
    vector<int> m_numb; 
    for (int i = 0; i < sum.size(); ++i){
        m_numb.push_back(sum[i] - '0'); 
    }
    int sm; 
    for (int i = 0; i < m_numb.size(); ++i){
        sm += m_numb[i]; 
        std::cout << m_numb[i] << " "; 
    }
    std::cout << std::endl; 
    
}
zynd9foi

zynd9foi1#

先不说你不使用std::isdigit的原因,你可以/应该简单地在处理数字时构建每个数字。注意下面的代码不会检查也不会关心无符号溢出,也不会尝试处理负数。

#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::string f = "e385p336J434Y26C2Z6X5Z2";
    std::vector<unsigned int> f_numb;

    for (auto it = f.begin(); it != f.end();)
    {
        if ('0' <= *it && *it <= '9')
        {
            unsigned int sm = 0;
            for (;it != f.end() && '0' <= *it && *it <= '9'; ++it)
                sm = (sm * 10) + (*it - '0');

            f_numb.emplace_back(sm);
        }
        else
        {
            ++it;
        }
    }

    for (auto x : f_numb)
        std::cout << x << ' ';
    std::cout << '\n';
}
    • 产出**
385 336 434 26 2 6 5 2

假设我理解了你的问题和你的代码,它们在表面目标上有很大的不同。

ct2axkht

ct2axkht2#

另一种更好地利用标准库函数的方法。https://onlinegdb.com/8eEgREuEN
我倾向于创建子步骤的函数,以便可以单独测试它们

#include <algorithm>
#include <iterator> // back_inserter
#include <string>
#include <vector>
#include <iostream>
#include <string_view>

// I like to make functions for substeps (they tend to be reusable)

std::vector<std::string> get_number_substrings(const std::string& input)
{
    static const std::string_view digits{ "0123456789" };
    std::vector<std::string> substrings;

    auto start_pos = input.find_first_of(digits, 0ul);
    auto end_pos = start_pos;
    auto max_length = input.length();

    while (start_pos < max_length)
    {
        end_pos = std::min(max_length, input.find_first_not_of(digits, start_pos));

        if (end_pos != start_pos)
        {
            substrings.emplace_back(&input[start_pos], end_pos - start_pos);
            start_pos = input.find_first_of(digits, end_pos);
        }
    }

    return substrings;
}

std::vector<int> get_numbers(const std::string& input)
{
    auto numbers = get_number_substrings(input);
    std::vector<int> output;

    // now transform the string to vector<int>
    // the back_inserter is needed because output doesn't have allocated memory yet
    // and that needs to be build up during the transform. 
    // https://en.cppreference.com/w/cpp/iterator/back_inserter
    // https://en.cppreference.com/w/cpp/algorithm/transform

    std::transform(numbers.begin(), numbers.end(), std::back_inserter(output), [](const std::string& string)
    {
        return std::stoi(string);
    });

    return output;
}

int main()
{
    std::string input{ "e385p336J434Y26C2Z6X5Z2" };

    auto output = get_numbers(input); // output will be a std::vector<int>

    // Use range based for loop
    // https://en.cppreference.com/w/cpp/language/range-for
    bool comma = false;
    for (const int value : output)
    {
        if (comma) std::cout << ", ";
        std::cout << value;
        comma = true;
    }

    return 0;
}
nx7onnlm

nx7onnlm3#

这对你有用吗?

std::string f = "e385p336J434Y26C2Z6X5Z2";
std::vector<int> f_numb; 
std::string sum; 

#define MAX_DIGITS 25
char aBuildNumber[MAX_DIGITS];
int aBuildCount=0;

std::vector<int> m_numb; 
for (int i = 0; i < f.size(); ++i)
{
    if (!isdigit(f[i]) || aBuildCount>=MAX_DIGITS-1) 
    {
        if (aBuildCount>0) m_numb.push_back(atoi(aBuildNumber)); 
        aBuildCount=0;
    }
    else {aBuildNumber[aBuildCount++]=f[i];aBuildNumber[aBuildCount]=0;}
}
if (aBuildCount>0) m_numb.push_back(atoi(aBuildNumber)); 

int sm=0; 
for (int i = 0; i < m_numb.size(); ++i)
{
    sm += m_numb[i]; 
    std::cout << m_numb[i] << " "; 
}
std::cout << std::endl;

相关问题