搜索+枚举字符串子串问题
来源:互联网 发布:snmp开源软件 编辑:程序博客网 时间:2024/06/05 20:09
求字符串的子串问题有两类,一种是不连续,一种是连续。
然而这两种都可以用暴力求解,不过容易 time limited exceed;
那可以只用两个for循环就get全部子串吗?
求不连续的子串:用DFS(深度优先搜索)
这里看一个题 HD 1015 Safecracker
这个题大意就是 在给出的5-12个字符里面找到字典序最大的子串(不连续),子串字符数目是5个,且子串满足公式
v - w^2 + x^3 - y^4 + z^5 = target (target由输入给出)
这个题要遍历所有的子串,如果一个一个找的话,要用5个for循环,如果更多呢?显然用暴力行不通。
那试试深度优先搜索(其实是递归的思想):
<span style="font-size:12px;"> #include <stdio.h> #include <iostream> #include <string.h> #include <math.h> #define ma 15 using namespace std; int len,num[30],bj[30]; char in[ma],ans[ma],t[ma]; int n; void work(int k){ int sum,i; if(k==5){ sum=num[t[0]-'A']-pow(num[t[1]-'A'],2)+pow(num[t[2]-'A'],3)-pow(num[t[3]-'A'],4)+pow(num[t[4]-'A'],5); if(sum==n&&strcmp(t,ans)>0) strcpy(ans,t); return; } for(i=0;i<len;i++){ if(!bj[in[i]-'A']){ //这里要用in[i]-'A',避免重复 t[k]=in[i]; bj[in[i]-'A']=1; work(k+1); //这里是核心,k不能写成k++,否则在回溯之后,k就不是递归之前的值了 bj[in[i]-'A']=0;//标记之后要复原 } } } int main(){ for(int i=0;i<26;i++) num[i]=i+1;while(scanf("%d %s",&n,in)!=EOF){ if(n==0||strcmp(in,"END")==0) return 0; memset(bj,0,sizeof(bj)); memset(ans,'\0',sizeof(ans)); memset(t,'\0',sizeof(t)); len=strlen(in); work(0); if(strlen(ans)==0) printf("no solution\n"); else printf("%s\n",ans); } return 0; }</span>
这个题是输出一个解,杭电有另一个题要求输出多个解,就要在主函数多加一个for循环。有兴趣可以练练手。
HD 1016 Prime Ring Problem
代码可以参考这个链接 :点击打开链接
求连续的子串:调用函数substr
substr函数在头文件#include<string>里面
要调用substr函数,定义字符串也要用string 定义。
substr函数:
string s,j;
j=s.substr(i,j); //从i的位置开始找长度为j的子串,赋给字符串j
杭电有个题可以练练手:HD 1238 Substring
题意大概是给定n个字符串,找到这n个字符串的最长子串(连续),输出最长子串的长度
上代码:
#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#define ma 105using namespace std;string a[ma];int main(){ int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int mi=ma,bj; for(int i=0; i<n; i++) { cin>>a[i]; if(a[i].size()<mi) { mi=a[i].size(); bj=i; } } int sum=0; for(int i=a[bj].size()-1; i>0; i--) //子串的长度,从最长的开始找 { for(int j=0; j<=a[bj].size()-i; j++) //用substr找子串的开始位置 { string aa,bb; aa=a[bj].substr(j,i); bb=aa; reverse(bb.begin(),bb.end()); //reverse也是string头文件的函数,把字符串逆置 int k; for(k=0; k<n; k++) { if(a[k].find(aa)==a[k].npos&&a[k].find(bb)==a[k].npos)//表示没有找到与目标字符串相同的 break; } if(k==n&&sum<aa.size()) sum=aa.size(); } } printf("%d\n",sum); } return 0;}
1 0
- 搜索+枚举字符串子串问题
- 字符串搜索、搜索子串 rangeOfString方法
- Java 中字符串的子串搜索
- 字符串的(暴力)枚举连续子串1
- 字符串的(暴力)枚举连续子串2
- strpos子字符串搜索函数
- 字符串匹配-基于子串的搜索方法
- 在字符串中搜索子字符串
- 字符串中最大子串问题
- 面试训练字符串子串问题
- 字符串重复子串数目问题
- 字符串中最长子串的问题
- hdu5672 找字符串的子串问题
- 最长字符串回文子串问题
- 字符串的最长回文子串问题
- 字符串的子串问题详解
- 子字符串问题
- Java子字符串问题
- linux热插拔
- IOS第9天控制器的使用
- 数组中重复的数字
- GetDeviceCaps WinAPI
- Ftp服务器搭建
- 搜索+枚举字符串子串问题
- Android图片下载缓存库picasso解析
- 贝叶斯分类算法值贝叶斯网络
- git菜鸟教程
- maven简单配置
- jQuery easyUI combotree和combobox使用实例
- 160802
- 二维数组的小秘密
- Caused by: java.sql.SQLException: 无效的列类型: 16 及oracle 方言选择问题。