[英]How to get multiple solutions for a crossword?
我已经看过论坛和不同的问题。
但我想问一些不同的问题。 我有两个不同单词的单词列表和一个由 0 和 1 指定的网格。我将不得不从单词列表 1 中的 select 单词中获取行和 2 中的列。
主要问题是我必须在给定的时间限制内找到多个解决方案。 有人可以为此建议我一些好的算法。 我没有得到我应该采取什么样的算法方法。
另一件事,我有两种语言选择。 c++ 或 java 会更好地实施。
谢谢你
我找到了一个可以满足您需求的解决方案。 可悲的是,我不能把它归功于它:)
这是一个例子。 你给它一个模式文件,比如pattern1
:
## ##
# #
# #
#
### ### ##
# # #
# #
# #
# #
# # #
## ### ###
#
# #
# #
## ##
您在其上调用程序,例如:
./cword pattern1 /etc/dictionaries-common/words
output 是
SODS##HOG##AMPS
APIA#RADON#LAUE
TESS#ALONE#ERNA
ENCHANTRESS#GYM
###ADS###TUTU##
#PAYDAY#ESPIES#
REV#SCALD#SCRIP
ARON#KNOWS#SITE
MCCOY#KNITS#TET
#HARASS#NAPPED#
##TACT###DIE###
MCI#COORDINATES
ELOY#AMARU#ROLL
SINE#TARIM#LIMA
SOSA##REP##SLOT
或者,再次运行:
PAWN##HOT##BEST
OLEO#SURYA#OMAR
LOAN#AGAPE#ABLE
SELFISHNESS#RTE
###ASH###OKAY##
#KATMAI#EPILOG#
INN#SYNOD#MULES
SETH#SCHWA#MONA
MEIER#AMIDS#GEM
#SPLATS#NOWAYS#
##APSE###RAY###
WIS#PATRONYMICS
ALTA#CHOKE#AREA
SLOP#HEARD#ROBS
PSST##ERA##ANUS
当然,对于较大的模式或较小的单词表,您的里程可能会有所不同(非常大)。 我能够在 Q9550 处理器上在 26.5 秒内完成 1000 代,使用
time for a in $(seq 1 200)
do
for a in 1 2 3 4 5
do
./cword pattern1 /etc/dictionaries-common/words | md5sum&
done
wait
done | sort | uniq -c | sort -n | tee >(wc -l)
output 证实这些实际上是 1000 个独特的解决方案。 不坏,如果你问我。 (时间包括计算每个解决方案的 md5sums 的时间)
您也许可以使用称为Dancing Links 或 DLX算法的东西。 这是解决精确覆盖问题的一种非常有效的算法。
有几个程序可以使用它来解决数独难题。
老实说,我对确切的封面问题知之甚少,无法说这肯定会满足您的需求,但值得一看。
在做填字游戏时,通常会发现自己在寻找一个特定长度的单词,其中包含某个 position 处的某个字母。 因此,您可能会想要这样的 function:
List<String> findWord(int ofLength, char withLetter, int atIndex) {/*implementation*/}
这可能会使用一组预先构建的 HashMap 来快速生成一组候选对象。 (您可能还希望能够跟踪该单词当前是否已在填字游戏中使用……假设不允许重复)
人们做的另一件事是使用提示进行猜测。 我认为您可能不是在寻找强大的 AI,因此留下了蛮力算法……在这种情况下,请尝试首先从最大的单词开始填写填字游戏,因为那里的可能性通常较小。
骨架算法:
private void checkPuzzleOn(Row row, SolutionSet s) {
List<Row> crossingRows = row.getCrossingRows();
if(allAlreadyFilled(crossingRows)) {
//This part of the crossword works; store info in solution set.
return;
}
crossingRows.sortBiggestToSmallest();
foreach(Row crossing in crossingRows) {
int index = row.getIndexOfIntersectionWith(crossing);
char c = row.charAt(index);
List<String> candidates = findWords(crossing.length, c, index);
foreach(String candidate in candidates) {
verifyAgainstPresentWords(crossing, candidate); //check that using this word won't collide with others; important because of cycles.
}
if(candidates.isEmpty()) {
//This part of the crossword won't match! store info in solution set.
return;
}
foreach(String candidate in candidates) {
crossing.setWord(candidate);
checkPuzzleOn(crossing, s);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.