gpt4 book ai didi

C++ remove_if 覆盖我的 vector

转载 作者:行者123 更新时间:2023-11-30 03:04:04 25 4
gpt4 key购买 nike

我的 remove_if 似乎正在用过滤掉的元素的值覆盖未过滤掉的元素。这些代码的目的是允许用户过滤和仅显示某个类别的教师。 (不删除任何元素)下面是部分代码

static string compare;
static string debug;

bool filter_Cat (Teacher &t)
{
return (t.getCat() != compare);
}

void filterCat (vector<Teacher> &t)
{
vector<Teacher>::iterator i;
vector<Teacher>::iterator newedited = remove_if(t.begin(), t.end(), filter_Cat);
for (i = t.begin(); i != newedited; ++i)
{
Teacher& te = *i;
te.getName();
cout << "\t";
te.getCategory();
cout << "\t";
te.getLocation();
}
}

void filterTutorCat(vector<Teacher> &t)
{
int choice;
cout << "No\tCategory" << endl
<< "1\tEnglish" << endl
<< "2\tMath" << endl
<< "3\tScience" << endl
<< "Choose the category you wish to filter :";
cin >> choice;
getline(cin, debug);

if(choice <= 3 && choice > 0)
{
if (choice == 1)
{
compare = "English";
filterCat(t);
}
if (choice == 2)
{
compare = "Math";
filterCat(t);
}
if (choice == 3)
{
compare = "Science";
filterCat(t);
}

}
else
{
cout << "Invalid Option" << endl;
}
}

最佳答案

remove_if 从右向左移动比较函数返回 false 的元素;换句话说,它用比较返回 false 的元素覆盖比较返回 true 的元素。但是, vector 的大小不会改变。

This reads ,

Removes all elements satisfying specific criteria from the range [first, last). The first version removes all elements that are equal to value, the second version removes all elements for which predicate p returns true.

Removing is done by shifting the elements in the range in such a way that elements to be erased are overwritten. The elements between the old and the new ends of the range have unspecified values. Iterator to the new end of the range is returned. Relative order of the elements that remain is preserved.

所以你想做的应该表达为:

void filterCat (vector<Teacher> &v)
{
for (vector<Teacher>::iterator it = v.begin(); it != v.end() ; ++it)
{
if (!filter_Cat(*i))
{
std::cout << i->getName() <<"\t" << i->getCategory() << std::endl;
}
}
}

在您的代码中,getName() 打印理想情况下不应执行的名称,而应返回名称。所以我建议您更改它以使其返回名称。对 getCategory 也做同样的事情。正确选择你的名字。如果它是 getName(),你应该通过返回它来得到你的名字;如果它是 printName(),那么它应该打印名字。


还有,你写的代码不好:

  • 您应该避免使用全局变量。
  • 您应该尽可能避免使用 if-else。学习更好的方法。
  • 您应该了解函数对象(或仿函数)
  • 您应该了解const 成员函数。
  • 您应该了解iteratorconst_iterator 之间的区别及其用法。
  • 您应该了解 const 引用和非 const 引用之间的区别。并尝试适本地使用它们。

所以我会把你的代码写成:

//this is functor, not a function
struct filter_cat
{
std::string m_cat; //use member data, avoid global variable
filter_cat(std::string const & cat) : m_cat(cat) {}
bool operator()(Teacher const & t) const //const member function
{
return (t.getCat() != m_cat); //getCat should be const member function
}
};

//pass vector by const reference
void filterCat (vector<Teacher> const & v, filter_cat filter)
{
//use const_iterator here, instead of iterator
for (vector<Teacher>::const_iterator it = v.begin(); it != v.end() ; ++it)
{
if (!filter(*i))
{
//getName and getCategory should be const member function
std::cout << i->getName() <<"\t" << i->getCategory() << std::endl;
}
}
}

void filterTutorCat(vector<Teacher> const &t)
{
int choice;
cout << "No\tCategory" << endl
<< "1\tEnglish" << endl
<< "2\tMath" << endl
<< "3\tScience" << endl
<< "Choose the category you wish to filter :";
cin >> choice;
getline(cin, debug);

//avoid if-else as much as possible, learn better ways!
std::string cats[] = {"English", "Math", "Science"};

if(choice <= 3 && choice > 0)
{
filterCat(v, filter_cat(cats[choice-1]));
}
else
{
cout << "Invalid Option" << endl;
}
}

如评论中所述:getCatgetNamegetCategory 应该是常量成员函数。事实上,如果 getCategory 返回类别,则甚至不需要 getCat

解决了我的问题。

关于C++ remove_if 覆盖我的 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8951032/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com