實現自然數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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從1到n的全排列(深度優先搜尋)
- 從基礎講全排列(Java實現)Java
- 計算2的N次冪n 可輸入,n為自然數
- 全排列的實現之遞迴版與迭代版遞迴
- 實現將10個整數升序排列
- 全排列價值(數學問題)
- 字串全排列字串
- 字母排列(python實現)Python
- 藍橋杯之帶分數(全排列+暴力)
- 數字自然資源領域的實現路徑
- 有重複元素的全排列
- 2014省賽---六角填數(填空)(全排列)
- Leetcode——46. 全排列LeetCode
- leetcode:全排列(java回溯)LeetCodeJava
- LeetCode系列46—全排列LeetCode
- 全排列演算法演算法
- 演算法——全排列演算法
- 【LeetCode】46. 全排列LeetCode
- LeetCode-046-全排列LeetCode
- 【leetcode】60. Permutation Sequence 全排列的第k位序的排列形式LeetCode
- Day 28 | 491.遞增子序列 、46.全排列、 47.全排列 II
- 遞迴-*全排列問題遞迴
- 【Algorithm】全排列演算法Go演算法
- JavaScript陣列元素全排列JavaScript陣列
- LeetCode-047-全排列 IILeetCode
- CSS3實現文字垂直排列CSSS3
- Python語言的全排列怎麼提速?Python
- Bailian2732 求自然常數e的近似值(精確到n)【迭代】AI
- 全排列及相關擴充套件演算法(二)——求字典序下一組排列及全排列演算法套件演算法
- 數之重排列
- js陣列全排列問題JS陣列
- 藍橋杯全排列專題
- 位右移 字母大小寫全排列
- DOM 和 Canvas 如何實現文字豎向排列的效果Canvas
- 前端電商 sku 的全排列演算法前端演算法
- 回溯法(排列樹)解決八(N)皇后問題
- 遞迴演算法實踐---實現排列組合遞迴演算法
- 遞迴解決全排列問題遞迴
- HTMl中標籤中li橫向排列的實現示例HTML