Как извлечь все числа из строки, где числа перемежаются буквами?

Как перебрать строку, состоящую из цифр и букв, и добавить в вектор только числа?

Например, если ввод:

e385p336J434Y26C2Z6X5Z2

Я хочу получить вектор int следующим образом:

число = {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; 
    
}

Просто в качестве примечания: Почему я не должен #include <bits/stdc++.h>?

Andreas Wenzel 19.02.2023 12:49

Ваш опубликованный код не работает? Если да, то каким образом? Пожалуйста отредактируйте этот вопрос, чтобы добавить эту информацию. Такие заявления, как «это не работает» , не являются достаточным описанием проблемы.

Andreas Wenzel 19.02.2023 12:50

Добавляйте цифры к строке так же, как вы это делаете сейчас. Но добавьте случай, когда вы получаете нецифровой символ, чтобы вставить строку в ваш вектор и сбросить строку.

Some programmer dude 19.02.2023 12:50

С другой стороны, int sm;, а затем sm += ...? Помните, что неинициализированные переменные на самом деле являются неинициализированными с неопределенным значением. Любое использование неопределенных значений приводит к неопределенному поведению.

Some programmer dude 19.02.2023 12:53
Руководство для начинающих по веб-разработке на React.js
Руководство для начинающих по веб-разработке на React.js
Веб-разработка - это захватывающая и постоянно меняющаяся область, которая постоянно развивается благодаря новым технологиям и тенденциям. Одним из...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
1
4
93
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Будет ли это работать для вас?

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; 
Ответ принят как подходящий

За исключением неустановленной причины, по которой вы не используете 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 

Это, если я понимаю ваш вопрос по сравнению с вашим кодом, которые сильно различаются по своим очевидным целям.

Большое спасибо! это именно то, что я хотел. isdigit я не использовал, так как просто не знал об этой функции :)

Swagga 19.02.2023 15:54

Еще один подход, в котором больше используются стандартные библиотечные функции. Живая демонстрация здесь: 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;
}

Другие вопросы по теме