Anagram算法检查原始的接近程度

时间:2014-01-20 07:29:35

标签: algorithm pseudocode

我正在尝试创建一个算法来测试anagram(由原始单词中的另一个算法创建)是否与原始单词太接近。上下文是一个字谜解决游戏 - 我希望游戏能够动态生成字谜(从我投入到游戏中的单词),但是由于随机性与原始单词的相似性而希望避免它们太容易解决(例如,BATMAN的字谜是BTAMAN。)

我是业余爱好者,所以我想知道我的想法是否在正确的轨道上。我目前的计划是基于为某些标准指定“点数”,然后将点数相加并检查是否达到某个阈值(意味着字谜与原始单词太相似并且应该被丢弃)。

(注意:我已经尝试了一些第三方代码来检查两个字符串的相似性,但它们似乎对字符串长度和实际字符的权重很大,这在我的字谜/原始单词对中是相同的)

我也想避免过多地使用字谜游戏并产生错误的随机性(例如,从未使用与原始单词具有相同起始字母的字谜)。

这是我的伪代码算法(游戏中的字谜,从短字到两三个字符串,如电影名称):

Function IsAnagramTooSimilarToOriginalWord(original, anagram) as Boolean
count = 0
if (original word 1st letter) = (anagram 1st letter) then count +=1
if (original word last letter) = (anagram last letter) then count +=1
if (any 3-letter substring from original word exists in anagram) then count +2 for each occurence
if count >=5 then return True else return False

等等。我可以根据结果磨练具体的检查。

我不是要求任何代码......只是想知道是否有人之前做过类似的事情和/或我是否在做任何算法noob错误。或者我是否在思考它?

我通过一个简单的算法自己创建anagrams,从字符串中取一个随机字符并将其添加到一个新字符串,直到原始字符串中没有。新算法将用于检查结果和(如果需要)重做anagram。

2 个答案:

答案 0 :(得分:2)

重量/点数系统应该更加精细。

  • 首先,你应该给第一个和最后一个字母增加更多的重量,因为如果只有它们在这个地方,而其他字母是混合的,本地读者(除了初学者或小孩子)通常甚至不会注意到。你知道吗?
  • 您应该为所有字母组合赋予相同的权重。更频繁的人应该有更大的重量。而且你必须重视严格的字母组合。例如,在英语中,如果ch,sh,tch,ck的组合被打破,则该词变得更难以识别。如果anagram打破它们,那就很好。
  • 如果出现新的常用字母组合,也很好。
  • 如果字谜代替字母,那通常听起来很接近,那就太糟糕了。
  • 如果anagram重新组合这些字母,那么一封信就会变得不同,就像sic->cis中的“c”一样,这很好。
  • 如果anagram看起来和听起来像一个普通的单词(它使用语言的频繁字母组合,较长的单词 - 越好),这是一个很好的字谜有两个原因 - 更难解决,它是NICE。 / LI>
  • 点数之和应根据单词的长度重新评估 - 它越长,就越容易做出困难的图表。

准备 - 所有重量系统必须 严重 测试。我建议做一个测试程序,提出解决方案的字谜,并比较评估时间和评估重量系统的质量。更好的是,如果它可以分别评估加权原则。

当然,经过这样的测试,您可以找到更多原则。顺便说一句,它是心理学博士论文的良好基础。

答案 1 :(得分:1)

这是我正在测试的代码。到目前为止,它已被证明足以满足我的需求,但在上面的评论中有一些很好的想法可以进一步改善它。为VB道歉,但这就是我使用的。这段代码很通用,但具体是VB.net WinRT代码

到目前为止,对于包含多个单词的4个字符,最多约25个字符的单词,这种方法效果很好。

Public Function IsAnagramTooSimilarToOriginal(originalWord As String, anagramWord As String) As Boolean

    ' matchPoints tracks how many matches are found between the two strings        
    Dim matchPoints As Integer = 0

    ' first letters of each string match
    If originalWord.Substring(0, 1) = anagramWord.Substring(0, 1) Then
        If originalWord.Length < 7 Then matchPoints += 3 Else matchPoints += 1.5
    End If


    ' last letters of each string match
    If originalWord.Substring(originalWord.Length - 1, 1) = anagramWord.Substring(anagramWord.Length - 1, 1) Then
        If originalWord.Length < 7 Then matchPoints += 2 Else matchPoints += 1.5
    End If


    ' first two letters match (NOTE: this is in addition to the first letters matching, so the points accumulate)
    If originalWord.Substring(0, 2) = anagramWord.Substring(0, 2) Then matchPoints += 1

    ' each three character string that appears in order in both strings
    For count = 0 To (originalWord.Length - 3)
        If anagramWord.Contains(originalWord.Substring(count, 3)) Then matchPoints += 2

    Next

    ' each four character string that appears in order in both strings
    For count = 0 To (originalWord.Length - 4)
        If anagramWord.Contains(originalWord.Substring(count, 4)) Then matchPoints += 2

    Next

    Dim result As Boolean = False

    If originalWord.Length - matchPoints <= 3 Then
        ' this makes the rules more stringent for shorter words
        result = True
    Else

        If matchPoints >= 5 Then result = True

    End If

    Return result


End Function