題目:給定乙個陣列,問:這組數進行四則運算(每個數必須用到,且只用一次)可以得到多少個不同的值?
如何劃分:表示式是一步一步算的,劃分的方法就是哪個數先加入和表示式的當前值進行計算,並且有4種計算方式(其實是6種,減法和除法各2種順序)
def uniquevalues(a):
ans = set()
def dfs(i, value):
if i == len(a): ans.add(value)
else:
for j in xrange(i, len(a)):
a[i], a[j] = a[j], a[i]
if i == 0:
dfs(i + 1, value + a[i])
else:
dfs(i + 1, value + a[i])
dfs(i + 1, value - a[i])
dfs(i + 1, a[i] - value)
dfs(i + 1, value * a[i])
dfs(i + 1, value / a[i])
if value != 0: dfs(i + 1, a[i] / value)
a[i], a[j] = a[j], a[i]
dfs(0, 0)
return ans
題目2,給定乙個數的集合,列印所有可以生成的不同表示式
劃分:以最後進行的計算作為劃分,是乙個不相交且完備的劃分。分治法,以最後進行的計算為軸,把集合分成2組,遞迴求解兩邊邊的集合,然後組合最後的表示式集合。
cache = {}
def expressions(a):
if len(a) == 1: return [str(a[0])]
else:
a.sort()
key = tuple(a)
if key in cache.keys(): return cache[key]
left, right, ans = , ,
def group(i, leftcount, rightcount):
if i == len(a):
for exp1 in expressions(left):
for exp2 in expressions(right):
exp1 = exp1 if exp1.isdigit() or exp1[0] == '(' else '(' + exp1 + ')'
exp2 = exp2 if exp2.isdigit() or exp2[0] == '(' else '(' + exp2 + ')'
else:
if leftcount < len(a) - 1:
group(i + 1, leftcount + 1, rightcount)
left.pop()
if leftcount == 0: return
if rightcount < len(a) - 1:
group(i + 1, leftcount, rightcount + 1)
right.pop()
group(0, 0, 0)
cache[tuple(a)] = ans
return ans
做法2:不需要儲存,一般dfs,但是有重複,是正確結果的2倍
def expressions(a, i, exp):
if len(a) == i: print exp
else:
for j in xrange(i, len(a)):
a[i], a[j] = a[j], a[i]
if i == 0: expressions(a, i + 1, str(a[i]))
else:
for op in '+-*/': expressions(a, i + 1, '(' + exp + op + str(a[i]) +')')
expressions(a, i + 1, '(' + str(a[i]) + '-' + exp + ')')
expressions(a, i + 1, '(' + str(a[i]) + '/' + exp + ')')
a[i], a[j] = a[j], a[i]
題目3 給定一組數,新增操作符使得表示式值為給定target(類似的問法:新增操作符使得等式成立)
把表示式看做是term的和,term由factor組成。t是表示式最後乙個term,
def solve(a, i, v, t, target, e):
if i == len(a):
if v == target: print e
else:
if i == 0: solve(a, i + 1, a[i], a[i], target, str(a[i]))
else:
solve(a, i + 1, v + a[i], a[i], target, e + '+' + str(a[i]))
solve(a, i + 1, v - a[i], -a[i], target, e + '-' + str(a[i]))
solve(a, i + 1, v - t + t * a[i], f * a[i], target, e + '*' + str(a[i]))
if a[i] != 0: solve(a, i + 1, v - t + t / a[i], f / a[i], target, e + '/' + str(a[i]))
題目4 給定一組數,列印可以構造的所有表示式,數的順序不能變,和題目2類似,差別就是順序不能變
def all_exp(a, l, r):
if l == r: yield str(a[l])
else:
for pivot in xrange(l, r):
for left in all_exp(a, l, pivot):
for right in all_exp(a, pivot + 1, r):
for op in '+-*/':
yield '(' + left + op + right + ')'
分治法一般需要儲存子問題的結果,這裡用generaor
括號生成問題
括號生成需要出現成對的括號 有效的括號 例如 給出n 3,則生成的結果是 給定n的值,左邊的括號 數量一定會小於n,當然右邊的括號 數量也一定小於n,左邊的值加一,則列印乙個 右邊的值加一,列印乙個 當左括號和右括號的數量等於n時,那就列印所有的括號。上圖的黑線是第一次列印的呼叫,知道列印 然後綠線...
python生成表示式
python的語法比較隨意,為了簡潔有許多生成表示式 如 列表生成表示式 list i for i in range 10 加判斷 list i for i in range 10 if i 2 0 多層迴圈 list i for in range 10 for j in range i 一般大公司...
三元表示式,生成式,生成器表示式
使用函式來寫 defmax2 x,y if x y return x else return y res max2 3,4 print res 4?使用三元表示式 x 3 y 4 res x if x y else y print res 3,4 4 函式加三元表示式 defmax2 x,y ret...