我正在做这个非常简单的代码卡kata下面是问题:
isogram是一个没有重复字母,连续或字母的单词 不连续的。实现一个确定字符串是否的函数 只包含字母的是等值线。假设空字符串是 等值线图。忽略字母案例。
function isIsogram(str){
var letter = str.toLowerCase().split("");
for(var i = 0; i < letter.length; i++) {
if(letter.indexOf(letter[i].toLowerCase()) > -1){
return false;
}
}
return true;
}
我的解决方案总是返回false,因为indexOf中的数组会比较字符串中的每个字母。该解决方案应该将数组与自身进行比较,如果没有重复字母则返回true。但不幸的是,当我将数组与自身进行比较时,它会比较数组中的每个字母本身,所以基本上即使数组中只有一个字母的字母,因为它再次与自身进行比较,它将会返回虚假陈述。
这个问题正在扼杀我。
答案 0 :(得分:2)
检查Array#lastIndexOf(它从末尾搜索)是否与当前索引相同。如果没有,它并不是唯一的:
function isIsogram(str){
var letter = str.toLowerCase().split("");
for(var i = 0; i < letter.length; i++) {
if(letter.lastIndexOf(letter[i]) !== i){
return false;
}
}
return true;
}
console.log(isIsogram('subdermatoglyphic'));
console.log(isIsogram('rare'));
更好的解决方案是使用Set与原始字符串中的字符数比较唯一字符的数量:
const isIsogram = (str) => new Set(str.toLowerCase()).size === str.length;
console.log(isIsogram('subdermatoglyphic'));
console.log(isIsogram('rare'));
答案 1 :(得分:1)
更简单:
check = str => new Set( str.toLowerCase() ).size === str.length;
或者,如果您想修复代码,请使用两个循环:
for(var i = 0; i < letter.length; i++) {
for(var j = i+1; j < letter.length; j++){
if(letter[i] === letter[j]) return false;
}
}
答案 2 :(得分:1)
function isIsogram(str){
var letter = str.toLowerCase().split("");
for(var i = 0; i < letter.length; i++) {
for (var y = i + 1; y < letter.length; y++) {
if (letter[i] === letter[y])
return false;
}
}
return true;
}
通过不重复比较来提高效率
答案 3 :(得分:0)
这是使用@rafael提出的方法的更有效的解决方案:按字母顺序重新排序单词并逐步将每个字母与下一个字母进行比较。如果匹配,立即返回false。
function isIsogram(word) {
word = word.split('').sort().join('').toLowerCase();
for (var i = 0; i < word.length; i++) {
if (word[i] === word[i+1]) {
return false;
}
}
return true;
}