如何根据模板生成字符串的所有组合?
例如: -
的模板字符串" {我|我们}想要{| 2 | 3 | 4} {apples | pears}"
花括号" {...}"识别一个或多个单词,每个单词用" |"。
分隔该类应该生成包含每个单词组中每个单词组合的字符串。
我知道它的有限自动机,还有正则表达式。如何有效地生成组合?
例如
G [0] [j] [想要] G [1] [j] G [2] [j]"
G[0] = {I, We}
G[1] = {2, 3, 4}
G[2] = {apples, pears}
首先,生成所有可能的组合c = [0..1] [0..2] [0..1]:
000
001
010
011
020
021
100
101
110
111
120
121
然后每个c用G [i]替换G [i] [j] [c [i]]
答案 0 :(得分:2)
Shell glob
$ for q in {I,We}\ want\ {2,3,4}\ {apples,pears}; do echo "$q" ; done
I want 2 apples
I want 2 pears
I want 3 apples
I want 3 pears
I want 4 apples
I want 4 pears
We want 2 apples
We want 2 pears
We want 3 apples
We want 3 pears
We want 4 apples
We want 4 pears
答案 1 :(得分:1)
到目前为止,我发现的这个问题最有效的解决方案是Python模块sre_yield。
sre_yield的目标是有效地生成 所有 值 匹配给定的正则表达式,或计算可能的匹配 有效。
我强调的重点。
将其应用于您声明的问题:将模板制作为正则表达式模式,并在sre_yield中使用它以获取所有可能的组合或计算可能的匹配:
import sre_yield
result = set(sre_yield.AllStrings("(I|We) want (|2|3|4) (apples|pears)"))
result.__len__()
result
输出:
16
{'I want apples',
'I want pears',
'I want 2 apples',
'I want 2 pears',
'I want 3 apples',
'I want 3 pears',
'I want 4 apples',
'I want 4 pears',
'We want apples',
'We want pears',
'We want 2 apples',
'We want 2 pears',
'We want 3 apples',
'We want 3 pears',
'We want 4 apples',
'We want 4 pears'}
PS:我使用list
代替项目页面上显示的set
,以避免重复。如果这不是您想要的,请使用列表。
答案 2 :(得分:1)
原则是:
实施该原则,例如在RexLex中:
DeterministicAutomaton dfa = Pattern.compileGenericAutomaton("(I|We) want (2|3|4)? (apples|pears)")
.toAutomaton(new FromGenericAutomaton.ToMinimalDeterministicAutomaton());
if (dfa.getProperty().isAcyclic()) {
for (String s : dfa.getSamples(1000)) {
System.out.println(s);
}
}
答案 3 :(得分:0)
将每组字符串{...}转换为string array
,这样就有了n个数组。
因此,对于"{I|We} want {|2|3|4} {apples|pears}"
,我们将有4个数组。
将每个数组放入另一个数组中。在我的示例中,我将调用collection
这是Java代码,但它很简单,您应该能够将其转换为任何语言。我没有测试,但它应该工作。
void makeStrings(String[][] wordSet, ArrayList<String> collection) {
makeStrings(wordSet, collection, "", 0, 0);
}
void makeStrings(String[][] wordSet, ArrayList<String> collection, String currString, int x_pos, int y_pos) {
//If there are no more wordsets in the whole set add the string (this means 1 combination is completed)
if (x_pos >= wordSet.length) {
collection.add(currString);
return;
}
//Else if y_pos is outof bounds (meaning no more words within the smaller set {...} return
else if (y_pos >= wordSet[x_pos].length) {
return;
}
else {
//Generate 2 new strings, one to send "vertically " and one "horizontally"
//This string accepts the current word at x.y and then moves to the next word subset
String combo_x = currString + " " + wordSet[x_pos][y_pos];
makeStrings(wordSet, collection, combo_x, x_pos + 1, 0);
//Create a copy of the string and move to the next string within the same subset
String combo_y = currString;
makeStrings(wordSet, collection, combo_y, x_pos , y_pos + 1);
}
}
*编辑更正