C++ 如何从输入字符串生成二维向量?

C++ 如何从输入字符串生成二维向量?,c++,string,vector,C++,String,Vector,我在大学考试中的一个编码问题中遇到了这个问题,我知道答案,但无法理解,因为我不知道如何解析字符串并将其转换为二维向量。 我得到了一个字符串形式的二维向量 "[[1,4], [5,7], [4,1], [8,9]]" 我想将此字符串转换为向量 编辑 也许上次我不清楚,我错过了一件事。字符串是 "[[1,4], [5,7], [4,1], [8,9]]" 我希望这个字符串是2d向量的形式。假设我有一个向量vec,定义为vector-vec。然后vec[0]

我在大学考试中的一个编码问题中遇到了这个问题,我知道答案,但无法理解,因为我不知道如何解析字符串并将其转换为二维向量。 我得到了一个字符串形式的二维向量

"[[1,4], [5,7], [4,1], [8,9]]"
我想将此字符串转换为
向量

编辑

也许上次我不清楚,我错过了一件事。字符串是

"[[1,4], [5,7], [4,1], [8,9]]"
我希望这个字符串是2d向量的形式。假设我有一个向量
vec
,定义为
vector-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);
    }
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
字符串str=“[1,4],[5,7],[4,1],[8,9]”;
stringstream ss(str);
向量向量机;
字符串温度;
而(ss>>温度){
库蒂)
{
t、 推回(x);
t、 向后推(y);
}
向量推回(t);
}
}
#包括
#包括
使用名称空间std;
模板
无效打印范围(常数范围和r)
{
用于(常数自动和e:r)
cout>x)
v、 推回(x);
}
用于(常数自动和矢量:vv)
打印范围(vec);
}

以下是快速实现:

注:此答案不适用于整数多于一位的情况。它不是通用的,也不容易扩展,但由于这是一个家庭作业问题,您可以理解并改进代码

#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();
        }
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
字符串输入{“[[1,4],[5,7],[4,1],[8,9]]”;
std::stringstream ss{input};
auto it=std::istream_迭代器{ss};
std::矢量输出;
std::向量内部;
//循环遍历字符串,每次一个字符
while(it!=std::istream_迭代器{})
{
++它;
//如果我们遇到一个数字,把它推入内向量
if(标准::isdigit(*it))
{
//将字符转换为整数(假定为ASCII)的恶意破解
内部。向后推_(*it-48);
}
//如果遇到']'字符,则将内部向量推入外部向量
//然后清除内部向量
//对于最后一个']',内部向量的大小为0,忽略此情况
如果(*it=']')
{
如果(内部.size()!=0)
{
输出。推回(内部);
}
内部。清除();
}
}
}

一般的答案是编写递归下降解析器(查找)。这是一种奇特的说法,你为每一个非终端(vector2,vector,int)写一个函数,然后你通常只看第一个字节就知道要做什么。在这种情况下,您的语法可能是:

vector2 = "[" vector (, " " vector) "]"
vector = "[" int (, number) "]"
number = 0 | 1 [0-9]
然后实现数字、向量和向量_向量,类似于@StPiere之前显示的方式

我通常使用c,我发现这个通用函数签名是一个有用的开始:

char*parse_某物(常量char*s,某物*v)


其中s是您要分析的字符串,返回值是您下一步要分析的内容。

请提供一个end-2-end示例,即此字符串应成为此对象。有很多方法可以从您的示例字符串中得到向量向量。然后提供到目前为止您尝试过但不起作用的内容。
是两个不同的分隔符吗?这个格式是固定的吗?在这种情况下,您可以先删除前两个字符和最后两个字符,然后按
]拆分,[
,然后被
拆分。这实际上是这个问题的一个变体:。解决方案只需要很小的调整就可以回答您的问题吗?一般建议:1.尝试编写通用的函数,以后可以重复使用。例如,可以对给定字符串进行定界的函数,即字符串->向量考虑字符串。2。考虑有一个状态机,有一个枚举的阶段,然后一个大循环与当前阶段的切换。用这种技术,你可以做很多。3。如果你这样问,展示你的一方的努力。如果你需要任何一种开始,考虑你可以重复通过一个字符串的字符像一个数组。@ThomasSablik你认为这个答案的哪一方面需要改进?删除代码。这是一个家庭作业问题。你可以帮助解决问题,但不应该提供完整的解决方案。嘿,谢谢,这就是我想要的。你能指出我在代码中犯的错误吗?@Levi当然,你的代码假设读取的所有内容都是错误的n
int
,但您还必须解析开/闭括号和逗号字符。我的实现通过将字符串作为一系列字符读入并检查它们是否为数字来解决这一问题。因此,它将处理来自链接的分隔符
和闭括号
]
@ThomasSablik:“不要对善意回答家庭作业问题的其他人投反对票,即使他们违反了这些准则(除非该答案值得投反对票,即使该问题与家庭作业无关)。”不要使用“上/下”来引用其他答案。这取决于每个用户的排序。我看不到任何答案高于您的正确点。使用临时引用来表示在我提交答案时已发布了详细答案。
vector2 = "[" vector (, " " vector) "]"
vector = "[" int (, number) "]"
number = 0 | 1 [0-9]