private static int getTotalWordValue(String word) {
int totalWordValue = 0;
// Code that produces correct results.
for(int i=0; i < alpha.length(); i++) {
char letter = alpha.charAt(i);
for(char ch: word.toCharArray()) {
if(letter == ch) {
totalWordValue += i+1;
}
}
}
// Code that produces incorrect results.
totalWordValue = 0;
for(int i=0; i < alpha.length(); i++) {
String letter = String.valueOf(alpha.charAt(i)); // <-- here?
if(word.indexOf(letter) != -1) {
totalWordValue += i+1;
}
}
return totalWordValue;
}
运行上面的代码来解决Project Euler Problem 42后,我得到了不同的结果。上面显示的第一个'for'循环输出正确的结果,第二个'for'循环输出错误的结果。
上面的代码采用String并返回其单词值。例如,单词SKY将返回单词值55,因为此单词中的字母添加如下(从1开始):
19 + 11 + 25 = 55。
我已将问题减少到上面的代码,并且不明白为什么会发生这种情况。也许我错过了与Java String类及其方法相关的重要信息。
我在Windows 10上的Eclipse Neon.3发行版(4.6.3)中运行Java 8。
答案 0 :(得分:1)
这两段代码完全不同。
在这两种情况下,你都有一个外部循环,用于提供变量alpha
中字符串letter
的每个字符。
在第一种情况下,您有一个内部循环,它贯穿字符串word
的每个字符,并计算每个匹配事件{{1 }}。当内部循环在letter
中计算 {/ 1}}的每次时,外部循环将移至下一个letter
。
在第二种情况下,没有内循环。每次围绕外部循环,您都会使用word
来查找letter
中word.indexOf(letter)
的第一次出现的索引。如果有,你提前计算。无论哪种方式,您现在已完成letter
,外部循环移至下一个word
。在letter
中可能会出现letter
的其他情况,但这种情况并未尝试查找并计算它们。
答案 1 :(得分:1)
对于包含多个字母多次的单词,第二个实现中的单词值不正确。例如对于WOOD, 第一种方法将计算3 + 14 + 14 + 22,但第二种方法将计算3 + 14 + 22。
为什么呢?第一种方法迭代 word 的字符:
for(char ch: word.toCharArray()) { if(letter == ch) { totalWordValue += i+1; } }
第二种方法迭代字母的字符:
for(int i=0; i < alpha.length(); i++) { String letter = String.valueOf(alpha.charAt(i)); // <-- here? if(word.indexOf(letter) != -1) { totalWordValue += i+1; } }
所以在&#34; WOOD&#34;的例子中, &#34; O&#34;只计算一次,而不是两次。
顺便说一下,
转换为String
在这里毫无意义:
String letter = String.valueOf(alpha.charAt(i)); if(word.indexOf(letter) != -1) {
写出相同内容的更好方法:
char letter = alpha.charAt(i);
if (word.indexOf(letter) != -1) {
(但实施仍然不正确。)
最后, 如果字母表是英文A-Z,则可以更快地实现:
int totalWordValue = 0;
for (char c : word.toCharArray()) {
if ('A' <= c && c <= 'Z') {
totalWordValue += (c - 'A') + 1;
}
}
return totalWordValue;
答案 2 :(得分:0)
indexOf
有4个重载方法,其中一个除了if let userUID = Auth().auth.currentUser?.uid{
ref.child("members/\(userUID)").setValue(*YOURMEMBERINFODICTIONARY*)
}
参数,并返回字符序列中第一次出现的字符的索引。
现在,来找你问题。在您的方案中,character
和indexOf
的行为相同,因为您只传递了角色。而且,从内部开始,但是,想象一下,你有一个charAt
并且你想检查并从另一个长String
获取它的索引。那你会怎么做?来String
答案 3 :(得分:0)
我知道这并不一定能解决你提到的方法之间存在差异的问题,但其他人已经对此做出了很好的回答。
你想要字母表中字母的位置总和吗?我们可以在一个循环中使用一些算术来做到这一点,而不会增加内部循环或alpha
常量的开销。
像这样:
public static int getWordValue(String word) {
int value = 0; //total word value
for(char c : word.toLowerCase().toCharArray()) { //iterate over character array of lower case string
int charAsInt = (int) c; //cast char to int, giving the ASCII value
if(charAsInt <= 122 && charAsInt >= 97) { //122 is the ASCII value of 'z', and 97 is 'a'
value += (charAsInt - 96); //only subtract 96 because we want 'a' to be 1, not 0
}
}
return value;
}
如果你现在不清楚它的工作原因,那么在检查ASCII到十进制表时会很明显。我们来看看吧。
记下小写'a'和小写'z'的值。它们分别是我们的下限和上限。我们只是循环遍历每个小写字符,将其转换为带有int
强制转换的ASCII十进制值。然后我们用'a'的值减去我们的ASCII值减一。