[动态规划经典之二]求字符串的最长不重复子串(连续子序列)
2011-05-11 22:56
375 查看
题目要求:找到一个字符串中的一个连续子串,这个子串内不能有任何两个字符是相同的,并且这个子串是符合要求的最长的。
例如:abcdeab,这个字符串有很多不重复子串,比如:abcde, bcdea, cdeab都是不重复子串,而且都是最长的。
这个是一个经典的笔试题,百度也曾经出过。
下面是代码:(注:由于我的代码本来目的是只求出长度即可,所以只保留了最后一个最长串的结果;如果想求得所有最长的不重复子串,即把所有可能都列出来,则需要再遍历一遍数组或者把所有结果保存下来,需要对代码作修改)
PS:我在代码中用了hash_map,估计要比较新版的VC才支持,我不知道GCC或者G++需要把命名空间改为什么,请读者自行修改代码。
#include <iostream>
#include <string>
#include <hash_map>
using namespace std;
using namespace stdext;
//acronym : LNS
pair<string, size_t> longest_norepeat_substring( string& str )
{
hash_map<char, int> char_index;//save the character and last postion it appears
size_t currentStart = 0;//start position of the LNS
size_t repeated_postion = 0;//the last postion of the repeated character
size_t maxLength = 0;//max length of the LNS
size_t curLength = 0;//current LNS length
size_t finalStart = 0;
//O(N) traverse
for( size_t i = 0 ; i < str.size() ; i++ )
{
if( char_index.find( str[i] ) != char_index.end() ) //repeated character
{
char repeatChar = str[i];
//if the repeated position is behind the current start position
//change the current start postion of LNS
repeated_postion = char_index[repeatChar];
if( repeated_postion + 1 > currentStart )
currentStart = repeated_postion + 1;
//also change the current LNS length
curLength = i - currentStart + 1;
//update the last appearance of the repeated character
char_index[repeatChar] = i;
}
else//not repeated character
{
char_index.insert( pair<char, int>( str[i], i ) );
curLength++;
//update the max LNS length
if( curLength > maxLength )
maxLength = curLength;
//remember the start position of final result
finalStart = currentStart;
}
}
return pair<string, size_t>( str.substr( finalStart, maxLength ), maxLength );
}
下面是测试的例子:
int main()
{
string str = "abcdeab";
cout<<longest_norepeat_substring( str ).first<<endl;
cout<<longest_norepeat_substring( str ).second<<endl;
string s = "happybirthdayob";
cout<<longest_norepeat_substring( s ).first<<endl;
cout<<longest_norepeat_substring( s ).second<<endl;
}
附:这里有一个CSDN的讨论:
http://topic.csdn.net/u/20090726/22/8b3f9f3a-5bad-4035-abd8-46b2231e83b0.html
通过 Wiz 发布
例如:abcdeab,这个字符串有很多不重复子串,比如:abcde, bcdea, cdeab都是不重复子串,而且都是最长的。
这个是一个经典的笔试题,百度也曾经出过。
下面是代码:(注:由于我的代码本来目的是只求出长度即可,所以只保留了最后一个最长串的结果;如果想求得所有最长的不重复子串,即把所有可能都列出来,则需要再遍历一遍数组或者把所有结果保存下来,需要对代码作修改)
PS:我在代码中用了hash_map,估计要比较新版的VC才支持,我不知道GCC或者G++需要把命名空间改为什么,请读者自行修改代码。
#include <iostream>
#include <string>
#include <hash_map>
using namespace std;
using namespace stdext;
//acronym : LNS
pair<string, size_t> longest_norepeat_substring( string& str )
{
hash_map<char, int> char_index;//save the character and last postion it appears
size_t currentStart = 0;//start position of the LNS
size_t repeated_postion = 0;//the last postion of the repeated character
size_t maxLength = 0;//max length of the LNS
size_t curLength = 0;//current LNS length
size_t finalStart = 0;
//O(N) traverse
for( size_t i = 0 ; i < str.size() ; i++ )
{
if( char_index.find( str[i] ) != char_index.end() ) //repeated character
{
char repeatChar = str[i];
//if the repeated position is behind the current start position
//change the current start postion of LNS
repeated_postion = char_index[repeatChar];
if( repeated_postion + 1 > currentStart )
currentStart = repeated_postion + 1;
//also change the current LNS length
curLength = i - currentStart + 1;
//update the last appearance of the repeated character
char_index[repeatChar] = i;
}
else//not repeated character
{
char_index.insert( pair<char, int>( str[i], i ) );
curLength++;
//update the max LNS length
if( curLength > maxLength )
maxLength = curLength;
//remember the start position of final result
finalStart = currentStart;
}
}
return pair<string, size_t>( str.substr( finalStart, maxLength ), maxLength );
}
下面是测试的例子:
int main()
{
string str = "abcdeab";
cout<<longest_norepeat_substring( str ).first<<endl;
cout<<longest_norepeat_substring( str ).second<<endl;
string s = "happybirthdayob";
cout<<longest_norepeat_substring( s ).first<<endl;
cout<<longest_norepeat_substring( s ).second<<endl;
}
附:这里有一个CSDN的讨论:
http://topic.csdn.net/u/20090726/22/8b3f9f3a-5bad-4035-abd8-46b2231e83b0.html
通过 Wiz 发布
相关文章推荐
- 经典字符串算法 “最长上升子序列,最大连续子序列和,最长公共子串”
- 找工作知识储备---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- ] 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 字符串空格替换、合法括号序列判断、最长无重复子串长度
- 【C】动态规划--最大连续子序列和/最长不下降子序列/最长公共子序列/最长回文子串/DAG最长路
- 最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 利用后缀数组求字符串的最长重复子串的算法 利用二维数组求两个字符串的最长公共字串(动态规划)
- 动态规划——最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串最小编辑距离日记整理
- 动态规划 - 最长公共子序列 - 最长公共子串 - 最长不重复子串 - 最长递增子序列 - 最长回文子串
- 算法题目二:寻找最长重复子序列(4) 求给定字符串重复最长的子串
- 动态规划之最长递增子序列 最长不重复子串 最长公共子序列
- 如何求最长连续公共子序列和最长连续子字符串