【发布时间】:2021-09-16 01:43:25
【问题描述】:
我正在处理这段代码:
const vowels = ['i', 'a', 'u', 'e', 'E', 'U', 'I', 'o', 'A', 'O', 'o#', 'u#', 'e#', 'i#', 'a#']
const consonants = ['m', 'n', 'q', 'g', 'd', 'b', 'p', 't', 'k', 'h', 'l', 'w', 'f', 's', 'C', 'z', 'v', 'y', 'x', 'r', 'c', 'j', 'Q', 'S', 'Z', '\'']
const tones = ['', '+', '-']
const shapes = [
'{c}{c}{v}{t1}{v}{t2}',
'{c}{v}{t1}{v}{t2}',
'{c}{v}{t}',
'{c}{c}{v}{t}',
'{c}!{v}{t}',
]
const words = {}
shapes.forEach(shape => {
words[shape] = generate(shape)
})
function generate(shape) {
const sets = {
v: vowels,
c: consonants,
t: tones
}
const selectors = {}
const nodes = []
shape.replace(/{(\w)(\d)?}/g, (_, $1, $2 = '') => {
selectors[`${$1}${$2}`] = sets[$1]
nodes.push(`${$1}${$2}`)
return _
})
// getting lost here
nodes.forEach(node => {
})
}
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
console.log(words)
shapes 数组有如下内容:{c}{c}{v}{t1}{v}{t2},其中c 表示辅音,v 表示元音,t 表示音调(来自上述 3 组)。类型旁边的数字只是使我们有不相关的值,而像 {c}{c} 这样的相同键表示相同的辅音两次,而 {c1}{c2} 表示两个不同的辅音。
目标是生成shape 的所有可能组合。我们该怎么做?
对于这个形状{c}{v}{t},我们会开始看到这个结果:
mi
me
ma
mo
mu
...
mi+
me+
ma+
...
ni
ne
na
no
nu
...
我已经尝试过的是:
function cartesian() {
var arr = [].slice.call(arguments),
intLength = arr.length,
arrHelper = [1],
arrToReturn = [];
for (var i = arr.length - 1; i >= 0; i--) {
arrHelper.unshift(arrHelper[0] * arr[i].length);
}
for (var i = 0, l = arrHelper[0]; i < l; i++) {
arrToReturn.push([]);
for (var j = 0; j < intLength; j++) {
arrToReturn[i].push(arr[j][(i / arrHelper[j + 1] | 0) % arr[j].length]);
}
}
return arrToReturn;
}
const vowels = [
'i',
'a',
'u',
'e',
'E',
'U',
'I',
'o',
'A',
'O',
'o#',
'u#',
'e#',
'i#',
'a#',
]
const consonants = [
'm',
'n',
'q',
'g',
'd',
'b',
'p',
't',
'k',
'h',
'l',
'w',
'f',
's',
'C',
'z',
'v',
'y',
'x',
'r',
'c',
'j',
'Q',
'S',
'Z',
'\'',
]
const tones = [
'',
'+',
'-',
]
const nasals = [
'',
'~',
]
const pharyngeals = [
'',
'~',
]
const ejectives = [
'',
'!',
]
const implosives = [
'',
'?',
]
const shapes = [
'{c}{c}{v}{t1}{v}{t2}',
'{c}{v}{t1}{v}{t2}',
'{c}{v}{t}',
'{c}{c}{v}{t}',
'{c}!{v}{t}',
]
const words = {}
shapes.forEach(shape => {
words[shape] = generate(shape)
})
function generate(shape) {
const sets = {
v: vowels,
c: consonants,
t: tones,
n: nasals,
p: pharyngeals
}
const selectors = {}
const string = []
shape.replace(/{(\w)(\d)?}/g, (_, $1, $2 = '') => {
selectors[`${$1}${$2}`] = sets[$1]
string.push(`${$1}${$2}`)
return _
})
const keys = Object.keys(selectors)
const values = keys.map(selector => selectors[selector])
const combinations = cartesian(...values)
.map(nodes => {
const map = {}
nodes.forEach((node, i) => map[keys[i]] = node)
return map
})
const result = []
combinations.forEach(combination => {
const out = shape.replace(/{(\w+)}/g, (_, $1) => {
return combination[$1]
})
result.push(out)
})
return result
}
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
这里是生成随机值的版本,内存中存储的值太多了。
const vowels = [
'i',
'a',
'u',
'e',
'E',
'U',
'I',
'o',
'A',
'O',
'o#',
'u#',
'e#',
'i#',
'a#',
]
const consonants = [
'm',
'n',
'q',
'g',
'd',
'b',
'p',
't',
'k',
'h',
'l',
'w',
'f',
's',
'C',
'z',
'v',
'y',
'x',
'r',
'c',
'j',
'Q',
'S',
'Z',
'\'',
]
const tones = [
'',
'+',
'-',
]
const nasals = [
'',
'~',
]
const focusings = [
'',
'~',
'=',
'Y',
'w',
'h',
]
const explosivities = [
'',
'!',
'?',
]
const shapes = [
'{c}{f}{e}{v}{t}{n}',
'{c}{f}{e}{v}{t1}{n}{v}{t2}{n}',
'{c}{f}{e}{c}{f}{e}{v}{t}{n}',
'{c}{f}{e}{c}{f}{e}{v}{t1}{n}{v}{t2}{n}',
'{c1}{f1}{e1}{c2}{f2}{e2}{v}{t}{n}',
'{c}{f}{e}{v1}{t}{n}{v2}{t}{n}',
'{c}{f}{e}{c}{f}{e}{v1}{t}{n}{v2}{t}{n}',
]
function generate() {
const sets = {
v: vowels,
c: consonants,
t: tones,
n: nasals,
f: focusings,
e: explosivities
}
const shape = shapes[randomBetween(0, shapes.length - 1)]
const selectors = {}
const string = []
shape.replace(/{(\w)(\d)?}/g, (_, $1, $2 = '') => {
selectors[`${$1}${$2}`] = sets[$1]
string.push(`${$1}${$2}`)
return _
})
const values = {}
Object.keys(selectors).forEach(selector => {
const set = selectors[selector]
const idx = randomBetween(0, set.length - 1)
values[selector] = set[idx]
})
const result = string.map(selector => values[selector]).join('')
return result
}
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
console.log(generate())
console.log(generate())
console.log(generate())
console.log(generate())
【问题讨论】:
-
试图使其更具可读性
-
!是什么意思? -
到目前为止,您尝试了哪些方法来自行解决此问题?它有什么问题?
-
@Andreas 我添加了我的尝试,我猜对了吗?
-
如果您有工作代码,但正在寻找更简单、更清洁、更高效、更优雅等,那么Code Review 更合适。另外:“这是一个生成随机值的版本”:我不明白为什么会出现在您的问题中,因为您明确 要求 生成 all 可能性。它使问题变得混乱。你是在随机生成之后还是在完全生成之后?
标签: javascript algorithm generator combinations