1. 程式人生 > >python練習例項1

python練習例項1

題目:有四個數字:1、2、3、4,能組成多少個互不相同且無重複數字的三位數?各是多少?

來看第一種解法

 1 num = [1, 2, 3, 4]
 2 """
 3 根據題中'互不相同'要求,建立一個集合(去重),存放三位數
 4 注意{}僅用於建立空字典!set()函式用來建立集合
 5 """
 6 s = set()
 7 # 遍歷整個列表三次,組成三位數
 8 for i in num:
 9     for j in num:
10         # 去掉與i重複的數字
11         if j !=i:
12             for k in num:
13
# 去掉與i,j重複的數字 14 if k != j and k != i: 15 n = 100*i + 10*j + k 16 # 注意集合新增元素的方法為add和update 17 s.add(n) 18 print("無重複的三位數個數:", len(s)) 19 print("分別是:", s)

這種解法時間複雜度為O(n2), 其中的列表可以換成range生成器

 1 s = set()
 2
# 遍歷整個列表三次,組成三位數 3 for i in range(1, 5): 4 for j in range(1, 5): 5 # 去掉與i重複的數字 6 if j !=i: 7 for k in range(1, 5): 8 # 去掉與i,j重複的數字 9 if k != j and k != i: 10 n = 100*i + 10*j + k 11 # 注意集合新增元素的方法為add和update
12 s.add(n) 13 print("無重複的三位數個數:", len(s)) 14 print("分別是:", s)

以上兩種解法都可以改成列表推導式的形式,如下,這種形式看上去簡潔,但如果出錯了排查起來比較困難,一般不推薦使用

lst = [100*i + 10*j + k for i in num for j in num for k in num if (i != j and j != k and k != i)]

第三種方法比較野路子,先確定最終數的範圍,然後一個一個判斷,當然這種效率是極低的

 1 s = set()
 2 # 縮小範圍,三位數肯定在123和433之間
 3 for i in range(123, 433):
 4     # 個位數字
 5     a = i%10
 6     # 十位數字
 7     b = (i%100)//10
 8     # 各位數字
 9     c = (i%1000)//100
10     if a != b and b != c and a != c and 0 < a < 5 and 0 < b < 5 and 0 < c < 5:
11         s.add(i)
12 print("無重複的三位數個數:", len(s))
13 print("分別是:", s)

第四種方法是運用python的內建函式permutations,其語法格式為:

permutations(iterable[, r]),返回一個長度為r的元組

程式碼如下:

from itertools import permutations
# permutations返回3位長度的元組,permutations意為交換
s = set()
for i in permutations([1, 2, 3, 4], 3):
    k = ''
    for j in range(0, len(i)):
        k = k + str(i[j])
    s.add(int(k))
print("無重複的三位數個數:", len(s))
print("分別是:", s)

總結

第一、二種方法比較接近,都是for迴圈巢狀加判斷求解,第三種方法比較另類,先判斷一個大致範圍再遍歷,第四種方法運用python內建的permutations函式直接生成包含3個數字的元組。綜合來看,第四種方法更簡潔