如何不用循環和條件語句列印1到N(假設N為4,排列數就為256)的全排列?

列印格式:每個組合一行,列印語句不能用printf("%d,%d,%d.........")這樣的方法,即要適用於任何的N值。

三目運算符也不能用。

下面是我的寫法,不過是失敗的。

#include &
using namespace std;
int count=0;
int arr[4]={0,0,0,0};
void print4(int num){
arr[3]=num;
if(num&>4)
return;
printf("%d %d %d %d
",arr[0],arr[1],arr[2],arr[3]);
print4(num+1);
}
void print3(int num){
arr[2]=num;
print4(1);
if(num&>=4)
return;
else{
arr[2]=++num;
print3(num);
}
}
void print2(int num){
arr[1]=num;
print3(1);
if(num&>=4)
return;
else{
arr[1]=++num;
print2(num);
}
}
void print1(int num){
print2(1);
if(num&>=4)
return;
else{
arr[0]=++num;
print1(num);
}
}
void print(){
arr[0]=1;
print1(1);
}
int main(int argc,char **argv){
print();
return 0;
}


N是常數的話用模板元編程可破,寫起來差不多(只要你把bug修了),就是把所有的函數寫到了同一個函數里。

題外話,本來想把Storage也做成template而不用變數的,這樣所有的if都可以幹掉了,後來覺得實在是麻煩到爆炸了,算了……你們拿來當習題吧

#include &
using namespace std;

template&
struct Storage
{
static int Numbers[N];
};

template&
int Storage&::Numbers[N];

template&
struct Test
{
static bool Do()
{
if (Storage&::Numbers[Index] == Current) return false;
return Test&::Do();
}
};

template&
struct Test&
{
static bool Do()
{
return true;
}
};

template&
struct Print
{
static void Do()
{
cout &<&< Storage&::Numbers[Index] + 1;
Print&::Do();
}
};

template&
struct Print&
{
static void Do()
{
cout &<&< endl; } }; template&
struct Enumerate
{
static void Do()
{
if (Test&::Do())
{
Storage&::Numbers[Index] = Current;
Enumerate&::Do();
}
Enumerate&::Do();
}
};

template&
struct Enumerate&
{
static void Do()
{
}
};

template&
struct Enumerate&
{
static void Do()
{
Print&::Do();
}
};

int main(int argc, _TCHAR* argv[])
{
Enumerate&<4&>::Do();
return 0;
}


嗯,這麼說,我想到了一個不同的思路。雖然對內存的需求太大,但不是不可以啊。

將每一行視為一個n進位,有n位的數

這樣的話,這道題就被簡化為了,列印從0到n^n-1的全部n進位數。當然,列印的時候每一位的取值範圍是1~n而不是對於正常n進位數的0~(n-1)

舉例來說,如果是十進位的話,原始數據是023,你就要列印1 3 4

原始數據是999,你就要列印 10 10 10

var printAll = function (n) {
var total = pow(n, n) - 1;
printLine(total, n);
};

var printLine = function (current, n) {
try {
var array = [];
populateArray(current, n, n - 1, array); // 創建有N個元素的數組
console.log(array.toString()); // 列印該數組
current / current; // 相當於if (current == 0) return;
printLine(current - 1, n); // 循環調用
} catch {
}
};

var populateArray = function(current, n, iteration, array) {
try {
array.push(current / pow(n, iteration) % n + 1);
iteration / iteration; // 相當於if (iteration == 0) return;
populateArray(current, n, iteration - 1, array); //循環調用
} catch {
}
};

// 主調用入口
printAll(N);

不考慮幾乎是一定會出現的棧溢出(最大棧深度是n^n,因為不讓用循環么……),這個方法其實沒問題啊!!!!

另外因為不讓用if而且javascript不自帶assert所以pre condition的判斷沒法寫了。前提條件應該是n &> 0。


樓主啊,你的膝蓋我就不收了。我給你一個威力加強版的,生成所有的組合。

#include &
#include &
#define NUMBER_ONE 3
#define NUMBER_ZERO 2
#define NUMBER_TOTAL (NUMBER_ZERO+NUMBER_ONE)
int for_out[NUMBER_TOTAL];
int for_i, for_x, for_y;
template& void result_out()
{
result_out&();
printf("%d", for_out[N-1]);
}

template&<&> void result_out&<0&>()
{
//nothing
}
template& struct factorial
{
const static int Value = N*factorial&::Value;
};
template&<&> struct factorial&<1&>
{
const static int Value = 1;
};
template& void combinator()
{
for_out[for_x] = 0;
for_out[for_y] = 1;
for_out[0] = for_out[for_x + 1];
for_out[for_x + 1] = 1;
for_x = 1 + (for_x) *(1 - (for_out[1])*(1 - for_out[0]));
for_y = for_out[0] * (for_y + 1);
result_out&();
printf("
");
combinator&();
}
template&<&> void combinator&<1&>()
{
//stop
}
template& void fill(int v)
{
for_out[a-1] = v;
fill&(v);
}
template&<&> void fill&<1&>(int v)
{
for_out[0] = v;
}
void main()
{
fill&(0);
fill&(1);
result_out&();
printf("
");
for_x = for_y = NUMBER_ONE - 1;
combinator&::Value / (factorial&::Value*factorial&::Value)&>();
}


void fif(bool cond, std::function& funfalse, std::function& funtrue)
{
std::function& fun[2] = { funfalse, funtrue };
fun[static_cast&(cond)]();
}
void ffor(int i, int limit, int step, std::function& fun)
{
fun(i);
fif(i == limit, [=]{ffor(i + step, limit, step, fun); } , []{});
}

沒了輪子咱就造呀~嘿喲嘿喲嘿喲嘿~


函數式可用

先佔坑想想→_→

========

我還以為不能重複。。。

========

條件語句不能用,其它形式的條件呢?

========

未經haskell正規訓練,見笑

main = printPermList (getFullPerm 4) where

getFullPerm n = getPerm n n

getPerm n x
| x == 0 = [[]]
| otherwise = [ prev ++ [last] | prev &<- (getPerm n (x-1)), last &<- [1..n] ] printPermList ls = mapM_ putStrLn (map (foldl (s t -&> s ++ (show t) ++ " ") "") ls)

======

我把條件去掉了

main = printPermList (getFullPerm 4) where

printPermList ls = mapM_ putStrLn (map (foldl (s t -&> s ++ (show t) ++ " ") "") ls)

getFullPerm n = head (drop n resList) where
resList = [[]]:(map (putBack n) resList)

putBack n ls = [ prev ++ [last] | prev &<- ls, last &<- [1..n]]

======

我還是too naive

main = printPermList (getFullPerm 4) where

printPermList ls = mapM_ putStrLn (map (foldl (s t -&> s ++ (show t) ++ " ") "") ls)

getFullPerm n = sequence $ replicate n [1..n]


Python大法好!

Whole = range(4)
def Poi(Array):
S = filter(lambda X: X not in Array, Whole)
M = map(lambda Arr, Num: Arr+[Num,], [Array,]*len(S), S)
M2 = map(Poi, M)
return M2 or Array
def Duang(Array):
Y = reduce(lambda A, x: A.extend(x) or A, Array)
return (isinstance(Y[0][0], list) and Duang(Y)) or Y
def Nico(Array):
return "%s "*len(Array)%tuple(Array)
RES = map(Nico, Duang(map(Duang, Poi([]))))
print "%s
"*len(RES)%tuple(RES)

列表展開保平安

拋出錯誤這個比較蛇精病還是別用了( ̄▽ ̄")

=====================原來的答案================

嘛既然不能循環我們來遞歸

既然不能if……我們還有try啊~~

def Atom(array1, array2, point = 0):
try:
b = 3/(point-len(array1))
array2.append(array1[point])
array1.pop(point)
next(array1[:], array2[:])
array1 = array1[:point]+[array2[-1], ]+array1[point:]
array2.pop()
point+=1
Atom(array1[:], array2[:], point)
except ZeroDivisionError:
raise
def next(array1, array2):
try:
Atom(array1[:], array2[:])
except KeyboardInterrupt:
raise
except ZeroDivisionError:
try:
b = 3/len(array1)
except ZeroDivisionError:
print ("%s "*len(array2))%tuple(array2)

next(range(3),[])


next_permutation


提供個思路,一個是遞歸,循環能做的遞歸都能做.

還有一個,不能用if,但沒說不能判斷邏輯吧?

typedef void(*T_Func)();

T_Func Funcs[2];

代入你想判斷的函數到Funcs[0]和[1].

然後你就可以歡快的:

Funcs[a&>b];//成立嗎?


if不也是條件語句嗎?


遞歸?


推薦閱讀:

演算法漸進複雜度,怎麼證明logn!= θ(nlogn)?
這個號稱「微軟的面試題」,該如何解答?
如何對1TB的數組進行排序?
如何清晰的理解演算法中的時間複雜度?
如何將一個[10^3,10^15]上的整數儘可能多地表示成n個互不相同的因數乘積?

TAG:編程 | CC | 演算法設計 |