在C++中,如何在列表中的每个连续零运行中删除除x之外的所有零?

b_r*_*on_ 3 c++ algorithm list erase-remove-idiom c++11

对于xC++列表中每次运行或连续的零,我想删除运行中的所有零,除了x它们.如果x = 0,则删除全部为零.

我在考虑一个C++函数,它将一个列表list<int> L和一个数字int x作为输入.

例如,让我们L = {7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8}.

  • 如果x = 0,那么回来L = {7, 12, 2, 27, 10, 8}
  • 如果x = 1,那么回来L = {7, 0, 12, 0, 2, 0, 27, 10, 0, 8}
  • 如果x = 2,那么回来L = {7, 0, 12, 0, 0, 2, 0, 0, 27, 10, 0, 0, 8}
  • 如果x = 3,那么回来L = {7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 8}
  • 如果x = 4,则返回L = {7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8}(与原始相同L)
  • 如果x >= 5,则返回原始,L因为没有5个或更多连续零的运行.

几个月前,我用Python(stackoverflow.com/questions/11732554/...)提出了同样的问题,并得到了很好的答案.现在我想用C++完成这个任务.

任何帮助将是真诚的感谢.

ema*_*tel 5

这里有一些应该完成这项工作的代码:

void DeleteAllZerosInARow(std::list<int>& theList, int x)
{
    if(x == 0)
    {
        theList.remove(0);
        return;
    }

    int streak = 0;
    std::list<int>::iterator itor = theList.begin();
    while(itor != theList.end())
    {
        if(*itor == 0)
            ++streak;
        else
            streak = 0;

        if(streak > x)
            itor = theList.erase(itor);
        else
            ++itor;
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,您可以计算连续多少个零,如果是> x,则删除它们,否则继续迭代列表.

给出以下输出:

  • 0: 7,12,2,27,10,8
  • 1: 7,0,12,0,2,0,27,10,0,8
  • 2: 7,0,12,0,0,2,0,0,27,10,0,0,8
  • 3: 7,0,12,0,0,2,0,0,0,27,10,0,0,0,8
  • 4: 7,0,12,0,0,2,0,0,0,27,10,0,0,0,0,8
  • 5: 7,0,12,0,0,2,0,0,0,27,10,0,0,0,0,8

这取决于你的风格,remove_if可能是更多的C++方式,但我发现直接操纵值更清楚,它不涉及新的数据类型(a struct跟踪0你遇到的数量).

之所以代码中使用不工作NTL::ZZ很简单,就是有一个之间不存在隐式转换int,0一个和NTL::ZZ大的数字,因此它不能remove(0).你能做什么虽然可能是这样的:

if(x == 0)
{
    static ZZ zero; // default value is 0, static so that it is only constructed once
    theList.remove(zero); // remove all items who are equal to "zero"
    return;
}
Run Code Online (Sandbox Code Playgroud)