求字符串中相同且长度最长的字符串及其首字母的位置
来源:互联网 发布:js offsetleft属性 编辑:程序博客网 时间:2024/05/16 07:21
题目:输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它及首字符的位置。例如“yyabcdabjcabceg”,输出结果应该为abc和3。
解法1:
程序思想: 按照长度递减去寻找相同的子串,只要找到第一对相同的子串,则立刻退出程序。因为是按照长度递减的顺序去寻找子串,所以必定能找到最长的相同子串。
以abcab为例子分析如下:
首先寻找长度为4的子串,只能是abca和bcab,再查看这两个子串是否有其他相同的子串。有的话直接输出结果并退出程序。
然后寻找长度为3的子串,只能abc,bca,cab。这3个子串都没有其他相同的子串。
最后寻找长度为2的子串,首先是ab,用find函数返回在abcab中正序查找的位置0,用rfind函数返回在abcab中逆序查找的位置3。这两个位置不相等,说明在不同的位置存在相同的子串ab。直接输出ab:1,然后退出程序。
详细代码见《程序员面试宝典》(第三版) P226页 面试例题2
//求一个字符串中出现的相同且长度最长的字符串pair<string, int> func2(string str){string strTemp;int i, j;int iLen = str.length();for (i = 0; i < iLen; i++){for (j = iLen; j > 1; j--) //从每个后缀的最长子串开始{if (i + j <= iLen) //确保获取子串不会越界{size_t pos1, pos2;strTemp = str.substr(i, j);pos1 = str.find(strTemp);pos2 = str.rfind(strTemp);if (pos1 != pos2) //位置不一致则说明存在重复子串{return make_pair(strTemp, pos1 + 1);}}}}return make_pair("", -1);}
附:
这个题目存在一个歧义,例如如果测试字符串为aaaaaa,我一开始以为结果是长度为3的aaa,原来正确答案是长度为5的aaaaa。即2个等长的子串可以有部分字符重叠。因此,面试前最好问仔细点题目意图,免得自己把自己给坑了。
首先,这题的2个for循环中的那个if语句明显多于,这个if语句可以放到j的for循环中去, 即for(int j=0;j<str.length();j++)改为for(int j=0;j<=str.length()-i;j++)。
再者,书上给的程序有一个小bug,例如输入测试例子abba,没有任何输出结果,理论上应该输出a:1或者b:2。当测试例子为abca,也没有任何输出结果,理论上应该输出a:1。 这是因为寻找相同的子串时,程序忽略了长度为1的子串,当然这也可能是题目本意。如果不忽略长度为1的子串,直接修改i变量的下限,令for中的i>=1即可。
解法2:
这道题目和前面的面试例题1非常相似,因此两者的思想也相似,法二的代码也是在面试例题1的方法二的代码基础上稍作修改。
相同子串的首字符必定相等,因此依次遍历str的每个字符作为相等子串的首字符,然后在str中搜索与首字符相等的字符,然后从这两个相等的首字符开始,依次比较下一个字符是否相等,相等的话字符长度就会增加,直到下一个字符不等为止或者到了字符串的末尾。然后把这长度最大的值存放在maxlen中,最后返回长度最大的子串和起始字符的下标。
程序源代码如下,fun函数是书上的源代码,封装成函数形式,去掉if语句后j的范围优化为j<=len-i,同时i的下限变成i>=1,其他不变。fun1是法二的版本。
#include<iostream> #include<string> using namespace std; //书上的源代码,封装成函数形式,j的范围优化了一下,同时i的下限变成i>=1,其他不变 pair<int,string> fun(const string &str) { int count=0; string substr,tep; int i,j,len=str.length(); for(i=len-1;i>=1;--i){ for(j=0;j<=len-i;j++){ size_t t=0; size_t num=0; tep=str.substr(j,i); t=str.find(tep); num=str.rfind(tep); if(t!=num){ count=t+1; substr=tep; return make_pair(count,substr); } } } return make_pair(count,substr); } pair<int,string> fun1(const string& str) { int index=0; int maxlen=0; string substr; int i=0,j=0; int len=str.length(); int k=i+1; int s,lt; while(i<len){ j=str.find(str[i],k); //从(k~len-1)范围内寻找str[i] if(j==string::npos )//若找不到,说明(k~len-1)范围内没有str[i] { i++; k=i+1; }else{ //若找到,则必有(j>=i+1) s=i; lt=1; while(str[++s]==str[++j] && j<len){} lt=s-i; if(lt>maxlen) { maxlen=lt; substr=str.substr(i,lt); index=i+1; } k=j; }//else }//while return make_pair(index,substr); } int main() { string str; pair<int,string> rs; while(cin>>str) { rs=fun(str); cout<<rs.second<<":"<<rs.first<<endl; rs=fun1(str); cout<<rs.second<<":"<<rs.first<<endl; /*书上源代码 int count=0; string substr,tep; int i,j,len=str.length(); for(i=len-1;i>1;--i){ for(j=0;j<len;j++){ if(j+i<=len){ size_t t=0; size_t num=0; tep=str.substr(j,i); t=str.find(tep); num=str.rfind(tep); if(t!=num){ count=t+1; substr=tep; cout<<tep<<" : "<<t+1<<endl; return 0; } } } }*/ } return 0; }
- 求字符串中相同且长度最长的字符串及其首字母的位置
- (1452)找出字符串中出现的相同的且长度最长的字符串,输出它及其首字母的位置
- 求一个字符串中出现的相同且长度最长的字符串,及其首字符的位置
- 005求一个字符串中出现相同且长度最长的字符串,输出它及其首字符位置
- 字符串中出现的相同且长度最长的字符串
- 字符串中相同且长度最长的字符串
- 字符串中相同且长度最长的字符串
- 字符串中相同且长度最长的字符串
- 求一段字符串中出现的相同且长度最长的字符串
- 求一个字符串中出现相同且长度最长的字符串
- 输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它及其首字符的位置
- 输入一行字符串,找出其中出现的相同且长度最长的字符串,输出他及其首字符串位置
- 寻找相同且长度最长的字符串
- 字符串中相同的且长度最长的子串
- 字符串中出现相同且长度最长的子序列
- 输入一行字符串,找出出现的相同且长度最长的字符串,输出它及其首字母的置比如:“yyabcdagaerabceg”答案应该是abc
- 利用后缀数组找字符串中相同且长度最长的字符串
- 输入一行子串,找出其中出现的相同且长度最长的字符串,输出它及其首字符的位置
- CHARIOT,号称史上最牛X的网络吞吐量丢包测试工具,
- linux 目录结构
- 配置VS编写Spring.Net 和NHibernate的配置文件时,给出代码提示
- Python性能测试脚本-开源中国
- Swift学习——函数的使用和分类(四)
- 求字符串中相同且长度最长的字符串及其首字母的位置
- 【proguard 专题二】如何混淆jar2
- textread使用举例-matlab
- hdu Lawrence(DP-单调性优化-斜率优化)
- !@OSC本日推荐!淘宝性能采集工具-Tsar
- matlab中注释多行
- C# Winform程序经验之Form问题总结
- NOJ1093阶乘之和——n超过24不变
- VB2QTPApi_Binary.zip