查找单词字谜数量的算法?
Posted
技术标签:
【中文标题】查找单词字谜数量的算法?【英文标题】: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
肯定有更多。
【参考方案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
。
将这些公式中的每一个相乘将得到线性时间内的字谜数(在使用哈希图进行字母计数的情况下)。
【讨论】:
以上是关于查找单词字谜数量的算法?的主要内容,如果未能解决你的问题,请参考以下文章