如何管理 Wordle Game (JavaFx) 中的重复字母?
How can I manage duplicate letters in Wordle Game (JavaFx)?
在我比较秘密单词和猜测单词的算法中,我需要管理重复的字母。例如,
如果秘密词是 newly
并且猜到的词是 newer
,这个输出应该是 "GGGWW" (G = green(Correct Place), W = White(The Letter不在秘密词中)),
但我下面的算法输出“GGGYW”(Y = 黄色(字母在单词中但不在正确的位置))。
for (int i = 0; i < 5; i++) {
if (secret.charAt(i) == prop.charAt(i)) {
status[i] = LetterStatus.IN;
} else if (secret.contains(Character.toString(prop.charAt(i)))) {
status[i] = LetterStatus.OK;
} else {
status[i] = LetterStatus.NOTIN;
}
}
return status;
secret = secretword,数组status是(IN, OK, NOTIN)
的enum,所以字母和prop status就是猜词。
关于如何修改此代码以解决我的问题的任何想法
你必须考虑出现的次数。所以,先处理完全匹配,记录目前没有找到的字母。对于每一个猜中的对方,把这个字母从记录的字母中去掉,这样就不会再匹配了。例如
ArrayList<Character> missing = new ArrayList<>();
for(int i = 0; i < 5; i++) {
if(secret.charAt(i) == prop.charAt(i)) {
status[i] = LetterStatus.IN;
}
else missing.add(secret.charAt(i));
}
if(!missing.isEmpty()) {
for(int i = 0; i < 5; i++) {
if(secret.charAt(i) != prop.charAt(i)) {
Object ch = prop.charAt(i); // ensure to use remove(Object) not remove(int)
status[i] = missing.remove(ch)? LetterStatus.OK: LetterStatus.NOTIN;
}
}
}
对于大数据,你会使用类似Map<Character,Integer>
的东西来记录每个元素出现的次数,但由于我们这里最多有五个元素,所以使用ArrayList
更简单同时提供合理的性能。重要的是要记住,这种方法不会扩展到其他问题。
最简单的似乎就是在每次 secret
字符匹配 prop
字符时覆盖秘密中的匹配字母,然后检查字母是否在单词中
for (int i = 0; i < 5; i++) {
if (secret.charAt(i) == prop.charAt(i)) {
status[i] = LetterStatus.IN;
secret = secret.substring(0, i) + "-" + secret.substring(i+1); // or any other invalid character that will not be provided by user
}
}
for (int i = 0; i < 5; i++) {
if(status[i] == null) {
if (secret.contains(Character.toString(prop.charAt(i)))) {
status[i] = LetterStatus.OK;
} else {
status[i] = LetterStatus.NOTIN;
}
}
}
return status;
还有一个问题,您想如何处理黄色的重复字符(假设用户提供 newee
- e
应该都是黄色还是只有一个),也许您会需要稍微调整一下这段代码
在我比较秘密单词和猜测单词的算法中,我需要管理重复的字母。例如,
如果秘密词是 newly
并且猜到的词是 newer
,这个输出应该是 "GGGWW" (G = green(Correct Place), W = White(The Letter不在秘密词中)),
但我下面的算法输出“GGGYW”(Y = 黄色(字母在单词中但不在正确的位置))。
for (int i = 0; i < 5; i++) {
if (secret.charAt(i) == prop.charAt(i)) {
status[i] = LetterStatus.IN;
} else if (secret.contains(Character.toString(prop.charAt(i)))) {
status[i] = LetterStatus.OK;
} else {
status[i] = LetterStatus.NOTIN;
}
}
return status;
secret = secretword,数组status是(IN, OK, NOTIN)
的enum,所以字母和prop status就是猜词。
关于如何修改此代码以解决我的问题的任何想法
你必须考虑出现的次数。所以,先处理完全匹配,记录目前没有找到的字母。对于每一个猜中的对方,把这个字母从记录的字母中去掉,这样就不会再匹配了。例如
ArrayList<Character> missing = new ArrayList<>();
for(int i = 0; i < 5; i++) {
if(secret.charAt(i) == prop.charAt(i)) {
status[i] = LetterStatus.IN;
}
else missing.add(secret.charAt(i));
}
if(!missing.isEmpty()) {
for(int i = 0; i < 5; i++) {
if(secret.charAt(i) != prop.charAt(i)) {
Object ch = prop.charAt(i); // ensure to use remove(Object) not remove(int)
status[i] = missing.remove(ch)? LetterStatus.OK: LetterStatus.NOTIN;
}
}
}
对于大数据,你会使用类似Map<Character,Integer>
的东西来记录每个元素出现的次数,但由于我们这里最多有五个元素,所以使用ArrayList
更简单同时提供合理的性能。重要的是要记住,这种方法不会扩展到其他问题。
最简单的似乎就是在每次 secret
字符匹配 prop
字符时覆盖秘密中的匹配字母,然后检查字母是否在单词中
for (int i = 0; i < 5; i++) {
if (secret.charAt(i) == prop.charAt(i)) {
status[i] = LetterStatus.IN;
secret = secret.substring(0, i) + "-" + secret.substring(i+1); // or any other invalid character that will not be provided by user
}
}
for (int i = 0; i < 5; i++) {
if(status[i] == null) {
if (secret.contains(Character.toString(prop.charAt(i)))) {
status[i] = LetterStatus.OK;
} else {
status[i] = LetterStatus.NOTIN;
}
}
}
return status;
还有一个问题,您想如何处理黄色的重复字符(假设用户提供 newee
- e
应该都是黄色还是只有一个),也许您会需要稍微调整一下这段代码