實現自然數N的全排列
今天同事問了一個問題,如何實現一個數N的全排列,也就是Pn。對於一個3來說,列印結果應該包括123、132、213、231、312、321。
當然還有一個小要求,不能使用遞迴演算法。其實演算法應該不復雜,不是遞迴就是迴圈。想了一下,覺得不難實現。
SQL其實最擅長這種類似笛卡兒的操作,下面是用SQL實現4個數的排列P4:
SQL> WITH A AS (SELECT ROWNUM ID FROM DUAL CONNECT BY LEVEL <= 4)
2 SELECT A.ID || B.ID || C.ID || D.ID
3 FROM A, A B, A C, A D
4 WHERE A.ID != B.ID
5 AND A.ID != C.ID
6 AND A.ID != D.ID
7 AND B.ID != C.ID
8 AND B.ID != D.ID
9 AND C.ID != D.ID;
A.ID||B.ID||C.ID||D.ID
---------------------------------------------------------------------
1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321
已選擇24行。
不過SQL實現固定值的排列結果和簡單,但是如果輸入引數是變數,那麼SQL就沒有辦法寫了,不過利用PL/SQL和SQL的配合還是很容易實現的,程式碼如下:
SQL> CREATE OR REPLACE FUNCTION F_TEST (P_IN NUMBER) RETURN SYS_REFCURSOR AS
2 V_STR VARCHAR2(32767);
3 V_RETURN SYS_REFCURSOR;
4 BEGIN
5 V_STR := 'WITH A AS (SELECT ROWNUM ID FROM DUAL CONNECT BY LEVEL <= ' || P_IN || ') SELECT ';
6 FOR I IN 1..P_IN LOOP
7 V_STR := V_STR || 'A' || I || '.ID || ';
8 END LOOP;
9 V_STR := RTRIM(V_STR, '| ') || ' FROM ';
10 FOR I IN 1..P_IN LOOP
11 V_STR := V_STR || 'A A' || I || ', ';
12 END LOOP;
13 V_STR := RTRIM(V_STR, ', ') || ' WHERE ';
14 FOR I IN 1..P_IN LOOP
15 FOR J IN I+1..P_IN LOOP
16 V_STR := V_STR || 'A' || I || '.ID != A' || J || '.ID AND ';
17 END LOOP;
18 END LOOP;
19 OPEN V_RETURN FOR SUBSTR(V_STR, 1, LENGTH(V_STR) - 4);
20 RETURN V_RETURN;
21 END;
22 /
函式已建立。
SQL> SELECT F_TEST(3) FROM DUAL;
F_TEST(3)
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
A1.ID||A2.ID||A3.ID
--------------------------------------------------------------------------------------------
321
231
312
132
213
123
已選擇6行。
當然,如果嚴謹一點,還應該對大於9和小於1的數進行輸入判斷,並對1進行單獨的處理,不過不到30分鐘的時間能實現到這樣已經比較滿意了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-553611/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java實現-全排列Java
- 字串全排列 java實現字串Java
- 全排列演算法的JS實現演算法JS
- 從基礎講全排列(Java實現)Java
- 【演算法】遞迴實現全排列演算法遞迴
- 計算2的N次冪n 可輸入,n為自然數
- Java實現全排列、組合演算法Java演算法
- 非1~2^n數列的自然數密碼《一》密碼
- 非1~2^n數列的自然數密碼《一A》密碼
- 非1~2^n數列的自然數密碼《二》密碼
- 非1~2^n數列的自然數密碼《二A》密碼
- 字串的全排列字串
- 全排列價值(數學問題)
- 實現將10個整數升序排列
- 非1~2^n數列的自然數密碼《一B》密碼
- 非1~2^n數列的自然數密碼《一C》密碼
- 非1~2^n數列的自然數密碼《二B》密碼
- 非1~2^n數列的自然數密碼《二C》密碼
- 非1~2^n數列的自然數密碼《二D》密碼
- 非1~2^n數列的自然數密碼《二E》密碼
- 尋找將1~N的整數隨機排列的高效方法隨機
- 生成{1,2,...,n}的排列的演算法-組合數學演算法
- 有重複元素的全排列
- 全排列演算法演算法
- 字母排列(python實現)Python
- 【Algorithm】全排列演算法Go演算法
- JavaScript陣列元素全排列JavaScript陣列
- 用q實現篩法求1-n的質數
- 前端電商 sku 的全排列演算法前端演算法
- 【leetcode】60. Permutation Sequence 全排列的第k位序的排列形式LeetCode
- 用sql實現的n王后SQL
- Leetcode——46. 全排列LeetCode
- 【LeetCode】46. 全排列LeetCode
- leetcode:全排列(java回溯)LeetCodeJava
- js陣列全排列問題JS陣列
- LeetCode系列46—全排列LeetCode
- LeetCode-046-全排列LeetCode
- CSS3實現文字垂直排列CSSS3