题目要求:找到一个字符串中的一个连续子串,这个子串内不能有任何两个字符是相同的,并且这个子串是符合要求的最长的。

例如: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 发布


posted on 2011-05-11 22:56  微型葡萄  阅读(2512)  评论(0编辑  收藏  举报