在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
,因为没有5个或更多连续零的运行L
任何帮助都将不胜感激。对于案例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,