之前一直沒怎麼重視這一塊,理解也是半知半解,現在想想還是得好好記下。
一.增量構造法
什麼意思呢,簡單來說就是把乙個乙個元素放進去又拿出來的過程
先上**
//ass集合的陣列下面借用一張圖,思路很清晰//num子集的陣列
//n 集合的元素的個數
//cur 初始為0,代表著子集的元素的個數
void print_subset(int n, int *num, int
cur)
cout
<
int st = cur ? num[cur - 1]+1 : 0;//
選擇最小的未被選擇的集合的乙個元素
for (int i = st; i < n; i++)
}
注意:這裡的1 2 3 4表示的是集合的下標,不是元素的值
跟著演算法的思路走一遍:
一開始,我們的子集為空,所以不需要輸出,然後我們現在的子集元素個數cur為0,然後 我們拿 目前的 未被用到的 最小號元素放進去 子集,
ok,目前的狀態是子集裡面已經有了0號元素,保持這個狀態我們接著往下走,
現在,我們的子集裡面已經有了0號元素,可以輸出0號,目前我們的子集元素個數cur為1,然後我們拿 目前的 未被用到的 最小號元素放進去 子集
ok,目前的狀態是子集裡面有了1號元素,保持這個狀態我們接著往下走
………………………………以此類推,直到遇到第乙個邊界,也就是num[cur]==3 的時候,我們的集合的元素的個數只有4個,所以輸出目前的子集後我們直接返回走,
目前我們回到了num[cur==2 ]=2的狀態,開始進入下乙個迴圈,
ok,此時我們的num[cur==2]=3,也就是說本來num[2]==2此時被代替成了3,這樣子目前 子集就是 0 1 3,以此類推
這樣我們的結果就是
0 10 1 2
0 1 2 3
0 1 3
0 20 2 3
0 31 2
1 2 3
1 32 3
二.位向量法
其實就是 放和不放 所得到的各種情況
例如 我目前的 集合的元素為 1 2 3 4 5
那我先拿出第乙個元素 1
那我的子集要不要這個元素呢?有要和不要兩種情況
那目前就有了兩個子集 : 第乙個子集 為 空
第二個子集 為 1
再拿出第二個元素 2:
那我的子集要不要這個元素呢?有要和不要兩種情況,而第乙個元素 1 要和不要也有兩種情況,於是目前就有了四種情況
那目前就有了四個子集: 第乙個子集為空
第二個子集為 1
第三個子集為 2
第四個子集為 1 2
以此類推,我們就會得到所有子集的情況
下面給出**:
#includeusing三 . 二進位制法namespace
std;
//ass集合的元素
//num子集的陣列
//n 集合的元素的個數
//cur 初始為0,代表著集合元素的下標
void print_subset(int n, int *num, int
cur)
}cout
<
return
; }
num[cur] = 1;//
要ass[cur]這個元素
print_subset(n, num, cur + 1
); num[cur] = 0;//
不要ass[cur]這個元素
print_subset(n, num, cur + 1
);}
這個應該是最難懂的,需要先學習二進位制的概念和各種位運算子,不然沒必要往下看
如果你已經懂了,那接著往下說。
要知道,二進位制中,只有 1 和 0 兩個數字,那我們就把 1代表有這個元素,0代表沒有這個元素
假如我們的集合為
那麼子集用二進位制表示就是這樣
001 010 011 100 101 110 111 如此,我們知道有9種情況
這代表著什麼呢?
(它的代表是反向的)
例如 001代表著 有 7 這個元素 ,沒有 8 和 9 元素 ,
101代表著 有7和 9元素,沒有 8元素
1 1 1 代表著全部都有
那好,我們知道它是怎麼代表的,那又有什麼用呢?
接著往下看:
首先我們要知道集合元素的個數,這裡假設為 n
那我們再看這樣乙個式子 (1什麼意思呢?我們知道陣列是從0開始的,比如我們的集合有3個元素,放在陣列裡面,它們的下標就是 0 1 2
那麼我們可以知道n==3,所以我們 (1那麼我們接下來不斷的讓 111 減去 001也就是 十進位制的 1 ,那麼就有了 110 101 011 010 001 000
所以,下面給出列舉的**:
//ass集合的元素
//n 集合的元素的個數
void print_subset(int n,int *ass)
}cout
<
}
列舉子集的幾種方法
程式設計挑戰競賽上156頁說了列舉組合和子集的幾種方法,我覺得挺好的,收藏一下 都是利用二進位制數的模型來進行列舉子集或者組合 下面列舉集合都是在二進位制位上進行列舉。列舉k個數的子集 void eunmset int k 用k個二進位制位數列舉k個狀態 當k等於3時,即eunmset 3 輸出 0...
構造子集的三種方法
包含空集 來自紫書 的所有子集 增量構造法 rujia liu include pragma warning disable 4996 using namespace std void print subset int n,int a,int cur int a 10 int main 的所有子集 ...
三種方法 2020 11 23
利用連線類,例項化得到連線物件 連線類 連線物件 new 連線類 cmd.executescalar cmd.excutereader 關注其中一條資料 物件名.read 獲取關注列所對應的值 console.writeline 物件名 name while 物件名.read 功能,聚焦下一行資料。...