寻找只有一个辅音不同的单词在大型单词列表中的方法
P粉757640504
2023-08-15 16:26:13
<p>我有一个近5000个“幻想”单词的列表,这些单词以ASCII文本形式书写。其中一些单词如下:</p>
<pre class="brush:php;toolbar:false;">txintoq
txiqbal
txiqfun
txiqwek
txiqyal
txiyton
txonmiq
txoqwul
txoqxik</pre>
<p>我想设计一个算法,检查/验证列表中没有两个单词之间只相差一个“相似辅音”。因此,我会像这样定义“相似辅音集合”(暂时):</p>
<pre class="brush:php;toolbar:false;">zs
xj
pb
td
kg</pre>
<p><em>一个集合中可能有3个或更多辅音,但我现在只展示2个。随着我对幻想语言音调中哪些辅音听起来相似的了解越来越深入,我需要进一步调整这个定义。</em></p>
<p>因此,像下面这样的单词将被标记为“需要修正”(因为它们听起来太相似):</p>
<pre class="brush:php;toolbar:false;">txindan
txintan # 只有d/t不同
xumaq
jumaq # 只有x/j不同
dolpar
dolbar # 只有a b/p不同</pre>
<p>我如何在我的约5000个单词列表中以<em>相对高效</em>的方式找到这些只相差一个辅音的单词?</p>
<p>这是我目前所想到的一种非常天真的解决方法,如下所示:</p>
<pre class="brush:php;toolbar:false;">import fs from 'fs'
const terms = fs
.readFileSync('term.csv', 'utf-8')
.trim()
.split(/n+/)
.map(line => {
let [term] = line.split(',')
return term
})
.filter(x => x)
const consonantSets = `
zs
xj
pb
td
kg`
.split(/n+/)
.map(x => x.split(''))
function computeSimilarTerms(
term: string,
consonantSets: Array<Array<string>>,
) {
const termLetters = term?.split('') ?? []
const newTerms: Array<string> = []
for (const consonantSet of consonantSets) {
for (const letter of consonantSet) {
for (const letter2 of consonantSet) {
if (letter === letter2) {
continue
}
let i = 0
while (i < termLetters.length) {
const termLetter = termLetters[i]
if (termLetter === letter) {
const newTerm = termLetters.concat()
termLetters[i] = letter2
newTerms.push(newTerm.join(''))
}
i++
}
}
}
}
return newTerms
}
for (const term of terms) {
const similarTerms = computeSimilarTerms(term, consonantSets)
similarTerms.forEach(similarTerm => {
if (terms.includes(similarTerm)) {
console.log(term, similarTerm)
}
})
}</pre>
<p>如何以相对较少的蛮力方式完成这个任务?而且这个解决方法还不完整,因为它没有构建<em>所有可能相似的单词组合</em>。所以在算法的某个地方,它应该能够做到这一点。有什么想法吗?</p>
在每个组中选择一个辅音作为该组的“代表”。然后,构建一个将单词分组在一起的映射,当它们的辅音被代表辅音替换时,它们变得相同。
重要提示:此方法仅在辅音组形成等价类时有效。特别是,辅音的相似性必须是传递的。如果
'bp'
相似,'bv'
相似,但'pv'
不相似,则此方法无效。以下是用Python示例的代码; 我让你编写JavaScript代码。
f
是一个将每个辅音映射到其代表辅音的映射;d
是一个将每个代表单词映射到具有此代表的单词列表的映射。最后,我们可以看到哪些单词是相似的: