一道递归问题

题目大意是:给定一个字符串A,然后给定多个单词,然后根据给定的单词在字符串中插入空格,求插入空格最少的组合。例如给定字符串ilikeeverything,给定单词i、like、every、thing、likeeverything。输出为i likeeverything。

#include <iostream> #include <vector> #include <set> #include <map> #include <string> #include<algorithm> #include<functional> using namespace std; string result; int mincount=1000; int count1 = 0; bool flag = false; //注意递归里面最好不要有全局变量,如果返回,注意保存有上次的值。如果想把本次的值传递到下一次递归, //完全可以利用参数传值传递,而且返回后,值不变(变化的注意复原)。(我只是在结束条件满足时获得值即可,中间的值我又不需知道) //local:当前查找的起始位置 //resulttemp:暂存结果,因为会有多个解。 //blanknum:插入的空格数量 //str:要插入空格的字符串 //dict:字典(放入的是多个字符串) void mincut(int local,string resulttemp,int blanknum,const string& str, const set<string>& dict) { //从起点开始子串依次增长 for (int i = 1; i <= str.size()-local; i++) { string strtemp = str.substr(local, i); if (dict.find(strtemp) != dict.end())//找到 { //先保存找到的子串 resulttemp += strtemp; resulttemp += ' '; blanknum++; local = local + i; if (local >= str.size())//判断此次是否符合结束条件,符合就接收最后的解 { if (blanknum < mincount)//判断是否是更好的解 { flag = true;//只要有一个解,最终就会有解 mincount = blanknum; result = resulttemp; // cout << result << endl; } } else//不符合结束条件,就继续 { mincut(local, resulttemp, blanknum, str, dict); local = local - i;//复原,开始下次循环,注意。 blanknum--; resulttemp.erase(local, resulttemp.size() - local); } } } } int main(int argc, const char * argv[]) { string strS="aababa"; set<string> dict; result.clear(); dict.insert("a"); dict.insert("aa"); dict.insert("aaa"); dict.insert("b"); string resulttemp; int blanknum = 0; mincut(0, resulttemp, blanknum, strS, dict); if (flag) cout << result << endl; else cout << "不存在" << endl; system("pause"); return 0; }

注意递归的结束条件,本题使用的方法相当于深度优先搜索,一次查找结束的条件是下次查找的起始位置超出字符串的个数。

特别注意递归后的代码如何写(想下递归返回后自己想要干什么,对于本题我的解法相当于深度优先搜索,所以递归返回后会走另一条路,所以还原一些需要用到的变量)


另一道题是:给定一个字符串A,另外给一个字符串B,问A能组合出多少个B?(A中相对顺序要一致)

例:A:asdad  B:asd 输出结果为2

#include <iostream> #include <vector> #include <set> #include <map> #include <string> #include<algorithm> #include<functional> using namespace std; int numcount = 0; void mincut(int strlocal,int dictlocal, const string str, const string dict) { if (dictlocal == dict.size()) { numcount++; return; } if (strlocal == str.size()) return; for (int i = strlocal; i < str.size(); i++) { if (str[i] == dict[dictlocal])//找到一个 { mincut(i+1, dictlocal+1, str, dict); } } } int main(int argc, const char * argv[]) { string strS; string dict; while (cin>>strS>>dict) { numcount = 0; mincut(0, 0, strS, dict); cout << numcount << endl; } system("pause"); return 0; }

此程序修改的最上面的代码,最上面的代码可以照着下面的修改下,传入变量类似这样写

mincut(i+1, dictlocal+1, str, dict),这样就不用还原i及dictlocal了。

点赞