Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.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++ 循环挂起,用于在std::list上执行迭代std::erase_C++_Hash_Stl_Iterator - Fatal编程技术网

C++ 循环挂起,用于在std::list上执行迭代std::erase

C++ 循环挂起,用于在std::list上执行迭代std::erase,c++,hash,stl,iterator,C++,Hash,Stl,Iterator,我试图使用哈希表删除列表中存储的整数向量的重复组合。迭代列表中的每个整数向量,I: 计算hash_值(thash) 查看哈希值是否已在哈希表(pids)中 如果它在哈希表中,请从列表中删除该向量。 否则,将该值添加到hash_表并递增列表 迭代器 Print语句似乎证实了我的逻辑,但循环在迭代的第四步挂起。我已经对引起问题的it++和vz.remove(it)进行了注释,它们只显示下面代码中的逻辑。该代码也可通过ideone获得: #包括 #包括 #包括 #包括 #包括 使用名称空间std; 双

我试图使用哈希表删除列表中存储的整数向量的重复组合。迭代列表中的每个整数向量,I:

  • 计算hash_值(thash)
  • 查看哈希值是否已在哈希表(pids)中
  • 如果它在哈希表中,请从列表中删除该向量。 否则,将该值添加到hash_表并递增列表 迭代器
  • Print语句似乎证实了我的逻辑,但循环在迭代的第四步挂起。我已经对引起问题的
    it++
    vz.remove(it)
    进行了注释,它们只显示下面代码中的逻辑。该代码也可通过ideone获得:

    #包括
    #包括
    #包括
    #包括
    #包括
    使用名称空间std;
    双hash_cz(std::vector&cz,std::vector&lprimes){
    双pid=0;
    for(auto it=cz.begin();it!=cz.end();it++){
    pid+=lprimes[*it];
    }
    返回pid;
    }
    int main(){
    //创建向量列表
    std::列表vz;
    vz.推回({2,1});
    vz.推回({1,2});
    vz.推回({1,3});
    vz.推回({1,2,3});
    vz.推回({2,1});
    //素数对数向量
    std::向量lprimes{2,3,5,7};
    对于(自动it=lprimes.begin();it!=lprimes.end();it++){
    *it=std::log(*it);
    }
    std::无序集PID;
    双塔什;
    for(auto it=vz.begin();it!=vz.end();){
    thash=hash_cz(*it,lprimes);
    
    问题是这行代码:

    vz.erase(it);
    
    它将迭代器保留在原来的位置,即使其无效。它应该是:

    vz.erase(it++);
    

    注意:
    std::unorered\u set::insert()
    返回值告诉您insert是否成功(如果相同的value元素已经存在),您应该调用它并检查结果。在代码中,您要查找两次:

    if (pids.insert(thash).second ) { 
        // new element added
        ++it;
    } else { 
        // insertion failed, remove 
        it = vz.erase( it );
    }
    
    正如
    std::list
    提供的,您的代码可以简化:

    vz.remove_if( [&pids,&lprimes]( auto &v ) { 
       return !pids.insert( hash_cz(v, lprimes) ).second );
    } );
    

    而不是整个循环。

    问题在于这行代码:

    vz.erase(it);
    
    它将迭代器保留在原来的位置,即使其无效。它应该是:

    vz.erase(it++);
    

    注意:
    std::unorered\u set::insert()
    返回值告诉您insert是否成功(如果相同的value元素已经存在),您应该调用它并检查结果。在代码中,您要查找两次:

    if (pids.insert(thash).second ) { 
        // new element added
        ++it;
    } else { 
        // insertion failed, remove 
        it = vz.erase( it );
    }
    
    正如
    std::list
    提供的,您的代码可以简化:

    vz.remove_if( [&pids,&lprimes]( auto &v ) { 
       return !pids.insert( hash_cz(v, lprimes) ).second );
    } );
    

    而不是整个循环。

    如果元素已经被看到,则删除(
    it
    节点,然后在循环结束时增加
    it
    :未定义的行为。请尝试删除(it++)


    如果未看到该元素,则递增
    it
    ,然后在
    for
    的末尾再次执行,如果
    it
    was
    end()-1
    ,则在该元素移过末尾时产生UB。

    如果已看到该元素,则删除()单击
    it
    节点,然后在循环结束时递增
    it
    :未定义的行为。请尝试删除(it++)


    如果未看到该元素,则递增
    it
    ,然后在
    for
    的末尾再次执行,如果
    it
    end()-1
    当它移动到末尾时。

    非常简单。谢谢你的澄清!非常简单。谢谢你的澄清!非常好的回答。非常感谢你的帮助。谢谢你关于插入到
    无序集的提示。
    。非常好的回答。非常感谢你的帮助。谢谢你关于插入
    无序集的提示ed_集合