Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C++;,如何在列表中的每个连续零运行中删除除x以外的所有零? < >在C++中,每次运行 x>代码>或列表中的更多的连续零点,我想删除运行中的所有零点,除了它们的代码> x>代码>。如果x=0,则删除所有零 我考虑了一个C++函数,它列出了一个列表,代码>列表L>代码>,一个数字,代码< int x>代码>作为输入。_C++_Algorithm_List_C++11_Erase Remove Idiom - Fatal编程技术网

在C++;,如何在列表中的每个连续零运行中删除除x以外的所有零? < >在C++中,每次运行 x>代码>或列表中的更多的连续零点,我想删除运行中的所有零点,除了它们的代码> x>代码>。如果x=0,则删除所有零 我考虑了一个C++函数,它列出了一个列表,代码>列表L>代码>,一个数字,代码< int x>代码>作为输入。

在C++;,如何在列表中的每个连续零运行中删除除x以外的所有零? < >在C++中,每次运行 x>代码>或列表中的更多的连续零点,我想删除运行中的所有零点,除了它们的代码> x>代码>。如果x=0,则删除所有零 我考虑了一个C++函数,它列出了一个列表,代码>列表L>代码>,一个数字,代码< int x>代码>作为输入。,c++,algorithm,list,c++11,erase-remove-idiom,C++,Algorithm,List,C++11,Erase Remove Idiom,例如,让L={7,0,12,0,0,2,0,0,0,27,10,0,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,0,8} 如果x=4,则返回L={7,0,12,0,0,2,0,0,0,0,27,10,0,0,0,0,8}(

例如,让
L={7,0,12,0,0,2,0,0,0,27,10,0,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,0,8}
  • 如果
    x=4
    ,则返回
    L={7,0,12,0,0,2,0,0,0,0,27,10,0,0,0,0,8}
    (与原始
    L
  • 如果
    x>=5
    ,则返回原始
    L
    ,因为没有5个或更多连续零的运行
几个月前,我使用Python()问了上面同样的问题,并得到了很好的回答。现在我想在C++中完成这个任务。p>
任何帮助都将不胜感激。

对于案例0,您可以使用
std::remove
,对于案例1,您可以使用
std::unique
,并使用一个仅将其应用于
0
的谓词。对于更大的值,可以设计一个偷偷的有状态谓词来与
unique
一起使用,也可以借用它的逻辑来应用于更大的序列。

以下是一些应该完成这项工作的代码:

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;
    }
}

最简单的方法是返回一个
std::vector
并使用
push_back
,这样就不必担心分配正确大小的数组

