Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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 有效地测试一个列表是否是另一个列表的排列_C_Arrays_Assembly_Permutation - Fatal编程技术网

C 有效地测试一个列表是否是另一个列表的排列

C 有效地测试一个列表是否是另一个列表的排列,c,arrays,assembly,permutation,C,Arrays,Assembly,Permutation,我在读一篇文章,其中提出了检查一个列表是否是另一个列表的排列的问题,并提出了两种解决方案 “c大脑”解决方案“你知道列表总是包含四个更少的数字,每个数字都小于256,因此我们可以将所有排列字节打包成32位整数,然后…” “PythonBrain”解决方案是对两者进行排序,然后进行比较,这似乎更为明显,但我对一个更高效(且级别较低)的解决方案感兴趣 我最初的做法是: 其中al+ar==bl+br==4,用于确定我们正在检查的字节 另一种方法 评论框中有人说:“在C语言中,为什么不简单地动态分配一段

我在读一篇文章,其中提出了检查一个列表是否是另一个列表的排列的问题,并提出了两种解决方案

“c大脑”解决方案“你知道列表总是包含四个更少的数字,每个数字都小于256,因此我们可以将所有排列字节打包成32位整数,然后…”

“PythonBrain”解决方案是对两者进行排序,然后进行比较,这似乎更为明显,但我对一个更高效(且级别较低)的解决方案感兴趣

我最初的做法是: 其中al+ar==bl+br==4,用于确定我们正在检查的字节

另一种方法 评论框中有人说:“在C语言中,为什么不简单地动态分配一段大小合适的内存,并将其视为一个数字? 的确,它比使用int要慢一点,但它也不限于包含四个或更少的元素或最多256个元素,并且仍然比排序(无论是在C还是Python中)快。”

如果我们可以有一个数组,它的位长度大于我们的最大数,那么我们可以设置适当的位并比较数组,但这会提供更多的比较,因为我们会进行比较,除非我们可以在c中有效地将其视为一个大数

在x86中(我刚刚开始学习),我们有SBC指令,所以我们可以减去每个部分,如果结果都为零(我们可以用JNE/JNZ测试),那么它们是相等的

据我所知,我们仍然需要做/SBCs和跳跃

实际问题 我想知道怎么做

  • 字节压缩
  • 将整个列表视为一个大数字

  • 可用于检查一个列表是否是另一个列表的排列(假设列表不超过4个项目,每个项目<256)

    优化假设结果可能为“否”:计算每个列表的和(或xor,或其他一些廉价的、关联的、可交换的运算符)。如果总和不同,则未经进一步测试,答案是否定的。如果总和相同,则执行更昂贵的测试以获得最终答案。

    优化假设结果可能为“否”:计算每个列表的总和(或xor,或其他廉价的、关联的、可交换的运算符)。如果总和不同,则未经进一步测试,答案是否定的。如果总和相同,则执行更昂贵的测试以获得最终答案。

    我认为您只需要不受排列影响的哈希。添加作为一种方法提供。我正在考虑一种与过滤器兼容的方法,这样你就可以用它做更多的事情

    bloom过滤器可以处理任意长度和任意大小的列表。它可以用来查看一个列表是否与一组列表具有相同的排列。它可以用来查看列表中是否存在元素

    bloom过滤器基本上是一个位数组。您只需将构成列表的元素的“或”位组合在一起,即可生成bloom过滤器。以任何顺序具有相同元素的任何列表都将设置相同的位。对于小列表,您可以在位数组中使用整数:

    unsigned char b = a1|a2|a3|a4; // where a1..n are items (8 bit numbers)
    
    如果您有a1项和带有bloom b的列表,并且想知道a1是否在列表中:

    fPossibleMatch = ((a1&b) == a1);
    
    如果您有两个任意长度的blooms b1和b2列表,并且想知道b2中是否存在b1的所有项目:

    fPossibleMatch = ((b1&b2) == b1);
    
    如果您想知道具有相同元素的列表b1和b2是否是彼此的排列

    fPossibleMatch = (b1==b2);
    
    要减少误报,请加宽bloom过滤器。如果我们使用64位bloom,我们可以使用这个任意选择的算法来分散位:

    unsigned long long b = (a1<<(a1&0x1F)) | (a2<<(a2&0x1F)) | (a3<<(a3&0x1F)) | a4<<(a4&0x1F);
    

    unsigned long long b=(a1我想你只需要一个不受排列影响的散列。加法是作为一种方法提供的。我在考虑一种与过滤器兼容的方法,这样你就可以用它做更多的事情了

    bloom筛选器可以处理任意长度和任意大小的列表。它可以用来查看列表是否与一组列表具有相同的排列。它可以用来查看列表中是否存在元素

    bloom筛选器基本上是一个位数组。您只需将构成列表的元素位“或”组合在一起,即可生成bloom筛选器。任何以任何顺序包含相同元素的列表都将设置相同的位。对于小列表,您可以在位数组中使用整数:

    unsigned char b = a1|a2|a3|a4; // where a1..n are items (8 bit numbers)
    
    如果您有a1项和带有bloom b的列表,并且想知道a1是否在列表中:

    fPossibleMatch = ((a1&b) == a1);
    
    如果您有两个任意长度的blooms b1和b2列表,并且想知道b2中是否存在b1的所有项目:

    fPossibleMatch = ((b1&b2) == b1);
    
    如果您想知道具有相同元素的列表b1和b2是否是彼此的排列

    fPossibleMatch = (b1==b2);
    
    为了减少误报,扩大bloom过滤器。如果我们使用64位bloom,我们可以使用这种任意选择的算法来分散位:

    unsigned long long b = (a1<<(a1&0x1F)) | (a2<<(a2&0x1F)) | (a3<<(a3&0x1F)) | a4<<(a4&0x1F);
    

    unsigned long long b=(a1使用哈希表并遍历每个列表。这将给出一个需要O(n)时间和O(n)内存的解决方案。

    使用哈希表并遍历每个列表。这将给出一个需要O(n)时间和O(n)内存的解决方案。

    (假设列表不超过4个项目,并且每个项目<256)在这些假设下,大多数解决方案都是常数时间。O表示法是关于渐近行为的,而不是告诉您对4个元素进行排序需要多少比较。无论如何,如果您稍微放宽条件,您仍然可以在比较列表之前使用线性时格排序来对列表进行排序。以下操作将起作用:创建一个has第一个列表的h表映射(元素->计数(元素))(通过迭代并插入/递增)。然后迭代第二个列表,递减计数。如果无法递减键的计数(哈希中不存在或为零),或者列表具有不同的