拼字游戏字谜生成器
我正在尝试编写一个拼字游戏字谜生成器。
到目前为止,我的代码可以工作,但速度非常慢,并且存在错误。其中之一是它会多次使用字母。例如:输入字母:“ABCDEFG”。它会生成AB,但也会生成AA,这是不对的。
请帮忙。
public class Scrabble1
{
private String[] dictionary2 = new String[97];
private String[] dictionary3 = new String[978];
private String[] dictionary4 = new String[3904];
private String[] dictionary5 = new String[8635];
private String[] dictionary6 = new String[15225];
private String[] dictionary7 = new String[23097];
public void sampleMethod(String s) throws FileNotFoundException
{
File in2 = new File( "dictionary2.txt" );
File in3 = new File( "dictionary3.txt" );
File in4 = new File( "dictionary4.txt" );
File in5 = new File( "dictionary5.txt" );
File in6 = new File( "dictionary6.txt" );
File in7 = new File( "dictionary7.txt" );
Scanner dict2 = null,dict3 = null,dict4 = null,dict5 = null,dict6 = null,dict7 = null;
try
{
dict2 = new Scanner(in2);
dict3 = new Scanner(in3);
dict4 = new Scanner(in4);
dict5 = new Scanner(in5);
dict6 = new Scanner(in6);
dict7 = new Scanner(in7);
int c = 0;
while(dict2.hasNext()&&dict3.hasNext()&&dict4.hasNext()&&dict5.hasNext()&&dict6.hasNext()&&dict7.hasNext())
{
dictionary2[c] = dict2.next();
dictionary3[c] = dict3.next();
dictionary4[c] = dict4.next();
dictionary5[c] = dict5.next();
dictionary6[c] = dict6.next();
dictionary7[c] = dict7.next();
c++;
}
}
catch( FileNotFoundException e )
{
System.err.println( e.getMessage () );
System.exit(1);
}
finally
{
dict2.close();
dict3.close();
dict4.close();
dict5.close();
dict6.close();
dict7.close();
}
// for(int i= 0; i<80612; i++)
//System.out.println(dicArray[i]);
String temp = "";
//All 2 letter anagrams
for(int k=0; k<=6; k++)
for(int i=0; i<=6; i++)
for(int d= 0; d<97; d++)
{
temp = "" + s.charAt(k) + s.charAt(i);
if(temp.equals(dictionary2[d]))
System.out.println(temp );
}
//All 3 letter anagrams
for(int j = 0; j<=6; j++)
for(int k=0; k<=6; k++)
for(int i=0; i<=6; i++)
for(int d= 0; d<978; d++)
{
temp = "" + s.charAt(j) + s.charAt(k)+ s.charAt(i);
if(temp.equals(dictionary3[d]))
System.out.println(temp );
}
//All 4 letter anagrams
for(int j = 0; j<=6; j++)
for(int k = 0; k<=6; k++)
for(int i=0; i<=6; i++)
for(int l=0; l<=6; l++)
for(int d= 0; d<-3904; d++)
{
temp = "" + s.charAt(j) + s.charAt(k)+ s.charAt(i)+ s.charAt(l);
if(temp.equals(dictionary4[d]))
System.out.println(temp );
}
//All 5 letter anagrams
for(int j = 0; j<=6; j++)
for(int k = 0; k<=6; k++)
for(int i=0; i<=6; i++)
for(int l=0; l<=6; l++)
for(int f=0; f<=6; f++)
for(int d= 0; d<8635; d++)
{
temp = "" + s.charAt(j) + s.charAt(k)+ s.charAt(i)+ s.charAt(l)+s.charAt(f);
if(temp.equals(dictionary5[d]))
System.out.println(temp );
}
//All 6 letter anagrams
for(int j = 0; j<=6; j++)
for(int k = 0; k<=6; k++)
for(int i=0; i<=6; i++)
for(int l=0; l<=6; l++)
for(int f=0; f<=6; f++)
for(int g=0; g<=6; g++)
for(int d= 0; d<15225; d++)
{
temp = "" + s.charAt(j) + s.charAt(k)+ s.charAt(i)+ s.charAt(l)+ s.charAt(f)+ s.charAt(g);
if(temp.equals(dictionary6[d]))
System.out.println(temp );
}
//All 7 letter anagrams.
for(int j = 0; j<=6; j++)
for(int k = 0; k<=6; k++)
for(int i=0; i<=6; i++)
for(int l=0; l<=6; l++)
for(int f=0; f<=6; f++)
for(int g=0; g<=6; g++)
for(int p=0; p<=6; p++)
for(int d= 0; d<23097; d++)
{
temp = "" + s.charAt(j) + s.charAt(k)+ s.charAt(i)+ s.charAt(l)+ s.charAt(f)+ s.charAt(g)+ s.charAt(p);
if(temp.equals(dictionary7[d]))
System.out.println(temp );
}
}
}
字典文件只是按单词大小排序。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以从字典中构建一个 trie 并遍历它。对于输入字符串中的每个字符,转到 trie 中的相应节点,从输入中删除该字符并递归重复。
伪代码:
您可以使用查找表来快速检查输入中还剩下多少特定字符(恒定时间检查)。
You could build a trie out of the dictionary and traverse it. For each character in the input string, go to the corresponding node in the trie, remove the character from the input and repeat recursively.
Pseudo-code:
You could use a lookup table to quickly check how many of a certain character there are left in the input (constant time check).
我会通过首先将所有词典统一到一个巨大的词典中来解决此问题,然后对您构建的词典中的字母以及您正在搜索的单词进行排序,以查找名为 searchWord 的子集。
我会做这样的事情
I would approach this by first unifying all of your dictionaries into one giant dictionary, and then sorting the letters in the dictionary you build and the word you're searching for subsets of called searchWord.
I would do something like this
您的问题归结为以下基本算法:
我还应该注意到一个问题您当前的代码是所有内部循环都从 0 开始,这是不正确的。这就是生成“AA”的原因(因为您最终返回索引 0 的字符两次)。
Java 中的位域计数器
Your question boils down to the following basic algorithms:
I should also note that one problem with your current code is that all your inner loops start from 0, which is not correct. This is why "AA" is generated (because you end up returning the character for index 0 twice).
A bitfield counter in Java
在Python中:
如果你想查看算法,只需查看source/文档:
In Python:
And if you want to see the algorithm, just look at the source/docs:
Jon Bentley 的书 Programming Pearls 提供了一个很好的示例这是字谜词,我相信你可以适应它。请参阅第 2 列的代码(或更好地抓住这本书!)。
我将在这里勾勒出一个实现:
1)浏览字典,对于每个单词,将字母按顺序排序(例如,fish 将变为“fihs”,“donkey”将变为“dekony”。此键将允许您查找可以用这一系列字母组成的所有单词。将此信息存储在数据结构 Map> 中,例如,对于单词“dog”,您最终会得到两个条目“dog ->”。 (god,dog)。
3) 现在,当您想要查找单词时,请按上述方式对机架中的字母序列进行排序,然后查询地图(例如,在您制作的地图中查找关键字)。这将为您提供由该系列字母组成的所有可能单词的列表。
您将在拼字游戏中对此进行一些调整,因为原始算法是用于字谜的,但它应该像多次查询地图一样简单(例如,如果您有字母 dayvgea 那么您不仅需要查询 aadgeyv ,而且还适用于 6 个及以下字母的每个组合 7 个不同 组合的数量。 items 只有 128 个,因此要找到最好的单词,您只需要在数据结构中进行固定次数的查找。
Jon Bentley's book, Programming Pearls, has a great example of doing this for anagrams and I'm sure you could adapt it. See the code for column 2 (or even better grab the book!).
I'll sketch out an implementation here:
1) Go through a dictionary, for each word sort the letters into order (e.g. fish would become "fihs", "donkey" would become "dekony". This key will allow you to look up all the words that can be made with this series of letters. Store this information in a data structure Map<String,Set<String>>. For example, for the word dog you'd end up with two entries dog -> (god,dog).
3) Now when you want to find a word, sort the sequence of letters in the rack as described above and query the map (e.g. look up the key in the Map you've made). This'll give you the list of all possible words made from that series of letters.
You'll have adapt this a little for Scrabble because the original algorithm was for anagrams, but it should be as simple as just querying the map more times (e.g. if you have the letters dayvgea then you'd need to query not only for aadgeyv, but also for each combination of 6 letters and below. The number of distinct combinations of 7 items is only 128, so to find the best word you'll only need a fixed number of lookups in the data structure.
我感谢你们提供的所有帮助。我采取了一种更简单的方法,如下:它似乎非常有效,但我仍然计划研究您提出的所有替代方案。
I appreciate all the help you have all provided. I took a simpler approach, here it is: It seems to be quite efficient, but I still plan to investigate all the alternatives you posed.