从对列表中删除一对 C++

问题描述 投票:0回答:2

我都是在课堂上做这一切的。我有一份私人配对名单:

std::list<std::pair<std::string, size_t>> pokemons_;

我已向其传递某些值:

{("Pikachu", 25),
    ("Raticate", 20),
    ("Raticate", 20),
    ("Bulbasaur", 1),
    ("Pikachu", 25),
    ("Diglett", 50)};

现在我想通过调用我的类的公共删除函数来删除一对。

bool PokemonCollection::Remove(const std::string& name, size_t id) {};

我不明白如何在调用删除函数时比较字符串和id值:

collection.remove("Raticate", 20);

“集合是我的类的一个对象”

我已经实现了:

bool PokemonCollection::Remove(const std::string& name, size_t id) {
    bool found;
    string x;
    size_t  y;

    for (auto currentPair : pokemons_) {

        pair<string, size_t> currentpair = currentPair;
        x = currentpair.first;
        y = currentpair.second;

        pokemons_.erase(pokemons_.begin() + i)

        for (int i=0; i<pokemons_.size(); i++) {
             if (pokemons_[i].first == x && pokemons_[i].second == y) {
                 //pokemons_.erase(pokemons_.begin() + i);
                 cout<<"FOUND!!!!!!!!!!!!!!!";
                 found = true;
                 return true;
            }
            else {
                found = false;
            }
        }
    }
    return found;
}

但是我的这个删除功能给出了一些我不太理解的错误。

它还在我使用 erase 函数的注释行上给出了很多错误。如何比较字符串和 id 并将该对从我班级的原始私有列表中删除?

我的职能

bool PokemonCollection::Remove(const std::string& name, size_t id) {

    bool found;
    //string x;
    //size_t y;

    pokemons_.remove_if([&](std::pair<std::string, size_t>& p) {
        return found = true and p.first==name and p.second==id;
    });

    if(found == true) {
        return true;
    }
    else {
        found = false;
    }
    return found;
}
c++ list vector
2个回答
2
投票

有一个非常简单的解决方案可以解决您的问题。

std::list
有一个功能
remove_if
,它会为你做一切。请参阅此处

请参阅以下代码作为示例:

#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <list>

std::list<std::pair<std::string, size_t>> poke
        {{"Pikachu", 25}, 
        {"Raticate", 20}, 
        {"Raticate", 20}, 
        {"Bulbasaur", 1}, 
        {"Pikachu", 25}, 
        {"Diglett", 50}};

void remove(const std::string& s, size_t i) {
    
    poke.remove_if([&](std::pair<std::string, size_t>& p){return p.first== s and p.second==i;});
}

int main() {
    remove("Raticate", 20);

    for (const auto& [s,i] : poke) 
        std::cout << s << '\t' << i <<'\n';
}

更多信息:

正如您可以在

remove_if
std::list
文档中阅读的那样,它需要按以下方式调用:

void remove_if( UnaryPredicate p );

您的问题可能是“UnaryPredicate”。我们可以读:

一元谓词,如果应删除元素则返回true。

并且,我们可以进一步阅读:

对于 T 类型(可能是 const)的每个参数 v,表达式 p(v) 必须可转换为 bool,无论值类别如何,并且不得修改 v。因此,不允许使用 T& 的参数类型,T 也不允许,除非T 移动相当于复制 (C++11 起)。

但这对你也没有多大帮助。基本上,谓词是一个极其简单的函数(对象)。

因此,

remove_if
将迭代
std::list
中的所有元素,并将其称为“函数”。如果这个“函数”返回
true
,那么关联的
list
元素将被删除。

C++ 标准定义 Predicate 如下(25/7):

每当算法需要一个函数对象时,就会使用 Predicate 参数,该函数对象在应用于解引用相应迭代器的结果时返回一个可测试为 true 的值。换句话说,如果一个算法将谓词 pred 作为其参数,将 first 作为其迭代器参数,则它应该在构造 if (pred(*first)){...} 中正常工作。函数对象 pred 不应通过解引用迭代器应用任何非常量函数。该函数对象可以是指向函数的指针,也可以是具有适当函数调用运算符的类型的对象。

对于上述情况,我使用了 lambda 表达式 作为函数对象。这种机制在C++中被广泛使用。请阅读相关内容。


不幸的是

remove_if
不会返回任何值。这里确实有多种方法可以构建解决方案。

让我向您展示一种解决方案,仍然使用 lambda。

#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <list>

std::list<std::pair<std::string, size_t>> poke
{ {"Pikachu", 25},
{"Raticate", 20},
{"Raticate", 20},
{"Bulbasaur", 1},
{"Pikachu", 25},
{"Diglett", 50} };

bool remove(const std::string& s, size_t i) {

    bool found = false;
    poke.remove_if([&](std::pair<std::string, size_t>& p) {bool rv = (p.first == s and p.second == i); if (rv) found = true; return rv; });
    return found;
}

int main() {
    if (remove("Raticate", 20))
        std::cout << "\nFound\n\n";
    else
        std::cout << "\nNot Found\n\n";

    for (const auto& [s, i] : poke)
        std::cout << s << '\t' << i << '\n';
}

0
投票

它可以比A M的解决方案更简单。

std::pair<>
带有比较运算符,因此您不需要自定义函数来检查列表中的元素是否等于给定的对:

void remove(const std::string& s, size_t i) {
    poke.remove({s, i});
}

自 C++20 起,

std::list
remove()
remove_if()
返回删除的元素数量的计数。如果需要兼容早期版本,可以随时在调用
poke.size()
之前和之后检查
remove()
的结果,看看列表的大小是否发生了变化。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.