如何不用循環和條件語句列印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&
template&
struct Test
{
static bool Do()
{
if (Storage&
return Test&
}
};
template&
struct Test&
{
static bool Do()
{
return true;
}
};
template&
struct Print
{
static void Do()
{
cout &<&< Storage&
Print&
}
};
template&
struct Print&
{
static void Do()
{
cout &<&< endl;
}
};
template&
struct Enumerate
{
static void Do()
{
if (Test&
{
Storage&
Enumerate&
}
Enumerate&
}
};
template&
struct Enumerate&
{
static void Do()
{
}
};
template&
struct Enumerate&
{
static void Do()
{
Print&
}
};
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 10var 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&
{
result_out&
printf("%d", for_out[N-1]);
}
template&<&> void result_out&<0&>()
{
//nothing
}
template&
{
const static int Value = N*factorial&
};
template&<&> struct factorial&<1&>
{
const static int Value = 1;
};
template&
{
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&
{
for_out[a-1] = v;
fill&(v);
}
template&<&> void fill&<1&>(int v)
{
for_out[0] = v;
}
void main()
{
fill&
fill&
result_out&
printf("
");
for_x = for_y = NUMBER_ONE - 1;
combinator&
}
void fif(bool cond, std::function&
{
std::function&
fun[static_cast&
}
void ffor(int i, int limit, int step, std::function&
{
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 naivemain = 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個互不相同的因數乘積?