ในปัญหานี้ เราได้รับสตริงขนาด n และเราต้องพิมพ์การเรียงสับเปลี่ยนพาลินโดรมที่เป็นไปได้ทั้งหมด ที่สามารถสร้างได้โดยใช้อักขระของสตริงตามลำดับตัวอักษร หากไม่ได้สร้าง palindrome โดยใช้สตริงการพิมพ์ '-1'
มาดูตัวอย่างเพื่อทำความเข้าใจหัวข้อกันดีกว่า −
Input: string = “abcba” Output : abcba bacba
เพื่อแก้ปัญหานี้ เราจำเป็นต้องค้นหาพาลินโดรมทั้งหมดที่เป็นไปได้ แล้วจัดเรียงตามลำดับตัวอักษร (ลำดับศัพท์) หรืออีกวิธีหนึ่งอาจเป็นการหา palindrome แรกที่ใช้ศัพท์ศัพท์เฉพาะซึ่งทำจากสตริง จากนั้นให้หาพาลินโดรมถัดไปตามลำดับ
สำหรับสิ่งนี้ เราจะทำตามขั้นตอนต่อไปนี้ -
ขั้นตอนที่ 1 − เก็บความถี่ของการเกิดขึ้นของอักขระทั้งหมดของสตริง
ขั้นตอนที่ 2 − ตอนนี้ ให้ตรวจสอบว่าสตริงสามารถสร้างพาลินโดรมได้หรือไม่ หากไม่มีการพิมพ์ "ไม่สามารถสร้าง palindrome ได้" และออก มิฉะนั้น ให้ทำ -
ขั้นตอนที่ 3 − สร้างสตริงตามตรรกะที่อักขระทั้งหมดที่มีเหตุการณ์คู่กันสร้างสตริงและเหตุการณ์แปลก ๆ จากผู้อื่น และเราจะประกบสตริงคี่ระหว่างสตริงคู่ (เช่น ในรูปแบบคู่_สตริง +คี่_สตริง +คู่_สตริง)
เมื่อใช้สิ่งนี้ เราสามารถค้นหา palindrome ที่เป็นศัพท์เฉพาะได้ จากนั้นค้นหารายการถัดไปโดยตรวจสอบการใช้คำศัพท์ร่วมกัน
ตัวอย่าง
โปรแกรมเพื่อแสดงแนวคิด -
#include <iostream> #include <string.h> using namespace std; const char MAX_CHAR = 26; void countFreq(char str[], int freq[], int n){ for (int i = 0; i < n; i++) freq[str[i] - 'a']++; } bool canMakePalindrome(int freq[], int n){ int count_odd = 0; for (int i = 0; i < 26; i++) if (freq[i] % 2 != 0) count_odd++; if (n % 2 == 0) { if (count_odd > 0) return false; else return true; } if (count_odd != 1) return false; return true; } bool isPalimdrome(char str[], int n){ int freq[26] = { 0 }; countFreq(str, freq, n); if (!canMakePalindrome(freq, n)) return false; char odd_char; for (int i = 0; i < 26; i++) { if (freq[i] % 2 != 0) { freq[i]--; odd_char = (char)(i + 'a'); break; } } int front_index = 0, rear_index = n - 1; for (int i = 0; i < 26; i++) { if (freq[i] != 0) { char ch = (char)(i + 'a'); for (int j = 1; j <= freq[i] / 2; j++) { str[front_index++] = ch; str[rear_index--] = ch; } } } if (front_index == rear_index) str[front_index] = odd_char; return true; } void reverse(char str[], int i, int j){ while (i < j) { swap(str[i], str[j]); i++; j--; } } bool nextPalindrome(char str[], int n){ if (n <= 3) return false; int mid = n / 2 - 1; int i, j; for (i = mid - 1; i >= 0; i--) if (str[i] < str[i + 1]) break; if (i < 0) return false; int smallest = i + 1; for (j = i + 2; j <= mid; j++) if (str[j] > str[i] && str[j] < str[smallest]) smallest = j; swap(str[i], str[smallest]); swap(str[n - i - 1], str[n - smallest - 1]); reverse(str, i + 1, mid); if (n % 2 == 0) reverse(str, mid + 1, n - i - 2); else reverse(str, mid + 2, n - i - 2); return true; } void printAllPalindromes(char str[], int n){ if (!(isPalimdrome(str, n))) { cout<<"-1"; return; } do { cout<<str<<endl; } while (nextPalindrome(str, n)); } int main(){ char str[] = "abccba"; int n = strlen(str); cout<<”The list of palindromes possible is :\n”; printAllPalindromes(str, n); return 0; }
ผลลัพธ์
รายการพาลินโดรมที่เป็นไปได้คือ −
abccba acbbca baccab bcaacb cabbac cbaabc