template<typename Iter>
std::vector<int> filter_zeroes(Iter start, Iter end, const size_t num_zeroes)
{
    std::vector<int> output;
    size_t zero_count = 0;
    while (start != end)
    {
        if (*start != 0)
        {
            output.push_back(*start);
            zero_count = 0;
        }
        else if (zero_count < num_zeroes)
        {
            output.push_back(*start);
            ++zero_count;
        }
        ++start;
    }
}
模板
标准::矢量滤波器零点(Iter开始、Iter结束、常数大小数值零点)
{
std::矢量输出;
大小\u t零\u计数=0;
while(开始!=结束)
{
如果(*开始!=0)
{
输出。推回(*启动);
零计数=0;
}
else if(零计数

您可以使此方法更加通用。将
int
更改为
typename-ValueType
并将
0
更改为
ValueType-value\u-to\u-remove
,您将进入
std::algorithm
通用性级别…

如果需要,您可以传递一个functor-to-list::remove\u。下面的例子

#include <iostream>
#include <list>

std::list<int> origL{7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8};

template <typename T>
struct remove_more_than_n_consecutive_zeros
{
    int n;
    int i;
    F(int n) : n(n), i(0) { }

    bool operator()(const T &element) {
        if (0 == element) {
            ++i;
            return i > n;
        }
        else 
        {
            i = 0;
            return false;
        }
    }
};

int main()
{
    for (int i = 0; i < 5; ++i) {
        std::list<int> L = origL;
        L.remove_if(remove_more_than_n_consecutive_zeros<int>(i));
        for (int x : L) { std::cout << x << " "; }
        std::cout << std::endl;
    }
}
#包括
#包括
std::list origL{7,0,12,0,0,0,2,0,0,0,0,27,10,0,0,0,0,0,8};
模板
结构删除多于连续零的
{
int n;
int i;
F(int n):n(n),i(0){
布尔运算符()(常量T和元素){
if(0==元素){
++一,;
返回i>n;
}
其他的
{
i=0;
返回false;
}
}
};
int main()
{
对于(int i=0;i<5;++i){
std::list L=origL;
L.删除如果(删除多于连续零(i));

对于(intx:L){std::cout来说,它本质上是一个状态机,因此您可以使用std::regex做一些聪明的事情,但这里有一个简单的实现

void TrimConsecutiveValues(int value, int cKeep, std::list<int> &list) {
  int cSeen = 0;
  auto it = list.begin();
  while (it != list.end()) {
    if (*it == value) {
      if (cSeen < cKeep) {
        ++cSeen;
        ++it;
      } else {
        it = list.erase(it);
      }
    } else {
      cSeen = 0;
      ++it;
    }
  }
}
void trimposecutivevalues(int-value、int-cKeep、std::list&list){
int-cSeen=0;
auto it=list.begin();
while(it!=list.end()){
如果(*it==值){
如果(cSeen
这是一个C++11版本(使用
auto
、lambdas和move语义),它使用
std::vector
来表示
T
类型的任意
值:

#include <algorithm>
#include <cstddef>
#include <iostream>
#include <iterator>
#include <vector>

template<std::size_t N, typename T>
std::vector<T> collapse_consecutive(std::vector<T> v, T const& value)
{
    if (v.size() <= N) return v;

    for (auto it = v.begin(); it != std::prev(v.end(), N); ++it) {
        if (*it == value) {
            // find first following mismatch
            auto jt = std::find_if(it, v.end(), [&](T const& elem) {               
               return elem != value;
            });
            // keep first N matches, remove rest of matches
            if (std::distance(std::next(it, N), jt) > 0)               
                v.erase(std::remove(std::next(it, N), jt, value), jt);
        }
    }
    std::for_each(v.begin(), v.end(), [](int const& elem) { std::cout << elem << ", "; });
    std::cout << "\n";
    return v;
}

int main()
{
   std::vector<int> v = {7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8};

  collapse_consecutive<0>(v, 0);
  collapse_consecutive<1>(v, 0);
  collapse_consecutive<2>(v, 0);
  collapse_consecutive<3>(v, 0);
  collapse_consecutive<4>(v, 0);
  collapse_consecutive<5>(v, 0);  
}

使用与Python相同的算法。C++是否具有与代码>收益率< /代码>的等价函数?你可以将它推回到结果列表而不是屈服。我不认为<代码> ReleVig如果实际上保证了它测试元素的顺序,那么我更愿意自己滚动,以防它不:- @ eMARTEL,虽然我不嘘。在上面的例子中,我的列表实际上包含大整数,所以我在NTL C++库中使用<代码> ZZ < /Cuff>类。当尝试用<代码>列表>代码> > <代码> >代码>时,编译时错误被抛出:<代码>没有调用StD的匹配函数::列表::删除(int)
。有什么方法可以将上面的代码改编成
ZZ
列表吗?@b_ron_u。我添加了一些解释,如果有帮助请告诉我!@emartel,非常感谢。你的解释非常有用,正是我编译代码所需要的。
list::erase
返回一个迭代器和
it=list.erase(它)
看起来好多了
旧的
是从哪里来的?是我根据Csq的评论错误编辑的原始版本。再次修复。
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <iterator>
#include <vector>

template<std::size_t N, typename T>
std::vector<T> collapse_consecutive(std::vector<T> v, T const& value)
{
    if (v.size() <= N) return v;

    for (auto it = v.begin(); it != std::prev(v.end(), N); ++it) {
        if (*it == value) {
            // find first following mismatch
            auto jt = std::find_if(it, v.end(), [&](T const& elem) {               
               return elem != value;
            });
            // keep first N matches, remove rest of matches
            if (std::distance(std::next(it, N), jt) > 0)               
                v.erase(std::remove(std::next(it, N), jt, value), jt);
        }
    }
    std::for_each(v.begin(), v.end(), [](int const& elem) { std::cout << elem << ", "; });
    std::cout << "\n";
    return v;
}

int main()
{
   std::vector<int> v = {7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8};

  collapse_consecutive<0>(v, 0);
  collapse_consecutive<1>(v, 0);
  collapse_consecutive<2>(v, 0);
  collapse_consecutive<3>(v, 0);
  collapse_consecutive<4>(v, 0);
  collapse_consecutive<5>(v, 0);  
}
stdout: 
7, 12, 2, 27, 10, 8, 
7, 0, 12, 0, 2, 0, 27, 10, 0, 8, 
7, 0, 12, 0, 0, 2, 0, 0, 27, 10, 0, 0, 8, 
7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 8, 
7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8, 
7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8,