Skip to content

Commit 9f5e904

Browse files
authored
Update report.md
1 parent 857978e commit 9f5e904

1 file changed

Lines changed: 39 additions & 36 deletions

File tree

homework1/report.md

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ int main()
118118
119119
## 解題說明
120120
121-
本題要求實現輸出集合 $S$ 的所有子集合,假設 $S = '{'a, b, c'}'$ 。
121+
本題要求實現輸出集合 $S$ 的所有子集合,假設 $S = {{a, b, c}}$ 。
122122
123123
### 解題策略
124124
@@ -128,8 +128,8 @@ int main()
128128
129129
### 解題範例
130130
131-
假設集合 $S = {a, b, c}$,其所有子集合為:
132-
${}, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}$
131+
假設集合 $S = {a, b, c}$,其所有子集合為:
132+
```{}, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}```
133133
共 $2^3 = 8$ 種子集合。
134134
135135
## 程式實作
@@ -138,26 +138,27 @@ ${}, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}$
138138
139139
```cpp
140140
#include <iostream>
141+
#include <cmath>
141142
using namespace std;
142-
int A(int m, int n)
143-
{
144-
if (m == 0)
145-
return n + 1;
146-
else if (n == 0)
147-
return A(m - 1, 1);
148-
else
149-
return A(m - 1, A(m, n - 1));
150-
}
151143
152-
int main()
153-
{
154-
int m, n, a;
155-
cout << "請輸入m:";
156-
cin >> m;
157-
cout << "請輸入n:";
158-
cin >> n;
159-
a = A(m, n);
160-
cout << "A = " << a;
144+
int main() {
145+
char S[] = { 'a', 'b', 'c' };
146+
int n = 3;
147+
int total = pow(2, n);
148+
149+
for (int i = 0; i < total; ++i) {
150+
cout << "{";
151+
bool first = true;
152+
for (int j = 0; j < n; ++j) {
153+
if (i & (1 << j)) {
154+
if (!first) cout << ", ";
155+
cout << S[j];
156+
first = false;
157+
}
158+
}
159+
cout << "}" << endl;
160+
}
161+
return 0;
161162
}
162163
```
163164

@@ -170,14 +171,16 @@ int main()
170171

171172
### 測試輸出
172173

173-
${}$
174-
${a}$
175-
${b}$
176-
${a, b}$
177-
${c}$
178-
${a, c}$
179-
${b, c}$
180-
${a, b, c}$
174+
```
175+
{}
176+
{a}
177+
{b}
178+
{a, b}
179+
{c}
180+
{a, c}
181+
{b, c}
182+
{a, b, c}
183+
```
181184

182185
### 結論
183186

@@ -191,12 +194,12 @@ ${a, b, c}$
191194

192195
在本程式中,使用遞迴來實現阿克曼函數的主要原因如下:
193196

194-
1. **程式邏輯簡單直觀**
195-
Ackermann 函數的遞迴寫法明確表達了「將問題拆解為更小的子問題」的核心概念。
196-
根據其數學定義,每一次呼叫 $A(m, n)$ 都會轉化為更簡單的子問題,直到遇到邊界條件 $m$ 為 $0$ 為止。
197+
1. **結構簡單、貼近子集的定義**
198+
遞迴自然符合「選擇與不選擇」的兩分策略,程式碼易於理解與實作。
197199

198-
2. **遞迴語意清楚、結構分明**
199-
每一次 $A(m, n)$ 的遞迴呼叫都代表著一個「子問題的解」,且其回傳值會逐層傳遞回原本的呼叫點,組合成最終結果
200-
這種設計讓程式結構簡潔,能夠清楚地追蹤問題的拆解與合併過程。
200+
2. **適合列舉所有組合情形**
201+
遞迴結構可完整走訪所有可能的子集合,不會遺漏也不重複
202+
201203

202-
本程式缺點主要表現在遞迴深度限制,當函數遞迴層數過深時,每一層的呼叫都會佔用一部分的記憶體(堆疊空間)。如果超出所允許的堆疊大小限制,就會發生Stack Overflow,導致程式中斷運行或崩潰。
204+
效能瓶頸:
205+
若集合元素超過 20 個,子集合數量達 $2^{20} = 1048576$,執行效率將明顯下降。

0 commit comments

Comments
 (0)