Algorithm 给定网格的纵横字谜算法

Algorithm 给定网格的纵横字谜算法,algorithm,crossword,Algorithm,Crossword,在我写一些关于这个问题的文章之前,我需要让你知道: 这个问题是我的家庭作业(我有大约一周的时间返回工作计划) 我花了大约一周的时间,每天都在研究这个问题,试图找到自己的解决办法 我不是要求完整的程序;我需要一个关于算法的大致概念 问题: 给定:单词列表和“网格”,例如: b X baca b X bXXX 网格(X表示任何字母): 字表: ccaa baca baaa bbbb 您必须找到示例“解决方案”-是否可以将单词列表中的单词放入给定的网格中?如果至少有一种解决方案,请打印一种(以正

在我写一些关于这个问题的文章之前,我需要让你知道:

  • 这个问题是我的家庭作业(我有大约一周的时间返回工作计划)
  • 我花了大约一周的时间,每天都在研究这个问题,试图找到自己的解决办法
  • 我不是要求完整的程序;我需要一个关于算法的大致概念
  • 问题:

    给定:单词列表和“网格”,例如:

    b X 
    baca
    b X
    bXXX
    
    网格(X表示任何字母):

    字表:

    ccaa
    baca
    baaa
    bbbb
    
    您必须找到示例“解决方案”-是否可以将单词列表中的单词放入给定的网格中?如果至少有一种解决方案,请打印一种(以正确的为准)。如果没有-打印消息,说明没有可能的解决方案。例如,有一个解决方案:

    b c 
    baca
    b a 
    baaa
    
    我很难写出我已经尝试过的所有东西(因为英语不是我的母语,我也有很多错误想法的论文)

    我的朴素算法的工作原理如下:

  • 第一个单词只需要适当的长度,所以找到任何长度合适的(第一个?)单词(我将使用给定的示例网格和单词列表来演示我的想法):

  • 对于第一个常用字母(在两个单词的交叉处),找到适合网格的任何(第一个)单词(因此,具有适当的长度,并且常用字母位于适当的位置)。如果没有这样的单词,回到(1)并记下另一个第一个单词。在原始示例中,没有以“c”开头的单词,因此我们返回(1)并选择下一个单词(此步骤重复几次,直到第一个单词有“bbbb”)。现在我们有:

    b X 
    bXXX
    b X
    bXXX
    
    我们正在寻找以“b”开头的单词,例如:

    b X 
    baca
    b X
    bXXX
    
  • 一般过程:尝试找到适合给定网格的成对单词。如果没有这样的词语,回到上一步,使用另一个组合——如果没有这样的组合——就没有解决方案

  • 上面的一切都很混乱,我希望你们至少能理解问题的描述。我写了一个算法草案,但我不确定它是否有效,以及如何正确地编写代码(在我的例子中:c++)。此外,在某些情况下(甚至在上面的例子中),我们需要找到一个依赖于2个或更多其他单词的单词

    也许我只是看不到一些明显的东西,也许我太笨了,也许。。。嗯,我真的试图解决这个问题。我的英语水平不高,无法准确描述我对这个问题的看法,所以我不能把我所有的笔记都放在这里(我试图描述一个想法,但很难)。信不信由你,我花了很多时间试图找出解决办法,但我几乎什么都没有

    如果你能描述一个解决方案,或者给我一个如何解决这个问题的提示,我会非常感激的。

    十字军的问题是,所以你最好的办法是使用暴力:尝试所有的可能性,当可能性有效时停止。当您用尽所有可能的解决方案时返回失败

    可以在第3.3节中找到证明该问题是NP完全问题的约简

    使用的暴力解决方案可能是:[伪代码]:

    solve(words,grid):
       if words is empty:
           if grid.isValudSol():
              return grid
           else:
              return None
       for each word in words:
           possibleSol <- grid.fillFirst(word)
           ret <- solve(words\{word},possibleSol)
           if (ret != None):
              return ret
       return None
    
    solve(单词、网格):
    如果单词为空:
    如果grid.isValudSol():
    回流栅
    其他:
    一无所获
    对于单词中的每个单词:
    
    我今天早上写了一个节目。以下是伪代码中稍微高效的版本:

    #pseudo-code
    solve ( words , grid ) : solve ( words , grid , None ) 
    
    solve ( words , grid , filledPositions ) :
        if words is empty :
            if grid is solved :
                return grid
            else :
                raise ( no solution )
        for ( current position ) as the first possible word position in grid 
                that is not of filledPositions :
            # note : a word position must have no letters before the word
                # 'before the word' means, eg, to the left of a horizontal word
                # no letters may be placed over a ' ' 
                # no letters may be placed off the grid
            # note : a location may have two 'positions' : one across , one down
            for each word in words :
                make a copy of grid
                try :
                    fill grid copy, with the current word, at the current position
                except ( cannot fill position ) :
                    break
                try :
                    return solve ( words\{word} , grid copy , 
                            filledPositions+{current position} )
                except ( no solution ) :
                    break
            raise ( no solution )
    
    下面是我在网格中水平放置单词的代码:

    以下是我在STL中使用的一些东西:


    网格中的
    X
    s是否具有相同的字符?i、 e.如果
    X
    是'a',那么所有
    X
    都必须是'a'?不,'X'表示任何字母,用于显示纵横字谜的网格(“模板”)外观。这些字符不需要相同。你能添加一个没有解决方案的情况吗?相同的网格,但“bbbb”有“bbba”。(编辑:在接下来的7小时内,我将无法回答其他问题)好的,如果我能找到解决方案,我将在这里发布!如果函数
    fillFirst
    找不到任何可能的解决方案怎么办?
    possibleSol
    的值是多少?你能举个更具体的例子吗?我不确定我是否理解你的算法。如果fillFirst()不能做任何事情,它会让谜题保持原样。。。该算法非常简单:它只需尝试拼图的所有可能解决方案,如果遇到一个,则返回一个有效的解决方案。您能给出一些语言(c++,java)中的
    fillFirst()
    示例吗?我理解这个函数的概念,但不知道如何实现它。我将网格表示为一个二维数组,其中包含1(当有字母的位置时)和0(当它应该是一个空白时)。我该如何确定我是否可以将一个单词放入给定的网格(可以部分填充)?我已经找到了我的笔记,有一次我的想法非常相似,但只是没有添加两行。无论如何,我理解你的解决方案,谢谢你的帮助。
    #pseudo-code
    solve ( words , grid ) : solve ( words , grid , None ) 
    
    solve ( words , grid , filledPositions ) :
        if words is empty :
            if grid is solved :
                return grid
            else :
                raise ( no solution )
        for ( current position ) as the first possible word position in grid 
                that is not of filledPositions :
            # note : a word position must have no letters before the word
                # 'before the word' means, eg, to the left of a horizontal word
                # no letters may be placed over a ' ' 
                # no letters may be placed off the grid
            # note : a location may have two 'positions' : one across , one down
            for each word in words :
                make a copy of grid
                try :
                    fill grid copy, with the current word, at the current position
                except ( cannot fill position ) :
                    break
                try :
                    return solve ( words\{word} , grid copy , 
                            filledPositions+{current position} )
                except ( no solution ) :
                    break
            raise ( no solution )