JavaScript 字谜比较
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23785465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript anagram comparison
提问by Ryan
I'm trying to compare two strings to see if they are anagrams.
我正在尝试比较两个字符串以查看它们是否为字谜。
My problem is that I'm only comparing the first letter in each string. For example, "Mary" and "Army" will return true but unfortunately so will "Mary" and Arms."
我的问题是我只比较每个字符串中的第一个字母。例如,“Mary”和“Army”将返回真值,但不幸的是,“Mary”和“Arms”也将返回真值。
How can I compare each letter of both strings before returning true/false?
如何在返回真/假之前比较两个字符串的每个字母?
Here's a jsbin demo (click the "Console" tab to see the results"):
这是一个 jsbin 演示(单击“控制台”选项卡查看结果“):
http://jsbin.com/hasofodi/1/edit
http://jsbin.com/hasofodi/1/edit
function compare (a, b) {
y = a.split("").sort();
z = b.split("").sort();
for (i=0; i<y.length; i++) {
if(y.length===z.length) {
if (y[i]===z[i]){
console.log(a + " and " + b + " are anagrams!");
break;
}
else {
console.log(a + " and " + b + " are not anagrams.");
break;
}
}
else {
console.log(a + " has a different amount of letters than " + b);
}
break;
}
}
compare("mary", "arms");
回答by Oriol
Instead of comparing letter by letter, after sorting you can join
the arrays to strings again, and let the browser do the comparison:
不是逐个字母比较,排序后您可以join
再次将数组转换为字符串,并让浏览器进行比较:
function compare (a, b) {
var y = a.split("").sort().join(""),
z = b.split("").sort().join("");
console.log(z === y
? a + " and " + b + " are anagrams!"
: a + " and " + b + " are not anagrams."
);
}
回答by Raja Sekar
If you want to write a function, without using inbuilt one, Check the below solution.
如果您想编写一个函数,而不使用内置函数,请查看以下解决方案。
function isAnagram(str1, str2) {
if(str1 === str2) {
return true;
}
let srt1Length = str1.length;
let srt2Length = str2.length;
if(srt1Length !== srt2Length) {
return false;
}
var counts = {};
for(let i = 0; i < srt1Length; i++) {
let index = str1.charCodeAt(i)-97;
counts[index] = (counts[index] || 0) + 1;
}
for(let j = 0; j < srt2Length; j++) {
let index = str2.charCodeAt(j)-97;
if (!counts[index]) {
return false;
}
counts[index]--;
}
return true;
}
回答by pujoey
This considers case sensitivity and removes white spaces AND ignore all non-alphanumeric characters
这会考虑区分大小写并删除空格并忽略所有非字母数字字符
function compare(a,b) {
var c = a.replace(/\W+/g, '').toLowerCase().split("").sort().join("");
var d = b.replace(/\W+/g, '').toLowerCase().split("").sort().join("");
return (c ===d) ? "Anagram":"Not anagram";
}
回答by Wallace Sidhrée
Make the function return false if the length between words differ and if it finds a character between the words that doesn't match.
如果单词之间的长度不同并且在单词之间找到不匹配的字符,则使函数返回 false。
// check if two strings are anagrams
var areAnagrams = function(a, b) {
// if length is not the same the words can't be anagrams
if (a.length != b.length) return false;
// make words comparable
a = a.split("").sort().join("");
b = b.split("").sort().join("");
// check if each character match before proceeding
for (var i = 0; i < a.length; i++) {
if ((a.charAt(i)) != (b.charAt(i))) {
return false;
}
}
// all characters match!
return true;
};
It is specially effective when one is iterating through a big dictionary array, as it compares the first letter of each "normalised" word before proceeding to compare the second letter - and so on. If one letter doesn't match, it jumps to the next word, saving a lot of time.
当迭代一个大字典数组时,它特别有效,因为它在继续比较第二个字母之前比较每个“规范化”单词的第一个字母 - 依此类推。如果一个字母不匹配,它会跳到下一个单词,节省大量时间。
In a dictionary with 1140 words (not all anagrams), the whole check was done 70% faster than if using the method in the currently accepted answer.
在包含 1140 个单词(并非所有字谜)的字典中,整个检查的速度比使用当前接受的答案中的方法快 70%。
回答by dominicbri7
I modified your function to work.
我修改了你的功能来工作。
It will loop through each letter of both words UNTIL a letter doesn't match (then it knows that they AREN'T anagrams).
它将遍历两个单词的每个字母,直到一个字母不匹配(然后它知道它们不是字谜)。
It will only work for words that have the same number of letters and that are perfect anagrams.
它仅适用于具有相同字母数且是完美字谜的单词。
function compare (a, b) {
y = a.split("").sort();
z = b.split("").sort();
areAnagrams = true;
for (i=0; i<y.length && areAnagrams; i++) {
console.log(i);
if(y.length===z.length) {
if (y[i]===z[i]){
// good for now
console.log('up to now it matches');
} else {
// a letter differs
console.log('a letter differs');
areAnagrams = false;
}
}
else {
console.log(a + " has a different amount of letters than " + b);
areAnagrams = false;
}
}
if (areAnagrams) {
console.log('They ARE anagrams');
} else {
console.log('They are NOT anagrams');
}
return areAnagrams;
}
compare("mary", "arms");
回答by danielbh
A more modern solution without sorting.
更现代的解决方案,无需排序。
function(s, t) {
if(s === t) return true
if(s.length !== t.length) return false
let count = {}
for(let letter of s)
count[letter] = (count[letter] || 0) + 1
for(let letter of t) {
if(!count[letter]) return false
else --count[letter]
}
return true;
}
回答by Pradeep kumar
function validAnagramOrNot(a, b) {
if (a.length !== b.length)
return false;
const lookup = {};
for (let i = 0; i < a.length; i++) {
let character = a[i];
lookup[character] = (lookup[character] || 0) + 1;
}
for (let i = 0; i < b.length; i++) {
let character = b[i];
if (!lookup[character]) {
return false;
} else {
lookup[character]--;
}
}
return true;
}
validAnagramOrNot("a", "b"); // false
validAnagramOrNot("aza", "zaa"); //true
回答by Inamur Rahman
I think this is quite easy and simple.
我认为这很容易和简单。
function checkAnagrams(str1, str2){
var newstr1 = str1.toLowerCase().split('').sort().join();
var newstr2 = str2.toLowerCase().split('').sort().join();
if(newstr1 == newstr2){
console.log("String is Anagrams");
}
else{
console.log("String is Not Anagrams");
}
}
checkAnagrams("Hello", "lolHe");
checkAnagrams("Indian", "nIndisn");
回答by bonatheripper
//The best code so far that checks, white space, non alphabets
//characters
//without sorting
function anagram(stringOne,stringTwo){
var newStringOne = ""
var newStringTwo = ''
for(var i=0; i<stringTwo.length; i++){
if(stringTwo[i]!= ' ' && isNaN(stringTwo[i]) == true){
newStringTwo = newStringTwo+stringTwo[i]
}
}
for(var i=0; i<stringOne.length; i++){
if(newStringTwo.toLowerCase().includes(stringOne[i].toLowerCase())){
newStringOne=newStringOne+stringOne[i].toLowerCase()
}
}
console.log(newStringOne.length, newStringTwo.length)
if(newStringOne.length==newStringTwo.length){
console.log("Anagram is === to TRUE")
}
else{console.log("Anagram is === to FALSE")}
}
anagram('ddffTTh@@@#$', '@dfT9t@D@#H$F')
回答by Cracked679
function anagrams(str1,str2){
//spliting string into array
let arr1 = str1.split("");
let arr2 = str2.split("");
//verifying array lengths
if(arr1.length !== arr2.length){
return false;
}
//creating objects
let frqcounter1={};
let frqcounter2 ={};
// looping through array elements and keeping count
for(let val of arr1){
frqcounter1[val] =(frqcounter1[val] || 0) + 1;
}
for(let val of arr2){
frqcounter2[val] =(frqcounter2[val] || 0) + 1;
}
console.log(frqcounter1);
console.log(frqcounter2);
//loop for every key in first object
for(let key in frqcounter1){
//if second object does not contain same frq count
if(frqcounter2[key] !== frqcounter1[key]){
return false;
}
}
return true;
}
anagrams('anagrams','nagramas');