我们今天将生成所有可能的数学方程式。
给出这样的语法:[1,0][+,-][2,3]
这意味着我们需要所有字符串,其中1或0作为第一个字符,+或 - 作为第二个字符,2或3作为第三个字符。
这就是8种可能的组合
1+2
1+3
1-2
1-3
0+2
0+3
0-2
0-3
我的方法可行,但对于略微大的值,它会变慢。我解析上面的语法并为每个标记创建一个可能值的数组,并将其放在一个数组中。
equation_set = [];
tokens = [['1','0'],['+','-'],['2','3']]
// Initialize empty equation_set
token = tokens.pop();
foreach symbol in tokens
question_set.add(symbol)
// We now have a question_set = ['1','0']
// and tokens = [['+','-']['2','3']]
//
// Now we need to fill out the rest of the possible equations
foreach token in tokens
new_question_set = []
foreach symbol in token
foreach question in question_set
new_question_set.add(question + symbol)
question_set = new_question_set
我相信应该给我我想要的结果,但所有那些foreach让我相当紧张。我刚刚想出了这个算法,但我觉得我错过了一些明显的东西。我们正在搞乱组合,所以如果它非常慢,我不会感到惊讶,但感觉这并不特别。
干杯!
答案 0 :(得分:2)
如果需要创建所有组合,则必须执行某种嵌套循环。
确保您的迭代在row major order中执行(假设您的语言以行主要顺序存储您的集合,大多数但不是全部都是这样)。如果不这样做会对性能产生很大的影响。
答案 1 :(得分:0)
首先,我不会硬编码你的答案只有3层这样。相反,我建议使用递归。
如果递归变得过于毛茸茸并且你有堆栈溢出,那么你可以使用动态编程。
如果你不知道动态编程是什么,我怀疑你是否会被要求用它来解决这个问题。
就效率而言,无论如何,你都将具有指数时间复杂度。这是不可避免的,因为你也有一个指数级的大量输出。
答案 2 :(得分:0)
对于大型情况,易于编写的递归方法可能比使用计数器处理子集(标记)及其中的字符(符号)更快地导致问题。
对于tokensize 3(而不是2,如你的情况)和15个令牌(而不是3),下面的代码生成了大约10个结果字符串所需的列表(3 ** 15 = 14.348,907)在我不那么新的PC上秒。
如果这适合你,请试试(vb:我很快就在我正在处理的现有项目中写了它):
' decompose input
Dim allSubSets As New List(Of List(Of Char))
Dim subSet As List(Of Char) = Nothing
For Each c As Char In inputLine
Select Case c
Case "["c
subSet = New List(Of Char)
Case "]"c
allSubSets.Add(subSet)
Case ","c
' just skip
Case Else
subSet.Add(c)
End Select
Next
Dim numberOfSubSets As Integer = allSubSets.Count
Dim subSetLength As Integer = allSubSets(0).Count
Dim allResults As New List(Of String)
Dim caseArray(numberOfSubSets - 1) As Char
' 1st / initialize
Dim setIndex As Integer
Dim charIndexes As New List(Of Integer)
For setIndex = 0 To numberOfSubSets - 1
caseArray(setIndex) = allSubSets(setIndex)(0)
charIndexes.Add(0)
Next
Dim caseResult As New String(caseArray)
allResults.Add(caseResult)
Dim resultCount As Long = 1
' current position
setIndex = numberOfSubSets - 1
' do the others
Do
' if the current subSet is exhausted, track back (iteratively)
While (setIndex >= 0) AndAlso (charIndexes(setIndex) = subSetLength - 1)
' and restart the subset we're going the re-access later on
charIndexes(setIndex) = 0
setIndex -= 1
End While
' exit if we're done
If setIndex = -1 Then
Exit Do
End If
' increase counter in the current subset
charIndexes(setIndex) += 1
' fill the (remainder of the) case
While setIndex < numberOfSubSets
caseArray(setIndex) = allSubSets(setIndex)(charIndexes(setIndex))
setIndex += 1
End While
' correct the last increment
setIndex -= 1
' store result
caseResult = New String(caseArray)
allResults.Add(caseResult)
resultCount += 1
Loop
其中“inputLine”采用您指定的格式。 此外,如果您的令牌大小不同,则必须调整代码,以便使用正确的代码大小;我现在假设它们的长度都相同。
祝你好运!