C++ 中的回文分区
假设我们有一个输入字符串,将该字符串进行分区为回文分区,其中分区的每一个子串都是回文。在本节中,我们必须找出对给定字符串进行回文分区所需的最小切割次数。因此,如果字符串类似于“ababbbabbababa”,则进行回文分区所需的最小切割次数为 3 次。回文有:a | babbbab | b | ababa
为了解决这个问题,我们将遵循以下这些步骤 −
- n := 字符串长度
- 定义一个切割矩阵和一个回文矩阵,每个矩阵的顺序都是 n x n
- 对于 i := 0 到 n 执行以下操作:
- pal[i, i] := true and cut[i, i] := 0
- 对于 len 在范围 2 到 n 执行以下操作:
- 对于 i 在范围 0 到 n - len 执行以下操作:
- j := i + len – 1
- 如果 len = 2,则:
- 如果 str[i] = str[j],则 pal[i, j] := true
- 否则,当 str[i] = str[j] 且 pal[i+1, j-1] ≠ 0 时,pal[i, j] := true
- 如果 pal[i, j] 为真,则 cut[i, j] := 0
- 否则
- cut[i, j] := ∞
- 对于 k 在范围 i 到 j-1 执行以下操作:
- cut[i, j] := cut[i, j] 与 (cut[i, k]+ cut[k+1, j+1]+1) 的最小值
- 对于 i 在范围 0 到 n - len 执行以下操作:
- 返回 cut[0, n-1]
示例
让我们查看以下实现,以便更好地理解 −
#include <iostream> #include <climits> using namespace std; int min (int a, int b){ return (a < b)? a : b; } int minPalPartion(string str){ int n = str.size(); int cut[n][n]; bool pal[n][n]; //true when palindrome present for i to j th element for (int i=0; i<n; i++){ pal[i][i] = true; //substring of length 1 is plaindrome cut[i][i] = 0; } for (int len=2; len<=n; len++){ for (int i=0; i<n-len+1; i++){//find all substrings of length len int j = i+len-1; // Set ending index if (len == 2) //for two character string pal[i][j] = (str[i] == str[j]); else //for string of more than two characters pal[i][j] = (str[i] == str[j]) && pal[i+1][j-1]; if (pal[i][j] == true) cut[i][j] = 0; else{ cut[i][j] = INT_MAX; //initially set as infinity for (int k=i; k<=j-1; k++) cut[i][j] = min(cut[i][j], cut[i][k] + cut[k+1][j]+1); } } } return cut[0][n-1]; } int main(){ string str= "ababbbabbababa"; cout << "Min cuts for Palindrome Partitioning is: "<<minPalPartion(str); }
输入
ababbbabbababa
输出
Min cuts for Palindrome Partitioning is: 3
广告