跳到主要內容

[Java] UVa 10098 Generating Fast, Sorted Permutation

題目連結

題意:
每組測資給定一個字串(長度最多10),要按順序列出所有相異的 Permutation
所謂的 permutation 指的是某個字串的一種排序方式
組成相同,但順序不同

例如: 字串 ABC,他的 permutation 有:
ABC, ACB, BAC, BCA, CAB, CBA
總共會有3! (3階乘) = 6種

題目要求按照字母順序從頭到尾輸出
像是給定 BCA ,其 permutation 與上述的ABC相同

輸出如下:
ABC
ACB
BAC
BCA
CAB
CBA

解法:
解題關鍵就是要找到所有permutation
而且必須是按字母順序

在C++的STL當中
似乎有相關方法可以呼叫(next_permutation)
不過Java沒有
所以我們必須自行實作
觀察找出下一個 permutation 的規律

規律如下:
以ABCDE為例,原本字串是遞增的 (以ASCII來看)
我們的最終目標是遞減的EDCBA (也就是最後一個 permutation)

下面列出前幾個 permutation :

ABCDE - ABCED - ABDCE - ABDEC - ABECD - ABEDC - ACBDE - ...

首先思考一下,我們寫一個字串的時候
第一個位置有5個選擇,第二個位置有4個,依此類推...
加上要按順序寫,所以第一個permutation產生的理由是
第一個位置可以選A~E,選擇最前面的A
第二個位置可以選B~E,同理
最後得到ABCDE

第二個permutation,由於第五個位置已經沒得選了
回到第四個位置,原本可以選D~E,現在選擇E,最後還是只能選D
所以得到ABCED

再者,第四個位置DE都選過了
所以往前到第三個位置,選擇C的下一個順位 D
D選完後,第四個位置可以選CE,選擇C,最後E
所以得到ABDCE

依此類推...

過程中
連續選過的位置會形成遞減的情況
往前找到沒有遞減的字元
取得該字元下一個順位後
後面的字元再形成他們自己的第一個 permutation
也就是字元由小到大排序的結果
最後就得到該次 permutation

[程式實作]
每次從後往前檢查兩兩相鄰字元
以ABEDC為例,找到BE為遞增,代表E以後都選完了

讓B換下一個順位(跟C換位置)      [ABEDC → ACEDB]

後面的字元們則由小到大排序即可 [ACEDB → ACBDE]

所以下一個為ACBDE

程式(Java):

留言

這個網誌中的熱門文章

【Ubuntu】Terminal 複製貼上的方法

Ctrl C + Ctrl V 能使用嗎? 有常常透過Ubuntu在指令海裡摸索的一定不陌生 在Terminal裡我們不能用Ctrl C + Ctrl V來進行複製貼上的作業 每次都不小心Ctrl C下去,就要抱頭痛哭QQ (在Terminal裡面是呼叫一個外部中斷,強制中止當下系統的動作) 其實在Terminal當中也有複製貼上的功能 Ctrl + Shift + C 複製 Ctrl + Shift + V 貼上 功能相當於一般的複製貼上,也只是多按一個Shift,相信不是太難適應 如果是透過VirtualBox建立的Ubuntu 想要跟主機互通的話,可以參考這篇: [VirtualBox] 共用剪貼簿與檔案 另外,在Terminal裡也有所謂的暫存剪貼簿,是針對指令設計的 Ctrl + U 剪下游標前的字元到剪貼簿 Ctrl + K 剪下游標後的字元到剪貼簿 Ctrl + Y 貼上 所謂的游標就是打指令的那行閃爍的位置 所以其他畫面上系統輸出的文字不會受影響,才說是針對指令設計 這個暫存的剪貼簿也跟一般的是分開的,或許會有派上用場的一天吧!

【Ubuntu】關閉預設畫面自動鎖定

近期一直碰到一個小麻煩 在Ubuntu VM做研究時 因為平常會在本機Search,才去VM操作 卻發現每次畫面跳去Ubuntu那邊 都還要重新打密碼登入,很惱人 怒查之下,原來這個動作叫  畫面鎖定 反正VM就是個測試環境,根本不需要這些安全措施 透過下面步驟就可以取消了 甚至連開機登入時都可以不用打密碼了呵呵

[Java] HashMap資料結構簡介與用法

Java HashMap 官方文件: https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html import java.util.HashMap; 簡介: 以每個獨立的 key 對應一個 value 特性: 資料(K, V)原則上是一對一 key不能重複,若重複宣告,後者會取代前者 資料不會排序,預設是先宣告的在前面(呼叫整個 HashMap 的話) 用途: 建立對應表(轉換表),一 key 對一 value 像是學生成績表,以名字做為 key,查詢 key 可以得對應的成績 value 資料格式: HashMap<K,V> K: key V: value 用法: 1. 宣告 : 型別是 reference,不能存基本型別,像整數要寫 Integer 而非 int HashMap<String, String> hashmap = new HashMap<String, String>(); HashMap<String, String> hashmap = new HashMap<>(); HashMap<String, Integer> hashmap = new HashMap<>(); 2.新增資料 : 同時給Key-Value參數,新增這筆資料到該hashMap hashmap.put("Item 1", "Value 1"); hashmap.put("Item 1", 25); 3.刪除資料 : 根據參數Key刪掉對應的Key-Value資料 hashmap.remove("Item 1"); 4.取特定key對應的值 hashmap.get("Item 1"); 5.顯示整個HashMap內容 System.out.println("內容:" + hashmap); for(String Key: map.keySet()){ System.out.println(Key + " &