Как сделать 2d вектор из входной строки?

У меня возникла эта проблема в одном из вопросов по кодированию на экзамене в университете, где я знал ответ, но не мог понять, так как не знал, как разобрать строку и преобразовать ее в 2d-вектор. Итак, у меня есть 2d-вектор в виде строки

"[[1,4], [5,7], [4,1], [8,9]]"

Я хочу преобразовать эту строку в vector<vector<int>>

РЕДАКТИРОВАТЬ

Может быть, я не ясно выразился в прошлый раз, и есть одна вещь, которую я пропустил. Строка

"[[1,4], [5,7], [4,1], [8,9]]"

Я хочу, чтобы эта строка была в виде двумерного вектора. Итак, допустим, у меня есть вектор vec, определенный как vector<vector<int>> vec. Тогда vec[0] = {1,4}, vec[1] = {5,7}, vec[2] = {4,1}, vec[3] = {8,9}. Ниже то, что я сделал, и он показывает неправильный вывод

#include<iostream>
#include<sstream>
#include<vector>
using namespace std;

int main()
{
    string str = "[[1,4], [5,7], [4,1], [8,9]]";
    stringstream ss(str);
    vector<vector<int>> vec;
    string temp;
    while(ss>>temp){
        cout<<temp<<endl;
        vector<int> t;
        int x,y;
        stringstream ss2(temp);
        while(ss2>>x>>y)
        {
            t.push_back(x);
            t.push_back(y);

        }
        vec.push_back(t);
    }
}

Пожалуйста, предоставьте пример end-2-end, т.е. эта строка должна стать этим объектом. Есть много способов перейти от вашего примера к строке векторов. Затем предоставьте то, что вы пробовали до сих пор, но это не сработало.

Mansoor 19.12.2020 14:29

, и , это два разных разделителя? Этот формат фиксированный? В этом случае вы можете сначала удалить первые два символа и два последних символа, разделить на ], [, а затем разделить на ,.

Thomas Sablik 19.12.2020 14:31

на самом деле это вариант этого вопроса: stackoverflow.com/questions/1120140/…. Решение требует лишь небольших доработок

463035818_is_not_a_number 19.12.2020 14:59

Отвечает ли это на ваш вопрос? stackoverflow.com/questions/1120140/…

463035818_is_not_a_number 19.12.2020 14:59

Общий совет для таких вещей: 1. Старайтесь писать общие функции, которые вы сможете использовать позже. Как, например, функция, которая может разграничить заданную строку, то есть строка -> вектор строки. 2. Рассмотрим создание конечного автомата. Имейте перечисление для фаз, а затем большой цикл с переключением на текущую фазу. С помощью этой техники вы можете многое. 3. Если вы спрашиваете на SO, проявите некоторое усилие с вашей стороны. Если вам нужно какое-то начало, учтите, что вы можете перебирать символы строки, как через массив.

Aziuth 19.12.2020 15:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
282
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

#include <iostream>
#include <vector>
using namespace std;

template <typename Range>
void print_range(const Range& r)
{
    for (const auto& e : r)
        cout << e << " ";
    cout << endl;
}

int main()
{
    vector<int> v;
    vector<vector<int>> vv;

    char c;
    int cnt = 0;

    while (cin >> c)
    {
        if (c == ',' || c == ' ' || c == '\n')
        {
            continue;
        }

        if (c == '[')
        {
            ++cnt;
            v.clear();
            continue;
        }

        if (c == ']')
        {
            --cnt;
            if (cnt == 0)
                break;

            vv.push_back(v);
            v.clear();
            continue;
        }

        cin.unget();

        int x;
        if (cin >> x)
            v.push_back(x);
    }

    for (const auto& vec : vv)
        print_range(vec);
}
meta.stackoverflow.com/questions/334822/…
Thomas Sablik 19.12.2020 14:59

@ThomasSablik Из вашей ссылки: «Не минусуйте тех, кто добросовестно отвечает на вопросы о домашнем задании, даже если они нарушают эти правила (если только ответ не заслуживает отрицательных голосов, даже если вопрос не был связан с домашним заданием)».

Sneftel 19.12.2020 15:45
Ответ принят как подходящий

Вот быстрая реализация Godbolt:

Примечание. Этот ответ не обрабатывает случаи, когда целые числа имеют более одной цифры. Он не является общим или легко расширяемым, но, поскольку это вопрос домашнего задания, вы можете понять и улучшить код.

#include <string>
#include <vector>
#include <istream>
#include <sstream>
#include <cctype>
#include <iostream>
#include <iterator>

int main()
{
    std::string input{"[[1,4], [5,7], [4,1], [8,9]]"};

    std::stringstream ss{input};
    auto it = std::istream_iterator<char>{ss};

    std::vector<std::vector<int>> output;
    std::vector<int> inner;

    // Loop through the string, one character at a time
    while (it != std::istream_iterator<char>{})
    {
        ++it;
        
        // If we encounter a digit, push it into the inner vector
        if (std::isdigit(*it))
        {
            // Dirty hack to convert char to integer (assumes ASCII)
            inner.push_back(*it - 48);
        }

        // If you encounter a ']' char, then push inner vector into the outer vector
        // and then clear the inner vector

        // For the final ']', the inner vector will be size 0, ignore this case
        if (*it == ']')
        {
            if (inner.size() != 0)
            {
                output.push_back(inner);
            }
            inner.clear();
        }
    }
}
meta.stackoverflow.com/questions/334822/…
Thomas Sablik 19.12.2020 14:59

@ThomasSablik Какой аспект этого ответа, по вашему мнению, нуждается в улучшении?

Mansoor 19.12.2020 15:10

Удалите код. Это вопрос домашнего задания. Вы можете помочь решить проблему, но не должны предлагать полное решение.

Thomas Sablik 19.12.2020 15:25

Эй, спасибо, это то, что я хотел. Можете ли вы указать на ошибку, которую я сделал в своем коде?

Levi 19.12.2020 17:47

@Levi Конечно, ваш код предполагает, что все, что читается, является int, но вам также нужно анализировать открывающие/закрывающие квадратные скобки и запятые. Моя реализация обходит это, читая строку как серию символов и проверяя, являются ли они цифрами. Таким образом, он будет обрабатывать разделители , и закрывающие скобки ].

Mansoor 21.12.2020 11:27

Общий ответ - написать парсер рекурсивного спуска (поищите его). Это причудливый способ сказать, что вы пишете функцию для каждого из нетерминалов (vector2, vector, int), тогда вы обычно смотрите только на первый байт, чтобы понять, что делать. В этом случае ваша грамматика может быть:

vector2 = "[" vector (, " " vector) "]"
vector = "[" int (, number) "]"
number = 0 | 1 [0-9]

Затем вы реализуете число, вектор и вектор_вектор аналогично тому, как @StPiere показал вам ранее.

Я обычно использую c, и я нашел эту универсальную сигнатуру функции полезной для начала:

char *parse_something(const char *s, something *v)

где s — это строка, которую вы анализируете, а возвращаемое значение — это то, что вы хотите проанализировать следующим образом.

не используйте выше/ниже для ссылки на другие ответы. Это зависит от сортировки каждого пользователя. Я не вижу ответа выше твоего

463035818_is_not_a_number 19.12.2020 15:22

Хорошая точка зрения. Вместо этого использовал временную ссылку, чтобы указать, что подробный ответ был опубликован к тому времени, когда я отправил свой ответ.

Allan Wind 19.12.2020 15:42

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