我需要创建某种公交路线手册(只是练习),所以我写了这个。
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
vector<string> GenWay(int length){
vector<string> res;
string stop;
for(int i = 0; i<length; i++){
cin >> stop;
res.push_back(stop);
}
return res;
}
int isVinMap(vector<string> vs, map<int,vector<string>> miv){
for(const auto& [key, vvalue]:miv){
if(vvalue == vs) return key;
}
return 0;
}
int main(){
int q=0;
cin >> q;
map<int,vector<string>> ways;
string stop="";
int command=0;
int next_way = 1; //last+1 //last = 0
for (int i = 0; i < q; i++){
cin >> command;
vector<string> new_way = GenWay(command);
int check = isVinMap(new_way,ways);
cout << check << !static_cast<bool>(check); //Debug code
if(!static_cast<bool>(check)){
cout << "New bus " << next_way << endl;
ways[next_way] = GenWay(command); //next_way is not controlled by user
next_way++;
} else{
cout << "Already exists for " << check << endl;
}
}
}
这是它应该做的:
首先输入的必须是即将到来的命令的数量。 (q)(例如 4
)(无输出)
first 之后只能处理一个命令,它有next 格式:number_of_bus_stops stop1 stop2 stop3...
(例如 2 m k
)。它向 map<int,vector<string>> ways
添加了一个条目,关于 marchrute(marchrute 的数量未由用户定义,并且是 next_way
,它应该在每个新条目后增加)。如果相同的 marchrute 出现在其他条目中,它告诉它已经存在并打印包含这种方式的 marchrute 的数量( isVinMap
方法检查并给出 marchrute 的数量)(不同停止顺序的方式不同),并通过说(例如 New bus 1
)告诉创建的新总线是否成功添加条目。
但是它并没有像预期的那样工作。输出几乎是不可预测的。我在 Winx64 系统上的 EclipseIDE 中工作并得到了这个输出:
>4
>2 m k
01New bus 1
>3 k r s
01New bus 2
20Already exists for 2
20Already exists for 2
在前两个命令之后,似乎循环又进行了两次,但它没有邀请我输入任何内容。
当然,欢迎对代码提出任何批评! 很抱歉代码中缺少文档和注释,我不认为我需要为此工作那么长时间。
最佳答案
将代码缩短到只包含相关部分:
for (int i = 0; i < q; i++)
{
cin >> command;
vector<string> new_way = GenWay(command);
if(!isVinMap(new_way, ways))
{
ways[next_way] = GenWay(command); // <-- (!)
// ...
在标记线处,您正在生成一个全新的 vector ,除了大小之外,它可能与之前创建的 vector (存储在 new_way
中)完全无关,而且可能更糟的是,它可能已经包含在 map 中(没有新的支票!)。
很可能,您打算插入之前已经阅读过的方式:
ways[next_way] = new_way;
I tried it and got some problems with debugger... I try step by step execution, but it just skips the cin input. [...]
好吧,那么您可以创建一些虚拟数据,例如。 G。通过使用随机数生成器:
char const* stopNames[] = {"a", "b", "c, /*... */ };
// (you'll need to find out how large it should be to produce sufficient different
std::mt19937 gen(std::random_device()());
std::uniform_int_distribution<> lengths(10, 12);
// (routes with length in between 10 and 12 - or whatever else appears appropriate
// to you)
std::uniform_int_distribution<> stops(0, sizeof(stopNames)/sizeof(*stopNames) - 1);
//cin >> command;
command = lengths(gen);
//cin >> stop
stop = stopNames[stops(gen)];
在其他情况下,您可能希望拥有完全静态的数据,例如。 G。只是有一个std::vector<std::vector<std::pair<std::string, std::string>>>
静态存储所有数据的位置。
嗯,std::pair<std::string, std::string>
???好吧,这样你就可以对这个答案所消除的方式进行第二次(错误的)阅读;这表明有时必须仔细选择测试数据......如果有疑问,您可能更喜欢范围检查(安全)访问器(std::vector::at
)而不是非检查访问器(operator[]
)来检索测试数据。
有时降低测试数据的复杂性也是合适的,例如。 G。在给定的情况下,您可以为所有路线使用恒定长度,可能会导致测试数据如
std::array<std::array<std::string, 12>, 10> routes({ ... });
生成 10 条路线,长度均为 12...
关于c++ - 初学者 C++ 练习的解决方案的意外输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58353074/