字符串的回文子串_计算回文子串的总数
字符串的回文子串Problem statement:问题陈述:Given a string str, find total number of possible palindromic sub-sequences. A substring need to be consecutive such that for any xixj i<j must be valid in the pa...
字符串的回文子串
Problem statement:
问题陈述:
Given a string str, find total number of possible palindromic sub-sequences. A substring need to be consecutive such that for any xixj i<j must be valid in the parent string too. Like "incl" is a substring of "includehelp" while "iel" is not.
给定字符串str ,找到可能的回文子序列的总数。 子字符串必须是连续的,以便对于任何x i x j i <j在父字符串中也必须有效。 像“ incl”一样,是“ includehelp”的子字符串,而“ iel”则不是。
Input:
输入:
The first line of input contains an integer T, denoting the no of test cases then T test cases follow. Each test case contains a string str.
输入的第一行包含一个整数T ,表示测试用例的数量,然后是T个测试用例。 每个测试用例都包含一个字符串str 。
Output:
输出:
For each test case output will be an integer denoting the total count of palindromic substring which could be formed from the string str.
对于每个测试用例,输出将是一个整数,表示可以从字符串str形成的回文子字符串的总数 。
Constraints:
限制条件:
1 <= T <= 100
1 <= length of string str <= 300
Example:
例:
Input:
test case:2
First test case:
Input string:
"aaaa"
Output:
Total count of palindromic substring is: 10
Second test case:
Input string:
"abaaba"
Output:
Total count of palindromic sub-sequence is: 11
Explanation:
说明:
Test case 1: Input: "aaaa"
测试案例1:输入:“ aaaa”
The valid palindromic sub-sequences are shown below:
有效的回文子序列如下所示:
Marked cells are character taken in subsequence:
标记的单元格是子序列中的字符:
So on...
等等...
Total 10 palindromic substrings.
总共10个回文子串。
Actually in this case since all the character is same each and every substring is palindrome here.
实际上,在这种情况下,由于所有字符都是相同的,每个子串在这里都是回文。
For the second test case,
对于第二个测试用例,
Few substrings can be,
"a"
"b"
"a"
"aba"
So on...
Total 11 such palindromic sub sequences
Solution approach
解决方法
This can be solved by using DP bottom up approach,
这可以通过使用DP自下而上的方法来解决,
-
Initialize dp[n][n] where n be the string length to 0 and a Boolean 2D array pal[n][n] to store whether the substrings are palindrome or not.
初始化dp [n] [n](其中n是字符串长度为0)和布尔2D数组pal [n] [n]来存储子字符串是否为回文。
-
Fill up the base case,
填满基本情况
Base case is that each single character is a palindrome itself. And for
基本情况是,每个字符本身都是回文。 而对于
length of two, i.e, if adjacent characters are found to be equal then [i][i+1]=3, pal[i][i+1]=true, else if characters are different then dp[i][i+1]=2, pal[i][i+1]=false
两个字符的长度 ,即,如果发现相邻字符相等,则[i] [i + 1] = 3 , pal [i] [i + 1] = true ,否则,如果字符不同,则dp [i] [i +1] = 2 , pal [i] [i + 1] = false
To understand this lets think of a string like "acaa"
要理解这一点,可以考虑一个字符串,例如“ acaa”
Here,
这里,
dp[0][1]=2 because there's only two palindrome possible because of "a" and "c".
dp [0] [1] = 2是因为“ a”和“ c”仅可能存在两个回文。
Whereas for
鉴于
dp[2][3] value will be 3 as possible substrings are "a", "a", "aa".
dp [2] [3]的值将为3,因为可能的子字符串为“ a”,“ a”,“ aa”。
for i=0 to n // for single length characters dp[i][i]=1;pal[i][i]=true if(i==n-1) break; if(s[i]==s[i+1]) dp[i][i+1]=3;,pal[i][i+1]=true else dp[i][i+1]=2,pal[i][i+1]=false; end if end for -
Compute for higher lengths,
计算更长的长度,
for len=3 to n for start=0 to n-len int end=start+len-1; // start and end is matching and rest of // substring is already palindrome if(s[end]==s[start] and pal[start+1][end-1]) // 1+subsequence from semaining part dp[start][end]=1+dp[start+1][end]+dp[start][end-1]-dp[start+1][end-1]; Pal[start][end]=true; else dp[start][end]=dp[start+1][end]+dp[start][end-1]-dp[start+1][end-1]; Pal[start][end]=false; end if end for end for -
Final result is stored in dp[0][n-1];
最终结果存储在dp [0] [n-1]中;
So for higher lengths if starting and ending index is same then we recur for the remaining characters, since we have the sub-problem result stored so we computed that. In case start and end index character are different then we have added dp[start+1][end] and dp[start][end-1] that's similar to recur for leaving starting index and recur for leaving end index. But it would compute dp[start+1][end-1] twice and that why we have deducted that.
因此,对于更大的长度,如果开始索引和结束索引相同,则将重复其余字符,因为我们存储了子问题结果,因此我们对其进行了计算。 如果起始索引和终止索引的字符不同,则我们添加了dp [start + 1] [end]和dp [start] [end-1] ,类似于recur离开起始索引和recur离开结束索引。 但是它将两次计算dp [start + 1] [end-1] ,这就是为什么我们要减去它。
For proper understanding you can compute the table by hand for the string "aaaa" to understand how it's working.
为了正确理解,您可以手动计算字符串“ aaaa”的表以了解其工作方式。
C++ Implementation:
C ++实现:
#include <bits/stdc++.h>
using namespace std;
int countPS(string s)
{
int n = s.length();
if (n == 0 || n == 1)
return n;
vector<vector<int> > dp(n);
vector<vector<bool> > pal(n);
for (int i = 0; i < n; i++) {
dp[i] = vector<int>(n);
pal[i] = vector<bool>(n);
}
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
pal[i][i] = true;
if (i == n - 1)
break;
if (s[i] == s[i + 1]) {
dp[i][i + 1] = 3;
pal[i][i + 1] = true;
}
else {
dp[i][i + 1] = 2;
pal[i][i + 1] = false;
}
}
for (int len = 3; len <= n; len++) {
for (int start = 0; start <= n - len; start++) {
int end = start + len - 1;
if (s[start] == s[end] && pal[start + 1][end - 1]) {
dp[start][end] = dp[start + 1][end] + dp[start][end - 1] - dp[start + 1][end - 1] + 1;
pal[start][end] = true;
}
else {
dp[start][end] = dp[start + 1][end] + dp[start][end - 1] - dp[start + 1][end - 1];
pal[start][end] = false;
}
}
}
return dp[0][n - 1];
}
int main()
{
int t;
cout << "Enter number of testcases\n";
cin >> t;
while (t--) {
string str;
cout << "Enter number of strings\n";
cin >> str;
cout << "Number of total palindromic substring is: " << countPS(str) << endl;
}
return 0;
}
Output:
输出:
Enter number of testcases
2
Enter number of strings
aaaa
Number of total palindromic substring is: 10
Enter number of strings
abaaba
Number of total palindromic substring is: 11
翻译自: https://www.includehelp.com/icp/count-total-number-of-palindromic-substrings.aspx
字符串的回文子串
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)