Lexicographically Next Permutation คือ Permutation (การเรียงสับเปลี่ยน) ที่มาถัดไปในลำดับ Dictionary Order (Lexicographical Order) ใน C++ มีฟังก์ชันสำเร็จรูป std::next_permutation ใน Header <algorithm>
ลายเซ็น
template <class BidirIt>
bool next_permutation(BidirIt first, BidirIt last);
template <class BidirIt, class Compare>
bool next_permutation(BidirIt first, BidirIt last, Compare comp);
- คืน
trueหากมี Permutation ถัดไป (และแก้ไข Range ให้เป็น Permutation ถัดไป) - คืน
falseหากอยู่ที่ Permutation สุดท้ายแล้ว (Descending Order) และ Reset Range ให้เป็น Permutation แรก (Ascending Order) - ต้องการ Bidirectional Iterator (Array, Vector, List, String, Deque)
ตัวอย่างพื้นฐาน
#include <iostream>
#include <algorithm>
#include <string>
int main() {
std::string s = "DBAC";
std::cout << "All permutations of " << s << ":\n";
// ต้อง Sort ก่อนเพื่อเริ่มจาก Permutation แรก
std::sort(s.begin(), s.end()); // "ABCD"
do {
std::cout << s << '\n';
} while (std::next_permutation(s.begin(), s.end()));
return 0;
}
ผลลัพธ์
ABCD
ABDC
ACBD
ACDB
ADBC
ADCB
BACD
BADC
BCAD
BCDA
BDAC
BDCA
CABD
CADB
CBAD
CBDA
CDAB
CDBA
DABC
DACB
DBAC
DBCA
DCAB
DCBA
การใช้งานแบบไม่ Sort ก่อน (จากสถานะปัจจุบัน)
std::string s = "DBAC";
for (int i = 0; i < 5; ++i) {
bool has_next = std::next_permutation(s.begin(), s.end());
if (!has_next) {
std::cout << "No next permutation (at: " << s << ")\n";
break;
}
std::cout << "Next: " << s << '\n';
}
// Output:
// Next: DBCA
// Next: DCAB
// Next: DCBA
// No next permutation (at: ABCD) <- Reset ไปที่ First
อัลกอริทึมเบื้องหลัง (How it Works)
- หา Pivot: Index
iสุดท้ายที่s[i] < s[i+1](Scan จากขวา) - หา Successor: Index
jสุดท้ายที่s[j] > s[i] - Swap
s[i]และs[j] - Reverse Sub-range
[i+1, end)
Complexity: O(N) Amortized
ฟังก์ชันคู่: prev_permutation
หา Permutation ก่อนหน้า (Previous) ทำงานกลับกัน
การประยุกต์ใช้
- Generate All Permutations สำหรับ Brute-force Search
- Combinatorial Algorithms (TSP, Scheduling)
- Next Lexicographical String/Number
- Testing: Generate Test Cases ทุก Combination
ข้อระวัง
- ต้อง
#include <algorithm> - Container ต้องรองรับ Bidirectional Iterator (ไม่รองรับ
forward_list) - หากมี Duplicate Elements จะสร้าง Permutation ซ้ำ (ใช้
std::uniqueกรองได้) - สำหรับ String ต้องเป็น Mutable (Non-const)
สรุป
std::next_permutation เป็นเครื่องมือมาตรฐานที่มีประสิทธิภาพสำหรับการ Generate Permutation ตามลำดับ Lexicographical ใช้งานง่ายด้วย Iterator Pattern เข้าใจอัลกอริทึมเบื้องหลังช่วย Debug และประยุกต์ต่อได้