2012-02-02 94 views
0

我正在尝试解决this UVa problemC++“矢量迭代器不可递减”?

我试图用Vector来解决这个问题。我需要模拟像循环链表这样的东西,所以我使用迭代器来访问元素。但尝试之后,我发现Vector迭代器存在一些关于增量和减量的问题,并且我无法使用reverse_iterator作为参数来擦除该元素。我现在很困惑。我的代码有什么问题,因为我错过了一些重要的细节,或者我应该以另一种方式解决这个问题?

在此先感谢。

这里是我的代码

#include <iostream> 
#include <vector> 
#include <iomanip> 

using namespace std; 

vector<int> people; 

int main() 
{ 
    int n, k, m;   // k -> counter clockwise, m -> cloclwise 
    while (cin >> n >> k >> m) 
    { 
     if (n == 0 && k == 0 && m == 0) 
      return 0; 
     for (int i = 1; i <= n; i++) 
      people.push_back(i); 
     vector<int>::iterator k_pos = people.begin(); 
     vector<int>::reverse_iterator m_pos = people.rbegin(); 

     //cout << n << " " << k << " " << m << endl; 

     while (!people.empty()) 
     { 
      int k_choose, m_choose; 
      for (int i = 1; i < k; i++) 
      { 
       k_pos++; 
       if (k_pos == people.end()) // if reach the end, go to begin 
        k_pos = people.begin(); 
      } 

      k_choose = *k_pos; 
      cout << k_choose << endl; 

      for (int i = 1; i < m; i++) 
      { 
       m_pos++; 
       if (m_pos == people.rend()) 
        m_pos = people.rbegin(); 
      } 

      m_choose = *m_pos; 


      if (k_choose == m_choose) 
      { 
       cout << setw(3) << k_choose << ","; 
       people.erase(k_pos);     // erase the element 
      } 

      else 
      { 
       cout << setw(3) << k_choose << setw(3) << m_choose << ","; 
       k_pos = people.erase(k_pos);   // erase the element 
       //vector<int>::iterator temp; 
       //for (temp = people.begin(); *temp != *m_pos; temp++) 
       //{ 
       //} 
       //cout << "ok" << endl; 
       people.erase(--m_pos.base());*****problem 

      } 
      vector<int>::iterator temp; 
      for (temp = people.begin(); temp != people.end(); temp++) 
       cout << *temp << endl; 

      k_pos++;        *****problem 
      if (k_pos == people.end())   // point to next 
       k_pos = people.begin(); 

      m_pos++;        *****problem 
      if (m_pos == people.rend())   // point to next 
       m_pos = people.rbegin(); 
     } 
    } 
    return 0; 
} 

回答

2

擦除或载体推动所有的迭代器有可能成为无效的(如果向量被重新分配)之后。这就是为什么擦除之后在else中执行m_pos可能会失效。我的建议是使用索引(至少这是我为竞争性编程所做的)。

+0

“利用指数” 是指使用Vector的 “[]”? – iceman126 2012-02-02 19:04:40

+0

是的。无论重新分配矢量,该运算符将始终正常工作。 – 2012-02-02 19:14:23

+0

感谢您的回答。我会尝试的。 – iceman126 2012-02-02 19:20:14

0

如果m_pos等于people.rbegin()会怎么样? 因此--m_pos不是一个有效的迭代器,这可能是问题的根源。

也有可能,你删除之前在该行通过--m_pos指出的元素:

k_pos = people.erase(k_pos);   // erase the element 

,你可以在你的代码提高的另一件事是在一个更有效的方式设置k_posm_pos迭代器。相反:

for (int i = 1; i < k; i++) 
{ 
    k_pos++; 
    if (k_pos == people.end()) // if reach the end, go to begin 
    k_pos = people.begin(); 
} 

你可以写:

#include <iterator> 
std::advance(people.begin(), k % people.size());