C 我的打印最长回文子序列的程序是';t工作,当我运行它时,控制台窗口在接受输入后停止工作 #包括 #包括 国际人工智能,aj;//ai和aj分别存储i和j的值 intmaxx(inta,intb){//返回两个数字的最大值 return(a
您的程序失败,因为它使用自动存储分配了太多的数据(也称为堆栈上的数据)。C 我的打印最长回文子序列的程序是';t工作,当我运行它时,控制台窗口在接受输入后停止工作 #包括 #包括 国际人工智能,aj;//ai和aj分别存储i和j的值 intmaxx(inta,intb){//返回两个数字的最大值 return(a,c,algorithm,subsequence,C,Algorithm,Subsequence,您的程序失败,因为它使用自动存储分配了太多的数据(也称为堆栈上的数据)。int p[1000][1000]使用4MB,对于您的系统默认堆栈大小来说可能太多。您可以尝试通过以下方式分配此数组以减少空间使用: #include <stdio.h> #include <string.h> int ai, aj; // ai and aj to store the value of i and j respectively int max
int p[1000][1000]
使用4MB,对于您的系统默认堆栈大小来说可能太多。您可以尝试通过以下方式分配此数组以减少空间使用:
#include <stdio.h>
#include <string.h>
int ai, aj; // ai and aj to store the value of i and j respectively
int maxx(int a, int b) { // to return max of the two numbers
return (a <= b) ? b : a;
}
void LongestPal(char a[], int n) { // to find longest palindrome
int i, j, max = 0;
int p[1000][1000] = { 0 };
for (j = 0; j < n; j++)
for (i = 0; i <= j; i++) {
if (i == j) { // for one string having only one character
p[i][j] = 1;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
}
if (j == (i + 1)) { // for string having two characters
if (a[i] == a[j]) { // if the string is like "aa","bb" etc.
p[i][j] = 2;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
} else { // if string like "ab","ba" etc.
p[i][j] = 1;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
}
} else { // for all other type of strings
if (a[i] == a[j]) { // if a longer palindrome found
p[i][j] = p[i-1][j-1] + 2;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
} else { // if no longer palindrome is present
p[i][j] = maxx(p[i+1][j], p[i][j-1]);
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
}
}
}
}
int main() {
int i, j, n;
char a[1000];
printf("Just enter the string hoss!\n");
scanf("%s", &a);
n = strlen(a);
LongestPal(a, n);
for (i = ai; i <= aj; i++)
printf("%c", a[i]);
return 0;
}
这在C99中是允许的,但您的编译器可能不支持C99
您的算法有点复杂。为什么不枚举i
和j
的所有位置,然后使用辅助函数验证是否有回文,并跟踪最长的回文:
int p[n][n];
#包括
#包括
int isPalindrome(常量字符*a、int i、int j){
对于(;ii+maxj-maxi;j--){
if(isPalindrome(a,i,j)){
maxi=i;
maxj=j;
打破
}
}
}
*ai=最大值;
*aj=maxj;
}
内部主(空){
字符a[1000];
int i,j;
printf(“输入字符串:”);
如果(扫描频率(“%999s”,a)==1){
获取最长回文(a,strlen(a),&i,&j);
printf(“最长回文在%d..%d:%.*s\n”,i,j,j-i+1,a+i);
}
返回0;
}
你确定int p[1000][1000]={0};
对于你的堆栈来说不是太大吗?如果你将大小减小到,比如说,[10][10]
并提供足够小的输入,会发生什么?参考:scanf(“%s”,&a);
通过传递一个指向类型错误的对象的指针来调用未定义的行为。你应该使用scanf(“%999s”,a);
。这还包括读取长度限制,以防止缓冲区溢出。谢谢您的回答。实际上,您的程序查找回文,回文中必须有连续字符,而我的回文是针对任何相对位置的,不一定是连续的。您的程序的复杂性为O(n^3)(如果我没有错的话),我的回文是O(n^2)我的程序也是基于动态规划的。你的算法思想很棒!@bŗbȟmŗmŖpůpț:好吧,我没有完全分析你的算法,你可能应该给出回文子序列的定义来明确你的目标。我代码的时间复杂度确实是O(n^3),但是,IsPalindrome
很可能会很快返回。对于具有长重复序列的病理病例,实际的复杂性分析非常重要:我很难想象如何构造一个真正得到O(n^3)的序列。您的算法的复杂性为O(n^2)但是在时间和空间上。我的建议intp[n][n];
解决了这个问题吗?是的,我得到了,是的,我减小了数组大小
#include <stdio.h>
#include <string.h>
int isPalindrome(const char *a, int i, int j) {
for (; i < j; i++, j--) {
if (a[i] != a[j])
return 0;
}
return 1;
}
void getLongestPalindrome(const char *a, int n, int *ai, int *aj) {
int i, j, maxi, maxj;
for (maxi = maxj = i = 0; i < n; i++) {
for (j = n - 1; j > i + maxj - maxi; j--) {
if (isPalindrome(a, i, j)) {
maxi = i;
maxj = j;
break;
}
}
}
*ai = maxi;
*aj = maxj;
}
int main(void) {
char a[1000];
int i, j;
printf("Enter the string: ");
if (scanf("%999s", a) == 1) {
getLongestPalindrome(a, strlen(a), &i, &j);
printf("longest palindrome at %d..%d: %.*s\n", i, j, j - i + 1, a + i);
}
return 0;
}