1

我一直在努力学习 python 并以某种方式想出了以下代码:

for item in list:
    while list.count(item)!=1:
        list.remove(item)

我想知道这种编码是否可以在 C++ 中完成。(使用 for 循环的列表长度同时减小其大小)如果没有,谁能告诉我为什么?

谢谢!

4

6 回答 6

5

我不是一个大的 Python 程序员,但上面的代码似乎从列表中删除了重复项。这是一个 C++ 等价物:

list.sort();
list.unique();

至于在迭代列表时修改列表,您也可以这样做。这是一个例子:

for (auto it = list.begin(), eit = list.end(); it != eit; ) {
    if (std::count(it, eit, *it) > 1)
        it = list.erase(it);
    else
        ++it;
}

希望能帮助到你。

于 2013-01-16T20:15:17.537 回答
0

在 C++ 中,您可以从标准库的各种算法中组合出类似的东西,查看 remove()、find(),但是,您的算法的编写方式看起来像 O(n^2) 复杂度。对列表进行排序然后扫描它以将每个值之一放入一个新列表中具有 O(n log n) 复杂度,但会破坏顺序。

通常,对于 Python 和 C++,将元素复制或移动到临时容器然后与原始容器交换比就地修改原始容器更好。这更容易正确,因为您不会踩到自己的脚(请参阅 delnan 的评论),并且速度更快,因为它避免了重复的重新分配和复制对象。

于 2013-01-16T20:03:00.397 回答
0

这就是我的做法。

//If we will not delete an element of the list
for (std::list<MyType>::iterator it = MyList.begin(); it != MyList.end();++it)
{
   //my operation here
}

//If we will delete an element of the list
for (std::list<MyType>::iterator it = MyList.begin(); it != MyList.end();)
{
std::list<MyType>::iterator itt = it;
++itt;
MyList.erase(it);
it = itt;
}

您可以使用列表的大小,但它无法与 [it] 相提并论,因为 [it]。

std:: 数据类的某些特性作为设计决定启用或禁用。当然,您可以创建自己的函数 MyList[int i],但由于列表的性质,它会导致很大的速度 gimp。

于 2013-01-16T20:03:36.007 回答
0

在 C++ 中,您可以在某些情况下在迭代容器时从容器中删除元素。这取决于容器和您要执行的操作。

目前,在不同的答案中对您的代码片段有不同的解释。我的解释是,您要删除列表中多次存在的所有元素。

这是 C++ 中的解决方案:它首先计算另一个容器 (std::map) 中的元素,然后从列表中删除适当的元素。

#include <list>
#include <map>
#include <algorithm>
#include <iostream>

int main() {

  std::list<int> li { 0, 1, 2, 3, 4, 5, 1, 2, 3, 2, 2 };

  // Create count map: element -> count 
  std::map<int, int> cm;
  std::for_each( li.begin(), li.end(), [&cm](int i) { ++cm[i]; } );

  // Remove all elements from list with count > 1
  std::for_each( cm.begin(), cm.end(), 
         [&li](std::pair<const int, int> const p) { 
       if( p.second > 1) {
         li.remove( p.first );
       }
    } );

  // Output all elements from remaining list
  std::for_each( li.begin(), li.end(), 
         [](int i) { std::cout << i << std::endl; } );

  return 0;
}
于 2013-01-16T20:23:40.917 回答
0

我不知道 Python,但有人在评论中说列表等同于 C++ 向量并且它没有排序,所以这里......

std::vector<int> v{1, 2, 2, 2, 3, 3, 2, 2, 1};

v.erase(std::unique(v.begin(), v.end()), v.end());

v包含{1, 2, 3, 2, 1}在此代码之后。如果目标是删除所有重复项(不仅仅是连续重复项),则必须首先对向量进行排序:std::sort(v.begin(), v.end());

于 2013-01-16T20:34:36.687 回答
0

std::vector是 C++ 中与 Python 最相似的容器,这是list在迭代向量时修改向量的正确方法:

template <typename T>
void dedupe(std::vector<T> &vec) {
    for (std::vector<T>::iterator it = vec.begin(); it != vec.end(); ) {
        if (std::count(vev.begin(), vec.end(), *it) != 1) {
            it = vec.erase(it);
        } else {
            ++it;
        }
    }
}

这不一定是最有效的重复数据删除方法,但它确实有效。

为 for 循环使用列表长度,同时减小其大小

如果您坚持使用长度而不是end(),那么您可以使用索引而不是迭代器:

template <typename T>
void dedupe(std::vector<T> &vec) {
    for (std::vector<T>::size_type pos = 0; pos != vec.size(); ) {
        if (std::count(vec.begin(), vec.end(), vec[pos]) != 1) {
            vec.erase(vec.begin() + pos);
        } else {
            ++pos;
        }
    }
}

顺便说一句,我假设您的 Python 代码的目的是删除所有重复项,并且事实并非如此,这是一个错误。例如输入[2,2,1,3,3,1,2,3]、输出[1,1,2,3]。如果您所说的是您的意思,那么将您的代码直接翻译为 C++ 是:

template <typename T>
void dedupe(std::vector<T> &vec) {
    for (std::vector<T>::size_type pos = 0; pos < vec.size(); ++pos) {
        T item = vec[pos];
        while (std::count(vec.begin(), vec.end(), item) != 1) {
            vec.erase(std::find(vec.begin(), vec.end(), item));
        }
    }
}
于 2013-01-16T20:47:45.237 回答