【问题标题】:Algorithm for finding amount of word anagrams?查找单词字谜数量的算法?
【发布时间】:2021-10-16 06:42:00
【问题描述】:

所以我知道查找字谜背后的理论,如here 所示。出于我的目的,我需要找到可以从一个单词中找到的字谜的数量不包括重复项

允许重复,这相当简单。 aab 有以下字谜:

aab
aab
aba
aba
baa
baa

这个数量可以通过字母数量计算factorial得到

factorial := 1

for i := len(word); i > 0; i-- {
    factorial = i * factorial
}

// aab -> 6

但是,如果您想排除重复,您可以将潜在的字谜从 6 个减少到 3 个。例如单词 hello,它有 120 个组合,但只有 60 个没有重复。

我编写了自己的算法来制作字母映射并返回映射的长度,但这也有问题。

hello -> 24 (actually 60)
helllo -> 24 (actually 120)

我怎样才能做到这一点?

【问题讨论】:

  • 相当肯定hello 有 60 个字谜,不包括重复。 helo 有 24 个,所以hello 肯定有更多。

标签: algorithm go duplicates factorial anagram


【解决方案1】:

如果不考虑单词的有效性,那么最好放弃单词“anagram”。您只是在询问排列。有一个计算重复的排列公式:

对于长度为n 的单词,取排列的基数,即n!。 然后,对于单词中的每个唯一字母,计算该字母出现的次数。对于这些字母中的每一个,取出现次数的阶乘,然后除以排列数。

对于“你好”:

n = 6
h = 1, e = 1, l = 3, o = 1

Permutations = 6! / (1! x 1! x 3! x 1!)
= 720 / 6
= 120

【讨论】:

  • 效果很好!你从哪里得到这个算法的?
  • @CyanCoding 我最初是在高中课堂上学习概率的。
【解决方案2】:

代码:

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {

    scanner := bufio.NewScanner(os.Stdin)
    fmt.Print("Enter word: ")
    scanner.Scan()
    word := scanner.Text()

    anagrams := factorial(len(word))
    chars := strings.Split(word, "")
    word1 := word
    n := 0

    for i := 0; i < len(word); i++ {
        n = strings.Count(word1, chars[i])
        if n > 0 {
            anagrams = anagrams / factorial(n)
            word1 = strings.Replace(word1, chars[i], "", -1)
        }
    }

    fmt.Println(anagrams)

}

func factorial(n int) int {

    factorial := 1

    for i := n; i > 0; i-- {
        factorial = i * factorial
    }

    return factorial

}

结果:

aab -> 3
helo -> 24
hello -> 60
helllo -> 120

【讨论】:

    【解决方案3】:

    你可以使用一些组合数学。首先,您计算每个字符的出现次数。然后使用牛顿符号将每个字符放置在其位置。例如给定单词

    aabcdee 你有 7 个地方可以放单个字母,而且你有重复的地方——双 a 和双 e。
    所以你用那个公式
    您可以将a 放置在 7 个位置中的 2 个上,然后您可以将其乘以您可以放置​​ b - 5 个剩余位置中的 1 个的位置。然后c 在 4 之 1 上。然后在 3 之 1 上 d。然后在 2 之 2 上 e
    将这些公式中的每一个相乘将得到线性时间内的字谜数(在使用哈希图进行字母计数的情况下)。

    【讨论】:

      猜你喜欢
      • 2019-02-02
      • 2011-02-07
      • 2012-09-10
      • 2013-09-20
      • 2011-09-19
      • 2010-12-01
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多