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++ cpp无序_集仅使用比较器而不是哈希 #包括 #包括 阶级边缘{ 公众: 浮子a1; 浮子a2; }; 结构组件{ 布尔运算符()(常数边和e1、常数边和e2)常数{ 返回true; 返回( (e1.a1==e2.a1和&e1.a2==e2.a2)|| (e1.a1==e2.a2和&e1.a2==e2.a1) ); }; }; 结构散列{ 大小\u t运算符()(常数边和e1)常数{ //返回std::hash()(e1.a1+e1.a2); 返回std::hash()(e1.a1+e1.a2*2); }; }; int main(){ std::无序的_集s1; s1.插入(边{1.1,2.2}); s1.插入(边{2.2,1.1}); 用于(自动和it:s1){ std::cout_C++_Set - Fatal编程技术网

C++ cpp无序_集仅使用比较器而不是哈希 #包括 #包括 阶级边缘{ 公众: 浮子a1; 浮子a2; }; 结构组件{ 布尔运算符()(常数边和e1、常数边和e2)常数{ 返回true; 返回( (e1.a1==e2.a1和&e1.a2==e2.a2)|| (e1.a1==e2.a2和&e1.a2==e2.a1) ); }; }; 结构散列{ 大小\u t运算符()(常数边和e1)常数{ //返回std::hash()(e1.a1+e1.a2); 返回std::hash()(e1.a1+e1.a2*2); }; }; int main(){ std::无序的_集s1; s1.插入(边{1.1,2.2}); s1.插入(边{2.2,1.1}); 用于(自动和it:s1){ std::cout

C++ cpp无序_集仅使用比较器而不是哈希 #包括 #包括 阶级边缘{ 公众: 浮子a1; 浮子a2; }; 结构组件{ 布尔运算符()(常数边和e1、常数边和e2)常数{ 返回true; 返回( (e1.a1==e2.a1和&e1.a2==e2.a2)|| (e1.a1==e2.a2和&e1.a2==e2.a1) ); }; }; 结构散列{ 大小\u t运算符()(常数边和e1)常数{ //返回std::hash()(e1.a1+e1.a2); 返回std::hash()(e1.a1+e1.a2*2); }; }; int main(){ std::无序的_集s1; s1.插入(边{1.1,2.2}); s1.插入(边{2.2,1.1}); 用于(自动和it:s1){ std::cout,c++,set,C++,Set,如果您想交替处理edge.a1和edge.a2,您必须实现一个哈希函数,即使在交换它们时也返回相同的值。我建议不要使用加法,因为,您可以按大小对它们进行排序,然后合并哈希: #include <unordered_set> #include <iostream> class edge{ public: float a1; float a2; }; struct comp{ bool operator()(const e

如果您想交替处理
edge.a1
edge.a2
,您必须实现一个哈希函数,即使在交换它们时也返回相同的值。我建议不要使用加法,因为,您可以按大小对它们进行排序,然后合并哈希:

#include <unordered_set>
#include <iostream>

class edge{
    public:
        float a1;
        float a2;

};

struct comp{
    bool operator()(const edge& e1, const edge& e2) const {
        return true;
        return (
            (e1.a1==e2.a1 && e1.a2==e2.a2) ||
            (e1.a1==e2.a2 && e1.a2==e2.a1)
        );
    };
};
struct hash{
    size_t operator()(const edge& e1) const {
        // return std::hash<float>()(e1.a1+e1.a2);
        return std::hash<float>()(e1.a1+e1.a2*2);
    };
};


int main() {
    std::unordered_set<edge,hash,comp> s1;
    s1.insert(edge{1.1,2.2});
    s1.insert(edge{2.2,1.1});
    for( auto& it : s1 ) {
        std::cout << it.a1 << " " << it.a2 << "\n";
    }
    std::cout << "s1.size " << s1.size() << "\n";
}
这样,使用交换的两条边就不会得到相同的哈希值 建议使用()这种组合哈希的方法


如果要交替处理
edge.a1
edge.a2
,则必须实现一个哈希函数,该函数即使在交换时也返回相同的值。我建议不要使用加法,因为,您可以按大小对其排序,然后合并哈希:

#include <unordered_set>
#include <iostream>

class edge{
    public:
        float a1;
        float a2;

};

struct comp{
    bool operator()(const edge& e1, const edge& e2) const {
        return true;
        return (
            (e1.a1==e2.a1 && e1.a2==e2.a2) ||
            (e1.a1==e2.a2 && e1.a2==e2.a1)
        );
    };
};
struct hash{
    size_t operator()(const edge& e1) const {
        // return std::hash<float>()(e1.a1+e1.a2);
        return std::hash<float>()(e1.a1+e1.a2*2);
    };
};


