我陷入困境,似乎无法弄清楚我应该从哪里开始。 我很感激有关如何处理这个问题的任何提示或提示。一直试图弄清楚超过9小时没有运气。
问题如下:
如果字符串s向前和向后读取相同的字符串,则称其为回文字符。 s的分解是s的一组非重叠子串,其串联是s。
编写一个C ++程序,它将字符串作为输入并计算其所有的字符串 - 原子分解。例如。如果s是字符串0204451881那么 分解020,44 5 1881是回文分解。
是的0 2 0 4 4 5 1 8 8 1
0 2 0 4 4 5 1 88 1
0 2 0 4 4 5 1881
0 2 0 44 5 1 8 8 1
0 2 0 44 5 1 88 1
020 4 4 5 1 8 8 1
020 4 4 5 1 88 1
020 4 4 5 1881
020 44 5 1 8 8 1
020 44 5 1 88 1
020 44 5 1881
这是一个班级项目。
到目前为止,我有:#include <iostream>
#include <string>
using namespace std;
void palDecom(string str1);
bool isPal(const string &str);
void subPal(string str1);
int main()
{
string s = "0204451881";
palDecom(s);
subPal(s);
return 0;
}
//shows the decomposition as the single char of the string
//takes a string as input
void palDecom(string str1)
{
int stringLastIndex = (str1.length());
for (int i = 0; i < stringLastIndex; i++)
{
cout<< str1[i] <<" ";
}
cout<<endl;
}
void subPal(string str1)
{
int stringLastIndex = (str1.length());
for (int curIndx = 0; curIndx < stringLastIndex; curIndx++)
{
for(int comparIndx = 1; comparIndx < stringLastIndex; comparIndx++)
{
//cout<< "i was in this loop"<<endl;
if (isPalindrome((str1,curIndx,comparIndx)))
//cout<<str1.substr(0,curIndx-1)<<" "<< str1.substr(curIndx,comparIndx) <<" "<< str1.substr(comparIndx,stringLastIndex)<<endl;
}
}
}
bool isPal(const string &str)
{
int start=0, end=str.length()-1;
while (start < end) {
if (str[start++] != str[end--])
return false;
}
return true;
}
答案 0 :(得分:2)
实际上,我才意识到这一点:
这意味着每个回文将&#34;分裂&#34;根据多少&#34;层数和#34;进入额外的子回文它拥有的回文。
例如:序列
当你解析字符串时,可能性会增加一个较大的可以分解的回文量,直到你有1个字符宽度的回文。
当然,我意识到回文可以重叠:
这是一个额外的窘境,但绝对是可以解决的。
就我个人而言,我认为这一思路将导致一种更好的算法和解决方法,因为在一个方向上迭代时组成新的回文可能比在一个方向上分解它们更容易。
我认为最好的方法是开始玩回文并绘制可能的分解。通过分析,您应该能够找到一个可以映射到递归解决方案的重复模式
我希望我有一个更确定的答案,但我自己正在努力解决这个问题。我希望其他人可以编辑这个并获取线程吗?
答案 1 :(得分:1)
使用递归通过从左到右扫描字符串来解决此问题。
保留一堆已经在整个字符串中“当前位置”“左侧”找到的先前回文分区。该堆栈可以是指向每个先前找到的回文的末端(即 - 超过最后一个字符的一个)的指针的数组或std ::向量。在这种情况下,“当前位置”由堆栈的顶部元素指示,或者如果堆栈为空则指示字符串的开头。
递归的基本/退出情况是当前位置是指整个字符串的结尾。在那种情况下,你已经筋疲力尽了。按照回文堆栈(从底部开始)指示打印出回文,然后返回。 (提示:不要改变原始字符串以插入nul终止符以将每个回文打印为字符串。而是根据堆栈上的分区逐个字符地打印每个回文,在回文和新行之间打印空格堆栈的结尾。)
否则,有一个循环从1开始到从当前位置开始的字符串中剩余的字符数。在每次迭代时,测试当前位置是否是长度等于循环索引的回文。如果它是这样的回文,那么将该回文的分区推到堆栈上并递减到更深的一层。
应该这样做。
我不会使用std :: stack来实现堆栈。而是使用std :: vector或数组。如果你使用std :: vector,那么不要在递归中对它进行结构操作(例如 - push_back,pop_back等)。相反,只需调整它()以在开始递归之前保持strlen(str)分区元素,因为最深的堆栈将是字符串的每个字符都是回文。然后在递归中,您只需传递堆栈的逻辑当前大小。这将告诉您应该放置下一个回文分区的索引(即 - 索引大小),并允许您访问堆栈中任何先前存在的顶部元素(即 - 索引大小 - 1)。这种方法适用于数组或std :: vector。
如果你想使用std :: vector :: push_back()(或std :: stack),那么在每次递归返回后你只需要记住std :: vector :: pop_back()。这种方法可以让你不需要明确地传递堆栈的“逻辑”大小,因为向量本身会知道它的正确大小。
答案 2 :(得分:0)
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <iomanip>
using std:: cin;
using std:: cout;
using std:: endl;
using std:: setw;
const int MAX_LEN = 100;
int palDecom(const char str[]);
bool isPal(const char str[], int start, int end);
int main()
{
char str[MAX_LEN];
cin >> setw(MAX_LEN) >> str;
cout << palDecom(str) ;
return EXIT_SUCCESS;
}
int palDecom(const char str[])
{
int counter=0;
for (int i = 1; i < strlen(str) ; i++)
for(int lastindex = strlen(str)-1; lastindex < strlen(str) ; lastindex--)
{
if(isPal(str, i , lastindex-1))
counter ++;
}
return counter;
}
bool isPal(const char str[], int start, int end)
{
if(start == strlen(str))
return 1;
if (str[start] == str[end]){
isPal(str, str[start], str[end-1]);
return true;
}
return false;
}