我用C ++编写了一个程序来帮助我学习GMAT。我用它以随机顺序练习最多25个时间表。它的工作原理是生成一个随机数,并要求用户将该数字乘以他们想要处理的时间表。程序将该数字添加到一个集合中,以便不重复。请找到以下代码:
int randumb(int a){
random_device rd;
mt19937 gen(rd());
uniform_real_distribution <> dis(1,a+1);
int u=dis(gen);
return u;
}
void mult_tables(){
cout<<"Which times table would you like to practice?"<<endl;
int a, input;
set<int> vect;
cin>>a;
int mult;
for(int i=0; i<a; ++i){
mult=randumb(a);
if(i==0)
vect.insert(mult);
if(i!=0){
for(set<int>::iterator it=vect.begin(); it!=vect.end(); ++it){
if(mult==*it){
mult=randumb(a);
it=vect.begin();
}
}
vect.insert(mult);
}
cout<<endl;
cout<<a<<" x "<<mult<<" = ";
cin>>input;
if(input==a*mult)
cout<<"Correct!"<<endl;
else
cout<<"Wrong."<<endl;
}
}
如您所见,代码将每个乘数与集合中已有的元素进行比较。如果一个数字已经在集合中,它将生成新的数字并将迭代器返回到集合的开头,以便它可以将新的乘数与所有先前使用的数字进行比较。我在GDB中逐步完成了程序,每次命中it=vect.begin();
时它都会将迭代器返回到集合中的SECOND元素。它每次都会发生并导致数字重复。有谁知道为什么会这样?
答案 0 :(得分:5)
逻辑错误是你在循环中调用vect.begin()
后递增迭代器。
您需要的是:
for(set<int>::iterator it=vect.begin(); it!=vect.end(); /** ++it **/){
if(mult==*it){
mult=randumb(a);
// Reset the iterator to the start.
// Don't increment it.
it=vect.begin();
}
else {
// Increment the iterator.
++it;
}
}
答案 1 :(得分:0)
不是修复你的实现,而是更简洁的方法来做同样的事情。
集合容器确保其中的每个值都是唯一的,因此,只要集合的大小小于所需数量,就可以更容易地添加数字,而不是检查数字是否已存在。
以下是代码段:
std::set<int> nums;
while(nums.size() < REQUIRED_SIZE)
{
nums.insert(randumb(a));
}
此时您有一组唯一的数字,可以根据需要使用它。