JS:编写一个遍历字符串列表并返回列表中最常见的前10个字符串的函数

九次

我试图编写一个遍历字符串列表并返回列表中最常见的前10个字符串的函数。我正在尝试针对这个问题提出多种解决方案

这是我的第一个解决方案

const list = [
    "this",
    "is",
    "a",
    "test",
    "which",
    "word",
    "wins",
    "top",
    "i",
    "don't",
    "know",
    "off",
    "hand",
    "do",
    "you",
    "this",
    "a",
    "a",
    "this",
    "test",
    "a",
    "a",
    "do",
    "hand",
    "hand",
    "a",
    "whatever",
    "what",
    "do",
    "do"
  ];

function fn1(strArr) {
    const map = new Map()
    for(const str of strArr) {
        if(map.has(str)) {
            map.set(str, map.get(str) + 1)
        } else {
            map.set(str, 1)
        }
    }
    const sortedMap =[...map.entries()].sort(([_,a], [__,b]) => a < b ? 1 : -1)
    return sortedMap.slice(0 , 10).map(([str]) => str)
}

但是我似乎找不到其他解决方案。有人可以提出替代建议吗?

另外,要注意的一件事是列表可能很大,可能包含一百万个字符串。所以我们需要尽量减少运行时的复杂性

莫斌

我相信以下解决方案在实践中是最快的:

  1. n正如已经完成的,字符串映射到其频率。O(n)
  2. 将地图转换为具有字符串/频率对的数组。 O(n)
  3. 使用弗洛伊德(Floyd)方法根据频率数组转换为最大堆(即,对所有从⌊n/2⌋ - 1低到0的索引调用max-heapify )。O(n)
  4. 提取顶部元素k时间。(对于您而言,k=10。)O(k log n)

(我这里没有提供任何代码,因为它基本上是由调用二进制堆库组成的(高度优化的实现请参见此处)。)

分析

渐近复杂度O(n + k log n)小于O(n log k)混沌猴子提供的解决方案。对于较小的对象k(例如10),可能不会有任何显着差异。越大,差异越明显k(只要k ≪ n;更大k,请参见下面的“替代”)。另请注意,步骤1和2的常数因子为1,而步骤3的常数因子也平均较小(1.8814),因此总常数因子小于4。

另类

有一种解决方案可以O(n)平均地解决该问题,而且还具有较小的常数因子,对于较大的因子k(即k接近时n/2),效率更高缺点是(极不可能)最坏情况下的复杂度是O(n²)

  1. n正如已经完成的,字符串映射到其频率。O(n)
  2. 将地图转换为具有字符串/频率对的数组。 O(n)
  3. 应用Quickselect(与Quicksort完全一样,但仅在分区的一侧递归)以找到k最大频率。左侧的所有元素甚至更大,因此结果是kQuickselected数组的第一个元素。O(n)平均,O(n²)最坏的情况。

可以O(n)使用中位数枢轴选择来实现具有保证复杂性的Quickselect变体,但这在实际中并不是那么好,因为恒定因子非常高。但是从学术角度来看,这将是渐近最优解。

是一个用于Quickselect的JavaScript库,尽管乍一看,该实现似乎不适用于这种情况:一个好的实现应该执行Dijkstra风格的3路分区。)

基准测试

一个快速和肮脏的基准用n = 10^6k = 10,仅测量运行时步骤2后(由于步骤1/2全部5种方法之间共享):

Average time for Sort: 7.5 ms
Average time for ChaosMonkey: 10.25 ms
Average time for CountingSort: 5.25 ms
Average time for Mo B. Max-Heap: 4 ms
Average time for Mo B. Alternative (Quickselect): 3.25 ms

https://dotnetfiddle.net/oHRMsp

我的结论是,对于给定的参数,不同方法之间没有太大差异。为简单起见,我将坚持使用排序方法,该方法对于n都可以很好地扩展k

