Java生成随机真实单词校验wordIndex时出现死循环问题求助
死循环问题原因及修复方案
核心问题触发点
- 随机字母范围错误:字母表共26个小写字母,代码中生成随机数范围是
0~23,永久取不到最后两位y、z,如果对应首字母下没有符合前缀要求的后续单词,就会直接触发死循环。 - 前缀匹配条件错误:校验前缀时写的是
test.length() > eachLetter+2,要求单词长度严格大于你要取的前缀长度,长度恰好等于前缀长度的单词会被直接排除。如果当前前缀只有等长单词匹配,代码会永远找不到符合条件的结果。 - 未做兜底判断:如果当前已生成的前缀没有对应的更长单词,代码还是会硬着头皮继续生成下一位字符,永远找不到匹配就会卡死。
- (效率问题)找到匹配前缀后未中断遍历,无意义遍历剩余单词拉低运行效率。
修复方案
- 修正随机数范围:所有生成随机字母的逻辑,把
(int) (Math.random() * (24 - 0) + 0)替换为(int) (Math.random() * 26),覆盖全部26个小写字母。 - 修正前缀匹配长度判断:把
if(test.length() > eachLetter+2)改为if(test.length() >= eachLetter+2),兼容长度恰好等于前缀长度的单词匹配,也可以直接用startsWith方法简化前缀判断逻辑,减少索引计算错误。 - 增加前缀兜底校验:每次生成下一位字符前,先统计当前前缀所有可能的后续字符,如果不存在合法后续字符,直接终止当前单词的生成,不再硬凑预设长度。
- 匹配成功后添加break:找到符合条件的前缀后直接跳出单词遍历循环,提升运行效率。
- 调整随机单词长度逻辑:如果需要生成长度≥1的单词,可以把
int randWordLength = (int) (Math.random() * (10 - 0) + 0);改为int randWordLength = (int) (Math.random() * 10) + 1;,避免出现生成0长度单词的异常情况。
修正后参考代码
public ArrayList<String> randomSize(int length) { ArrayList<String> randomWords = new ArrayList<>(length); String letters = "abcdefghijklmnopqrstuvwxyz"; // 外层循环生成指定数量的单词 for (int eachSlot = 0; eachSlot < length; eachSlot++) { // 生成1-10位的单词长度,可按需调整范围 int randWordLength = (int) (Math.random() * 10) + 1; int slotFound = 0; String firstConfirmedLetter = ""; // 生成合法首字母 while (slotFound == 0) { int randNumer = (int) (Math.random() * 26); String firstLetter = letters.substring(randNumer, randNumer + 1); if (wordIndex.containsKey(firstLetter)) { firstConfirmedLetter = firstLetter; randomWords.add(firstConfirmedLetter); randWordLength--; slotFound = 1; } } // 生成剩余字符 for (int eachLetter = 0; eachLetter < randWordLength; eachLetter++) { String currentPrefix = randomWords.get(eachSlot); // 先检查当前前缀是否有合法后续字符,没有就直接终止生成 boolean hasValidSuffix = false; for (int i = 0; i < wordIndex.get(firstConfirmedLetter).size(); i++) { String test = wordIndex.get(firstConfirmedLetter).get(i); if (test.length() >= currentPrefix.length() + 1 && test.startsWith(currentPrefix)) { hasValidSuffix = true; break; } } if (!hasValidSuffix) { break; } // 生成匹配的下一位字符 int isFound = 0; while (isFound == 0) { int randLetter = (int) (Math.random() * 26); String nextLetter = letters.substring(randLetter, randLetter + 1); String currWord = currentPrefix + nextLetter; for (int i = 0; i < wordIndex.get(firstConfirmedLetter).size(); i++) { String test = wordIndex.get(firstConfirmedLetter).get(i); if (test.length() >= currWord.length() && test.startsWith(currWord)) { randomWords.set(eachSlot, currWord); isFound = 1; break; } } } } } return randomWords; }
内容的提问来源于stack exchange,提问作者Nexteon
相关产品推荐
相关产品推荐

