简体   繁体   English

Javascript-查找字谜的更好解决方案-时间复杂度O(n log n)

[英]Javascript - Better solution for finding anagrams - Time complexity O (n log n)

DISCLAIMER 免责声明

Hey everyone, I understand that there are few Javascript questions/answers that deal with figuring out the how to find if two words are anagrams. 大家好,我知道很少有Javascript问题/答案可以用来弄清楚如何找到两个单词是否是字谜。

I'm not just looking for a function that figures out whether two words/strings are anagrams. 我不只是在寻找一个可以弄清楚两个单词/字符串是否是字谜的函数。 I'm looking for a function that will be quicker than the one provided below. 我正在寻找一种比下面提供的功能更快的功能。 Currently, I believe the time complexity of the function below is O (n log n) . 目前,我相信以下函数的时间复杂度为O(n log n)

I'd like to figure out a function that has a time complexity of O(n) or something that has a runtime that is quicker than the one provided. 我想找出一个函数,该函数的时间复杂度为O(n)或运行时间比提供的函数快。

CODE

const isAnagram = (str1, str2) => {

  str1 = str1.toLowerCase();
  str2 = str2.toLowerCase();


  if (str1.length !== str2.length) {
     return false
  }

  let sortStr1 = str1.split('').sort().join('').trim();
  let sortStr2 = str2.split('').sort().join('').trim();

  return sortStr1 === sortStr2
 };

console.log(isAnagram('dog', 'goD')); //true

You can try counting based algorithm. 您可以尝试基于计数的算法。

 const isAnagram = (str1, str2) => { str1 = str1.toLowerCase(); str2 = str2.toLowerCase(); //and remove any char you think not important (like space) here if (str1.length !== str2.length) return false let counting = {} for(let c of str1) if(counting[c]) ++counting[c] else counting[c] = 1 for(let c of str2) if(counting[c]) --counting[c] else return false return true }; console.log(isAnagram('dog', 'goD')); //true console.log(isAnagram('eleven plus two', 'twelve plus one')); //true console.log(isAnagram('dog', 'hot')); //false console.log(isAnagram('banana', 'nana')); //false 

Here is another possible idea that comes from: An Algorithm for Finding Anagrams and is based on the fundamental theorem of arithmetic that states: 这是来自另一个可能的想法: 查找字谜的算法,该算法基于算术基本定理,定理指出:

Every integer greater than 1 either is a prime number itself or can be represented as the product of prime numbers and that, moreover, this representation is unique, up to (except for) the order of the factors. 每个大于1整数本身就是质数,或者可以表示为质数的乘积,此外,该表示是唯一的,直到(除)因子的阶数为止。

So, if we assign each letter in the alphabet to a prime number, and then compute the product of these numbers, this number will be unique ( because of the fundamental theorem of arithmetic). 因此,如果我们将字母表中的每个字母分配给一个质数,然后计算这些数字的乘积,则该数字将是唯一的(由于算术的基本定理)。 That means that for a multiset of letters, the product of prime numbers for each letter in that multiset is unique. 这意味着对于字母的多集合,该多集合中每个字母的素数乘积是唯一的。 Then, if two words or sentences have the same number, these two words or sentences are anagrams of each other. 然后,如果两个单词或句子具有相同的编号,则这两个单词或句子是彼此的字谜。

Implementation: 实现方式:

 let letters = {"a":2, "b":3, "c":5, "d":7, "e":11, "f":13, "g":17, "h":19, "i":23, "j":29, "k":31, "l":37, "m":41, "n":43, "o":47, "p":53, "q":59, "r":61, "s":67, "t":71, "u":73, "v":79, "w":83, "x":89, "y":97, "z":101}; const isAnagram = (str1, str2) => { str1 = str1.toLowerCase(); str2 = str2.toLowerCase(); let repStr1 = 1, repStr2 = 1; for (let i = 0; i < Math.max(str1.length, str2.length); i++) { repStr1 *= (str1[i] && letters[str1[i]]) ? letters[str1[i]] : 1; repStr2 *= (str2[i] && letters[str2[i]]) ? letters[str2[i]] : 1; } return (repStr1 === repStr2); }; console.log("[dog, goD] Anagrams?", isAnagram('dog', 'goD')); console.log("[dogo, goD] Anagrams?", isAnagram('dogo', 'goD')); console.log("[Roast Beef, Eat for BSE] Anagrams?", isAnagram('Roast Beef', 'Eat for BSE')); 
 .as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;} 

Advantages 好处

  • Accepts anagrams of different lengths (check third example). 接受不同长度的字谜(请参见第三个示例)。
  • Is O(n) (only one loop is required). O(n) (仅需要一个循环)。

Disadvantages 缺点

  • Won't work for large expressions, there will be an overflow on the generated number. 不适用于大型表达式,生成的数字将溢出。
  • Needs a predefined dictionary between letters and primer numbers. 需要在字母和引物数字之间预定义的字典。
  • Won't work for expression that contains rare characters, unless you extend the dictionary, but the overflow will become more frequently. 除非扩展字典,否则不适用于包含稀有字符的表达式,但是溢出将变得更加频繁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Javascript:将解决方案更改为O(n log n) - Javascript: Change the solution to O(n log n) 这个函数的时间复杂度是否为O(log n)? - Is the time complexity of this function O(log n)? 此解决方案O(N)或O(LogN)的时间复杂度是多少? - What is time complexity of this solution O(N) or O(LogN)? 该函数的时间复杂度是O(N)还是O(N ^ 2)? - Is the time complexity for this function O(N) or O(N^2)? 为什么优先队列入队的时间复杂度是 O(log n)? - why is Time complexity of a Priority Queue enqueue is O(log n)? 如何在javascript中返回O(n)时间复杂度相同的字母元素? - how to return same letters elements with O(n) time complexity in javascript? JavaScript中时间复杂度为O(n)的好友推荐算法 - Friends recommendation algorithm with O(n) time complexity in JavaScript 线性或(n log n)时间复杂度 - Linear or (n log n) time complexity 如何在不改变原始数组的情况下从时间复杂度为 O(n) 或更好的排序数组中获取唯一值 - How to get unique values from a sorted array with time complexity of O(n) or better without altering the original array 为什么这个阶乘查找算法的运行时复杂度不是 O(n!)? - Why isn't this factorial finding algorithm O(n!) run-time complexity?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM