最高得分词算法抛出古怪的错误
Highest Scoring Word algorithm throwing quirky error
我在 CodeWars 上做挑战,我遇到了一个古怪的错误。这是问题陈述:
Given a string of words, you need to find the highest scoring word. Each letter of a word scores points according to its position in the alphabet: a = 1, b = 2, c = 3 etc. You need to return the highest scoring word as a string. If two words score the same, return the word that appears earliest in the original string. All letters will be lowercase and all inputs will be valid.
这是我写的算法,在某些情况下不起作用:
public static String high(String s) {
String[] words = s.split(" ");
int[] scores = new int[words.length];
for (int j = 0; j < words.length; j++) {
for (int i = 0; i < words[j].length(); i++) {
scores[j] += (int) words[j].charAt(i);
}
}
int highestWordIndex = 0;
for (int i = 1; i < words.length; i++) {
if (scores[i] > scores[highestWordIndex]) highestWordIndex = i;
}
return words[highestWordIndex];
}
但是,当我在嵌套的 for 循环中添加一个“- 96”时,它起作用了。这是代码:
public static String high(String s) {
String[] words = s.split(" ");
int[] scores = new int[words.length];
for (int j = 0; j < words.length; j++) {
for (int i = 0; i < words[j].length(); i++) {
scores[j] += (int) words[j].charAt(i) - 96;
}
}
int highestWordIndex = 0;
for (int i = 1; i < words.length; i++) {
if (scores[i] > scores[highestWordIndex]) highestWordIndex = i;
}
return words[highestWordIndex];
}
知道为什么这会产生影响吗?
'a' 是十六进制的 0x61,或十进制的 97。所以当你 -96 时,你使用的是正确的计算。我会做以下其中一项:
score += charAt() - 0x60;
或
int offset = ('a' - 1);
...
score += charAt() - offset;
对于长度相等的单词,这不会有什么不同,但是当单词长度不同时,超出 96 的额外分数会使结果偏向更长的单词。
之所以减96有效,是因为ASCII中小写字符的十进制值是从97开始的。例如ASCII中的“a”是97,所以97 - 96 = 1,如题所求。
'a'的(int)char版本是97,'b'是98,'c'是99等等。该问题要求您将这些转换为 1,2,3,... 是有充分理由的。
考虑 cab 这个词和 ox 这个词。
"cab" 应该是 3 + 1 + 2 = 6。但是在你的实现中它是 99+97+98=294
"ox" 应该是 15 + 24 = 39。但是在你的实现中它是 111 + 120 = 231
“ox”的得分应该高于“cab”,但事实并非如此,因为您将字符转换为它们的 ascii 代表整数,而不是问题所问的 1-26。因此,您的算法会给更长的单词更多的分数,因为每个额外的字符都会比根据问题应该得到的分数高出 96 分。减去 96 将你的分数域从 97-122 降低到 1-26,这为你解决了这个问题。
希望对您有所帮助 :)
我在 CodeWars 上做挑战,我遇到了一个古怪的错误。这是问题陈述:
Given a string of words, you need to find the highest scoring word. Each letter of a word scores points according to its position in the alphabet: a = 1, b = 2, c = 3 etc. You need to return the highest scoring word as a string. If two words score the same, return the word that appears earliest in the original string. All letters will be lowercase and all inputs will be valid.
这是我写的算法,在某些情况下不起作用:
public static String high(String s) {
String[] words = s.split(" ");
int[] scores = new int[words.length];
for (int j = 0; j < words.length; j++) {
for (int i = 0; i < words[j].length(); i++) {
scores[j] += (int) words[j].charAt(i);
}
}
int highestWordIndex = 0;
for (int i = 1; i < words.length; i++) {
if (scores[i] > scores[highestWordIndex]) highestWordIndex = i;
}
return words[highestWordIndex];
}
但是,当我在嵌套的 for 循环中添加一个“- 96”时,它起作用了。这是代码:
public static String high(String s) {
String[] words = s.split(" ");
int[] scores = new int[words.length];
for (int j = 0; j < words.length; j++) {
for (int i = 0; i < words[j].length(); i++) {
scores[j] += (int) words[j].charAt(i) - 96;
}
}
int highestWordIndex = 0;
for (int i = 1; i < words.length; i++) {
if (scores[i] > scores[highestWordIndex]) highestWordIndex = i;
}
return words[highestWordIndex];
}
知道为什么这会产生影响吗?
'a' 是十六进制的 0x61,或十进制的 97。所以当你 -96 时,你使用的是正确的计算。我会做以下其中一项:
score += charAt() - 0x60;
或
int offset = ('a' - 1);
...
score += charAt() - offset;
对于长度相等的单词,这不会有什么不同,但是当单词长度不同时,超出 96 的额外分数会使结果偏向更长的单词。
之所以减96有效,是因为ASCII中小写字符的十进制值是从97开始的。例如ASCII中的“a”是97,所以97 - 96 = 1,如题所求。
'a'的(int)char版本是97,'b'是98,'c'是99等等。该问题要求您将这些转换为 1,2,3,... 是有充分理由的。 考虑 cab 这个词和 ox 这个词。
"cab" 应该是 3 + 1 + 2 = 6。但是在你的实现中它是 99+97+98=294
"ox" 应该是 15 + 24 = 39。但是在你的实现中它是 111 + 120 = 231
“ox”的得分应该高于“cab”,但事实并非如此,因为您将字符转换为它们的 ascii 代表整数,而不是问题所问的 1-26。因此,您的算法会给更长的单词更多的分数,因为每个额外的字符都会比根据问题应该得到的分数高出 96 分。减去 96 将你的分数域从 97-122 降低到 1-26,这为你解决了这个问题。
希望对您有所帮助 :)