2016-11-10 83 views
1

出於某種原因,在此功能中重要的地方的兩個或兩個以上相同的值的「塊體」:迭代器操作不工作

#include <iostream> 
#include <iterator> 
#include <set> 

int countClumps(multiset<int> set) 
{ 
    int clumps = 0; 

    for (multiset<int>::const_iterator iter(set.begin()), end(set.end()); iter != end; ++iter) 
    { 
     if (iter == iter[1] && iter != iter[-1]) 
     { 
      clumps += 1; 
     } 
    } 
    return clumps; 
} 

我得到的錯誤「不操作‘[]’相匹配,這些操作數」 。爲什麼會發生?我認爲像iter [i]和*(iter + i)這樣的東西是標準操作?我確實嘗試*(iter + 1),但是這給了我相同的操作數錯誤,但是+。有沒有我忘記包含的東西?

回答

1

std::multiset有一個雙向迭代器。這個迭代器不能使用operator []operator +。使用標準功能std::nextstd::prev而是獲得一個或下一個迭代器..

你也應該比較值的迭代器,而不是自己的迭代器指向。

考慮到如果參數聲明爲引用會更好。

功能可以看看下面的方式

#include <iostream> 
#include <set> 

size_t countClumps(std::multiset<int> &set) 
{ 
    size_t clumps = 0; 

    for (auto first = set.begin(), last = set.end(); first != last;) 
    { 
     auto value = *first; 
     size_t i = 0; 

     while (++first != last && *first == value) ++i; 

     if (i) ++clumps; 
    } 

    return clumps; 
} 

int main() 
{ 
    std::multiset<int> set { 1, 1, 2, 3, 3, 3, 5, 5 }; 

    std::cout << countClumps(set) << std::endl; 

    return 0; 
} 

程序輸出是

3 
+0

這有助於噸,謝謝!事實上,在比較數值之後,我嘗試過比較方向,因爲那只是我走錯了方向。 – BaloneyOs

+0

@BaloneyOs另請參閱我的答案中的示範程序。:) –

4

我得到的錯誤 「不操作 '[]' 匹配這些操作數」。爲什麼會發生?

這是因爲multiset<int>::const_iterator不支持operator[]

我以爲像iter[i]*(iter + i)是標準操作?

你以爲是錯的。

我也嘗試*(iter + 1)但給了我同樣操作數錯誤但+。有沒有我忘記包含的東西?

operator+是不是一個multiset<int>::const_iteratorint之間支承。因此,iter + 1不是一個有效的表達式。

你還沒有忘記包含任何東西。您正在嘗試在對象類型上不受支持的操作。您將不得不重新考慮您的代碼。


下面的實現應該可以工作。

int countClumps(multiset<int> set) 
{ 
    int clumps = 0; 
    int previousNumber = 0; 

    multiset<int>::const_iterator iter(set.begin()); 
    multiset<int>::const_iterator end(set.end()); 

    // Account for empty input. 
    if (iter != end) 
    { 
     previousNumber = *iter; 

     for (++iter; iter != end;) 
     { 
     if (previousNumber == *iter) 
     { 
      ++clumps; 

      // Skip the rest of the clump 
      for (++iter; iter != end && previousNumber == *iter ; ++iter); 
     } 
     else 
     { 
      ++iter; 
     } 

     if (iter != end) 
     { 
      previousNumber = *iter; 
     } 

     } 
    } 
    return clumps; 
} 
0

的問題是,一個std::multiset<>::const_iteratorbidirectional_iterator,不支持的引用操作,不像random_access_iterator

你可以做這樣的事情:

if (set.length() > 2) 
    for (multiset<int>::const_iterator iter(std::next(set.begin())), end(std::prev(set.end())); iter != end; ++iter) 
    { 
     if (*iter == *std::next(iter) && *iter != *std::prev(iter)) 
     { 
      clumps += 1; 
     } 
    } 

但是你的算法仍然是錯的......我會做(未測試):

bool first_time = true; 
bool in_clump = false; 
int prev_val; 
for (auto element: set) 
{ 
    if (first_time) 
    { 
     prev = element; 
     first_time = false; 
    } 
    else if (element == prev) 
    { 
     if (!in_clump) 
     { 
      ++clumps; 
      in_clump = true; 
     } 
    } 
    else 
    { 
     in_clump = false; 
    } 
}