2016-11-10 81 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; 
    } 
}