int main() {
    std::unordered_set<edge,hash,comp> s1;
    s1.insert(edge{1.1,2.2});
    s1.insert(edge{2.2,1.1});
    for( auto& it : s1 ) {
        std::cout << it.a1 << " " << it.a2 << "\n";
    }
    std::cout << "s1.size " << s1.size() << "\n";
}
这样,使用交换的两条边就不会得到相同的哈希值 建议使用()这种组合哈希的方法

您不必使用
edge
的成员来提供散列。只要求相等的值具有相等的散列。可以使用“始终有效”散列

但你最初的尝试似乎更好

struct hash{
    size_t operator()(const edge& e1) const {
        return 0;
    };
};
struct散列{
大小\u t运算符()(常数边和e1)常数{
返回std::hash{}(e1.a1+e1.a2);//+是可交换的
};
};
您不必使用
edge
的成员来提供散列。只要求相等的值具有相等的散列。可以使用“始终有效”散列

但你最初的尝试似乎更好

struct hash{
    size_t operator()(const edge& e1) const {
        return 0;
    };
};
struct散列{
大小\u t运算符()(常数边和e1)常数{
返回std::hash{}(e1.a1+e1.a2);//+是可交换的
};
};


std::unordered\u multiset
是否符合您的要求?如果您使用
std::tie
,则排序通常并不困难。您的目的是使
size()==1
?“我意识到,如果不同的元素具有相同的哈希值,则认为它们相等。”-不正确。无序集哈希+比较器的要点是提供恒定时间哈希和线性子时间(k)比较。无序集仍然是一个集(疯狂,对吧?)。元素是唯一的。唯一性是通过
散列
在当前哈希表中找到合适的碰撞桶,然后通过
比较
在碰撞桶中搜索匹配的元素来确定的。如果这不是您想要的行为,则停止尝试将方形木桩推入圆孔;使用不同的con我认为比较哈希比比较一个<代码>浮点< /代码> s要快得多,而且你的哈希看起来有点弱。所以我会考虑使用<代码> STD::设置。<代码> STD::unOrdEdSuleSuth是否符合你的要求?如果使用<代码> STD::TIG/<代码>,通常不难排序。你的意图是拥有< COD >e> size()==1
?“我意识到如果不同的元素具有相同的哈希值,那么它们被认为是相等的”-不是真的。无序集哈希+比较器的要点是提供恒定时间哈希和线性子时间(k)比较。无序集仍然是一个集(疯狂,对吧?)。元素是唯一的。唯一性是通过
散列
在当前哈希表中找到合适的碰撞桶,然后通过
比较
在碰撞桶中搜索匹配的元素来确定的。如果这不是您想要的行为,则停止尝试将方形木桩推入圆孔;使用不同的con我认为比较哈希比比较一对<代码>浮点< /代码> s要快得多。总之,你的哈希看起来有点弱。所以我会考虑使用<代码> STD::设置< <代码> >。这将使<>代码> unordeDeSET/<代码>的所有好处无效。为什么不只是使用<代码> SET?那么,EIKE不是每个好处。OP仍然可以使用T。继承人KeyEqual(混淆地称为
comp
),但他的实现似乎不应该实现equals操作。@Evg OPs
hash
+
comp
给出了未定义的behaviour@eike“相同”根据
comp
的定义,这将使
unordered\u set
的所有好处无效。那么为什么不直接使用
set
呢?@eike并不是所有好处。OP仍然可以使用它们的KeyEqual(混淆地称为
comp
)但他的实现似乎不应该实现等于运算。@Evg OPs
hash
+
comp
给出了未定义的behaviour@eike“相同”正如
comp
所定义的。如果我正确理解了这个问题,那么我的意图是让
comp
忽略
a1
a2
的顺序。然后问题是OP的哈希函数不正确。@Evg如果OP实现了一个equals操作,而不是对
KeyEqual
进行比较,那么问题就解决了问题是。@eike的目的是忽略a1和a2的顺序,因为对于edge,哪一个是无关紧要的first@Athos好的,这解释了很多。我完全误解了你的问题。现在编辑…如果我正确理解了这个问题,目的是让
comp
忽略
a1
a2
的顺序d那么问题是OP的哈希函数不正确。@Evg如果OP实现了等于运算而不是对
KeyEqual
进行比较,那么问题就解决了。@E的目的是忽略a1和a2的顺序,因为对于edge,哪一个是无关紧要的first@A
struct hash{
    size_t operator()(const edge& e1) const {
        return std::hash<float>{}(e1.a1 + e1.a2); // + is commutative
    };
};