【问题标题】:Best way to remove an element from a std::list nested inside a std::map从嵌套在 std::map 中的 std::list 中删除元素的最佳方法
【发布时间】:2020-07-08 09:16:13
【问题描述】:

正如标题所说,我想知道从满足特定条件(名称和日期)的地图内的列表中删除元素的最有效方法是什么。这是我提供的功能:

void Register::DeleteActivity(const Date &f,const std::string &a) {
    auto it = Registro.find(f);
    if(it != Registro.end()) {
        if(it->second.empty()) {
            std::cout <<"Error"<<std::endl;
        } else {
            for(auto ip = it->second.begin(); ip != it->second.end();) {
                if(ip->getName() == a && ip->getStartdate() == f){
                    ip->printInfo();
                
                    it->second.erase(ip);
                } else {
                    ip++;
                }
            }
        }
    } else {
        std::cout<< "DeleteActivity::day not found"<<std::endl;
    }
}

这是完整的课程:

class Register {
    private:
        map<Date,std::list<Activity>> Registro;
    public:
        Register(){};
        void addActivity(Date &z, Activity &n);
        void editActivity(const Date &a, const std::string &c, Date k, const std::string newname);
        void DeleteActivity(const Date &f, const std::string &a);

}

【问题讨论】:

    标签: c++ std stdmap stdlist


    【解决方案1】:

    有一个错误:您需要ip = it-&gt;second.erase(ip);
    erase 使迭代器无效,并将迭代器返回到下一个元素。

    但是你可以摆脱循环,让列表来完成工作:

    else {
        it->second.remove_if([&f, &a](const Activity& act) 
                                     { return act.getName() == a 
                                           && act.getStartdate() == f; });
    }
    

    【讨论】:

    • 是的,这解决了问题!
    【解决方案2】:

    您的代码存在分段错误,因为擦除使迭代器无效,但将迭代器返回到下一个元素。应该是:

    ip = it->second.erase(ip);
    

    前增量也比后增量更有效,因为不必存储原始值并复制迭代器:

    ++ip;
    

    否则,如果您没有重复项,我会使用 std::set 而不是 std::list,这也应该更高效(日志而不是线性)。

    #include <iostream>
    #include <map>
    #include <set>
    
    
    std::map<const int, std::set<int>> map_set({{0, {1, 2, 3, 4}},
                                                {1, {10, 20, 30, 40}},
                                                {2, {100, 200, 300, 400}},
                                                {3, {}}});
    
    
    void delete_from_map_set(const int map_index, int value) {
    
        const auto & map_it = map_set.find(map_index);
    
        if(map_it != map_set.end()) {
    
            map_it->second.erase(value);
        }
    }
    
    
    void print_map_set() {
        for(auto & map_it : map_set) {
            std::cout << map_it.first << ": [";
            for(auto & list_it : map_it.second) {
                std::cout << list_it << ", ";
            }
            std::cout << "]" << std::endl;
        }
    }
    
    
    int main(int argc, char * argv[]) {
    
        print_map_set();
    
        delete_from_map_set(0, 1);
    
        print_map_set();
    
        return 0;
    }
    
    

    【讨论】:

      猜你喜欢
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-16
      • 1970-01-01
      相关资源
      最近更新 更多