(很多警告:它是用C#(而不是JavaScript)编写的(草率的);尚未经过正确性测试;未优化单个方法;运行时也可能取决于频率的分布,实现的Quickselect天真,因为未对其进行优化对于(这里)很多频率相等的常见情况等)

关于空间的最后说明

所有基准测试方法都使用一个额外的O(n)空间,因为它们首先创建频率图(而计数排序方法O(n)在频率图的顶部使用一个额外的最坏情况空间进行计数)。可以仅用O(1)额外的空间来解决该问题,但要以时间复杂度为代价O(kn²)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Ocaml - 对字符串列表中的每个字符串应用一个函数并返回一个新的字符串列表

来自分类Dev

编写一个将字符串列表作为参数并返回包含每个字符串长度的列表的函数

来自分类Dev

如何编写返回字符串列表中超过10个字符的字符串计数的程序

来自分类Dev

JavaScript | 返回字符串中最常见的多个字符

来自分类Dev

编写一个接收字符串列表并返回列表列表的函数

来自分类Dev

显示多个字符串列表中的一个字符串

来自分类Dev

给定一个字符串列表,如何检查这些字符串是否在列表中?

来自分类Dev

返回字符串中最常见的字符

来自分类Dev

查找字符串列表中的字符串是否在Esper中的另一个字符串列表中

来自分类Dev

停留在遍历列表并在字符串以列表中的另一个字符串结尾时返回True

来自分类Dev

如何生成其中出现另一个字符串的字符串列表

来自分类Dev

将字符串列表连接到一个字符串haskell

来自分类Dev

如何寻找另一个字符串中的字符串列表?

来自分类Dev

如何知道一个字符串是否属于python中字符串列表的组合?

来自分类Dev

在其他字符串列表中查找一个字符串

来自分类Dev

将一个字符串附加/连接到字符串列表的元素(Python 3.5)

来自分类Dev

遍历列表以查找数据并构造一个字符串

来自分类Dev

编写一个名为shortest()的函数,该函数在字符串列表中查找最短字符串的长度

来自分类Dev

用另一个字符串列表对字符串列表进行排序

来自分类Dev

使用另一个字符串列表对字符串列表进行排序

来自分类Dev

用python中的字符串列表替换一个字符串列表

来自分类Dev

将字符串列表复制到另一个字符串列表

来自分类Dev

根据另一个字符串列表对字符串列表进行排序

来自分类Dev

在字符串列表中找到最常见的子字符串?

来自分类Dev

遍历字符串列表,然后将所有字符串附加到另一个字符串(第一个单词除外)

来自分类Dev

如何从字符串列表中的每个字符串中删除最后一个字符

来自分类Dev

如何创建一个列表,其中包含两个字符串之间常见字母的所有可能组合?

来自分类Dev

根据字符串中的第一个字符,找到字符串列表中元素的第一个匹配项

来自分类Dev

根据字符串中的第一个字符,找到字符串列表中元素的第一个匹配项

Related 相关文章

  1. 1

    Ocaml - 对字符串列表中的每个字符串应用一个函数并返回一个新的字符串列表

  2. 2

    编写一个将字符串列表作为参数并返回包含每个字符串长度的列表的函数

  3. 3

    如何编写返回字符串列表中超过10个字符的字符串计数的程序

  4. 4

    JavaScript | 返回字符串中最常见的多个字符

  5. 5

    编写一个接收字符串列表并返回列表列表的函数

  6. 6

    显示多个字符串列表中的一个字符串

  7. 7

    给定一个字符串列表,如何检查这些字符串是否在列表中?

  8. 8

    返回字符串中最常见的字符

  9. 9

    查找字符串列表中的字符串是否在Esper中的另一个字符串列表中

  10. 10

    停留在遍历列表并在字符串以列表中的另一个字符串结尾时返回True

  11. 11

    如何生成其中出现另一个字符串的字符串列表

  12. 12

    将字符串列表连接到一个字符串haskell

  13. 13

    如何寻找另一个字符串中的字符串列表?

  14. 14

    如何知道一个字符串是否属于python中字符串列表的组合?

  15. 15

    在其他字符串列表中查找一个字符串

  16. 16

    将一个字符串附加/连接到字符串列表的元素(Python 3.5)

  17. 17

    遍历列表以查找数据并构造一个字符串

  18. 18

    编写一个名为shortest()的函数,该函数在字符串列表中查找最短字符串的长度

  19. 19

    用另一个字符串列表对字符串列表进行排序

  20. 20

    使用另一个字符串列表对字符串列表进行排序

  21. 21

    用python中的字符串列表替换一个字符串列表

  22. 22

    将字符串列表复制到另一个字符串列表

  23. 23

    根据另一个字符串列表对字符串列表进行排序

  24. 24

    在字符串列表中找到最常见的子字符串?

  25. 25

    遍历字符串列表,然后将所有字符串附加到另一个字符串(第一个单词除外)

  26. 26

    如何从字符串列表中的每个字符串中删除最后一个字符

  27. 27

    如何创建一个列表,其中包含两个字符串之间常见字母的所有可能组合?

  28. 28

    根据字符串中的第一个字符,找到字符串列表中元素的第一个匹配项

  29. 29

    根据字符串中的第一个字符,找到字符串列表中元素的第一个匹配项

热门标签

归档