列印出 N 個元素集合
所有的子集合
在 N 個元素集合中所有的子集合共有 2N 個
例如:N = 3 集合的元素假設為 {0, 1, 2}
{}
{0}
{1}
{2}
{0, 1}
{0, 2}
{1, 2}
{0, 1, 2}
怎樣寫一個 C 程式來列印出這些子集合呢?
-
這個問題一眼看起來似乎沒那麼容易,
就算讓你用手去列出所有的子集合,
都需要一點功夫才能夠找到規則,
如果你要用程式來製作這些規則的話,
又需要一些功夫,
這是可行的,
不過就這個問題來說,
有一個較簡單的作法
-
剛剛學過二進位的數字表示法,
有沒有覺得 2N 個數字很熟悉呢?
讓我們看一下面 N=3 的 8 個二進位數字
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
和前面的 8 種子集合對照一下,
發現了什麼特性嗎?
這兩者之間有一對一的關係,
0 0 0 代表空集合,
1 0 1 代表 {0, 2} 的子集合,
也就是說如果二進位數字中第 3 位數字是 1 的話,
就表示子集合中包括第 3 個元素,
依此類推
-
所以要寫一個程式來列印 N 個元素集合的所有子集合的話,
我們可以寫一個迴圈,
把 0 到 2N-1 所有的數字一一列出,
然後把對應的二進位位元找到,
列印出原來集合中對應 1 的位元的那些元素就可以了。
程式要求:
-
你可以用陣列變數來記錄數字,
如此的話你必須自己製作加法,
才能夠把這組數字逐一加 1
-
你也可以用 C 語言中的整數來記錄數字,
如此的話你必須知道怎樣可以看到第幾個位元是 1 或是 0,
你可以用 bitwise 的邏輯運算來看,
也可以自己寫一個函式專門來看一個數字的二進位表示法中某一個位元是 1 或是 0
-
你需要注意 N 這個數值的大小,
一方面要留意在累加數字時 2N
很快就會超過整數能夠表達的範圍,
另一方面必須要注意所使用的陣列變數的大小必須足夠
-
如果需要的話,
你可以用 math.h 裡的 pow(x,y) 來計算 xy 的數值,
或是利用 1<<N 來計算 2N 的數值,
注意當 N 大於 16 時,
你必須要用 1L<<N 來計算 2N。
-
請儘量用函式來簡化邏輯,
執行速度暫時不用太在意,
當然你可以討論一下不同的 N 值大概需要多少時間。
-
-
請以 ANSI C 語法及函式庫來製作