为什么迭代器不返回集合的开头

Why does the iterator not return to the beginning of the set?

本文关键字:开头 集合 返回 迭代器 为什么      更新时间:2023-10-16

我在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();时,它都会返回迭代器到集合中的第二个元素。它每次都会发生,并导致数字重复。有人知道为什么会发生这种情况吗?

逻辑错误是您在循环中调用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;
    }
  }

不是实现的修复,而是一种更清洁的做同样事情的方法。

设置容器可确保内部的每个值都是唯一的,因此,只要集合的大小小于所需的大小,就不必检查数字是否已经存在。

这是一个代码段:

std::set<int> nums;
while(nums.size() < REQUIRED_SIZE)
{
    nums.insert(randumb(a));
}

此时,您有一组唯一的数字,请按照您的意愿使用它。