ACAG 0x02-8非再帰的コンビナトリアル
それは再帰的に最も基本的な実現をマシンから学んだ感じているので、この質問は、特にブログを書く理由は、あります。
主なもの2つの命令- コールとのRet。
コール命令は、その後にジャンプし、アドレス・スタック(スタックシステム)を返します\(アドレス\)文の位置。
RET命令が復帰命令(リターン)、スタックからの戻りアドレスであり、継続する位置にジャンプします。
要約すると、あなたが実現非再帰型列挙の組み合わせを得ることができます。
#include<bits/stdc++.h>
using namespace std;
int n,m,top,address;
int sta[100010];
vector <int> v;
void Call(int x,int ret_addr) {
int old_top=top;
sta[++top]=x;
sta[++top]=ret_addr;
sta[++top]=old_top;
return;
}
int Ret() {
int ret_addr=sta[top-1];
top=sta[top];
return ret_addr;
}
void Recursive() {
Call(1,0);
while(top) {
int x=sta[top-2];
switch(address) {
case 0:
if(v.size()>m||v.size()+(n-x+1)<m) {
address=Ret();
continue;
}
if(x==n+1) {
for(int i=0;i<v.size();i++) {
printf("%d ",v[i]);
}
printf("\n");
address=Ret();
continue;
}
v.push_back(x);
Call(x+1,1);
address=0;
continue;
case 1:
v.pop_back();
Call(x+1,2);
address=0;
continue;
case 2:
address=Ret();
continue;
}
}
return;
}
int main()
{
scanf("%d%d",&n,&m);
Recursive();
return 0;
}