Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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
String 在超过百万个字符串的列表中,以相反顺序排列的字符串对?_String_Reverse - Fatal编程技术网

String 在超过百万个字符串的列表中,以相反顺序排列的字符串对?

String 在超过百万个字符串的列表中,以相反顺序排列的字符串对?,string,reverse,String,Reverse,最近在一次采访中被问到“如果在一个超过百万个字符串的列表中存在所有字符串的反向,如何找到?” 例如,str[1]=“abc”,我需要准确地检查“cba”,没有字谜 方法1.将所有字符串存储在一个hashset中,从第一个字符串开始遍历,检查hashset中是否存在反向形式。如果是,则将pair else移动到下一个元素 如果内存是约束条件,您可以建议任何方法吗?您可以使用,它将告诉您是否在类似哈希表的结构中已经存在字符串,但每个bucket仅为0或1,因此占用的空间非常小 确切地说,1000 0

最近在一次采访中被问到“如果在一个超过百万个字符串的列表中存在所有字符串的反向,如何找到?”

例如,str[1]=“abc”,我需要准确地检查“cba”,没有字谜

方法1.将所有字符串存储在一个hashset中,从第一个字符串开始遍历,检查hashset中是否存在反向形式。如果是,则将pair else移动到下一个元素

如果内存是约束条件,您可以建议任何方法吗?

您可以使用,它将告诉您是否在类似哈希表的结构中已经存在字符串,但每个bucket仅为0或1,因此占用的空间非常小


确切地说,1000 000位==125 KB

如果允许的话,您可以对字符串进行适当的排序,这样当您查找字符串的反面时,您就可以进行二进制搜索。

首先,我将使用一个与方向无关的散列对字符串进行散列。这可能是一个简单的字符和,尽管肯定有更好的方案可以对f进行散列为了“增加交易的甜头”,可以将字符串长度附加到散列值,或者将其合并到散列中

然后,当字符串被分成相同的散列组时,进行“长手”比较

请注意,使用此方案或简单地向前或向后使用方向相关哈希的方案时,要做的事情是不要立即将字符串插入哈希集中,而是首先检查它(如果需要,使用反向哈希),然后检查是否匹配(随后的长比较为真)删除已经散列的字符串并将其配对。第二个字符串永远不会进入该集合,并且,如果所有字符串最多都有匹配项,则散列集合中只有500000个条目,如果字符串是随机的,则可能接近250000个(我还没有坐下来计算概率)

因此,只需通过一次字符串集即可完成整个操作。

使用“内存作为约束条件”,我甚至不会选择HashSet(它也会删除原始列表中的重复字符串),因为您将使用需要一些内存的HashSet的附加结构

排序也不会提高内存使用率

我将使用原始列表(已经存在,因此不会使用额外内存)+一个3字节的整数变量来迭代列表。3字节可以迭代2^24=16777216个字符串的列表

使用“内存作为约束条件”,我会选择2个for循环。我认为类似C的伪代码会更容易理解,因为我的简单英语

注:

  • 根据问题中提供的示例,它实际上不是一个列表,而是一个数组,因此我将对该结构进行操作,就像它是一个数组一样
  • 问题不清楚如何将此“abc”、“def”、“cba”、“abc”配对。我将把第一个“abc”与“cba”配对,同时将“cba”与“第二个”abc配对(问题中的意图不清楚)
  • 我想我们不能修改原始列表
  • 下面是我能想到的内存消耗最少的代码:

    // "list" holds the original list (array)
    for (int i = 0; i < length(list) - 1; i++) {
        for (int j = i + 1; j < length(list); j++) {
            if (list[i] == reverse(list[j])) {
                print(list[i] + " reversed is " list[j])
            }
        }
    }
    
    /“list”保存原始列表(数组)
    对于(int i=0;i
    关于内存使用,这个解决方案将使用2个整数变量(通常每个4字节)+原始列表,我认为我们无法摆脱它


    关于CPU使用率(实际上,与问题无关),字符串的反转次数将为:(N*(N+1))/2,其中N是列表的长度

    您可以选择哈希表并使用bucket来减少哈希冲突。对于特定的查询字符串,我们现在需要做的是将其反转、散列并在哈希表中查找,而不是从头到尾遍历。

    这是我的观点:

    我会用

    key=character

    value=以该字符开头的字符串列表

    • 现在开始一个循环,需要从第一个字符串开始
    • 倒过来
    • 获取第一个字符并在哈希中搜索该键
    • 然后在该值中,它包含字符串列表,并在该列表中查找字符串

    1。)这将占用更多内存。2) 你不需要长字符串就能得到很多长度相同的字符串。使用方向独立散列值不会给你带来任何实际好处,但肯定会增加冲突率。方向独立散列将“abc”和“cba”散列到同一个存储桶中。这大大减少了你必须尝试的组合的数量。我不明白。为什么它会减少任何东西?你说的是什么组合?使用此方案,只需比较具有相同哈希的字符串。我猜你可以安排得到至少5000个不同的散列,这样你必须与另一个进行比较的字符串的平均数量大约是200,而不是1000000。一点点努力可能会产生一个哈希算法,它会做得更好。你是说你想产生很多哈希冲突?这有什么意义?您需要一个链表来存储结果,因此不会占用更少的内存,但由于冲突,肯定会占用更多的CPU。在这种情况下,我更喜欢OP的解决方案,因为它优于。10000000000次迭代,或多或少。(不计算实际的比较循环)嗯,不。只需在列表上重复一次。这个解决方案的顺序是N。但正如我所说的,提问的人也清楚地说的那样,没有必要用最少的内存快速完成。列表已经存在了,我只是添加了3个字节。您的解决方案需要多少额外的字节?因此,请解释如何在通过列表的一次过程中识别所有反转的dup