面试题 字符串专题---转载

http://blog.csdn.net/agwujiang/article/details/5829543

1、一道面试题:从一个字符串中找出第一个不重复字符

比如:
   abbbccdefafgg 其中d、e只出现一次,只需要找出d(第一个出现的不重复字符)即可

有什么最快的方法?

 

#include<stdio.h>

#include<string.h>
int num[26]={0};
int index[26]={0};
int main()
{
    char *s="aaedaa";
    int i;
    for(i=0;i<strlen(s);i++)
    {
        num[s[i]-'a']++;
        index[s[i]-'a']=i;
    }
    int min=strlen(s);
 
    for(i=0;i<26;i++)
        if(num[i]==1 && index[i]<min)
        {
            min=i;
        }
    printf("%c\n",min+'a');
    return 0;       
}
 
 
2、程序员面试题精选100题(36)-在字符串中删除特定的字符[算法]  
题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.””aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”

#include<stdio.h>
#include<string.h>
void delete_ch(char *src,char *del_chs)
{
     int hash[256];

     char *p_slow=src,*p_fast=src;

     int i;

     memset(hash,0,sizeof(int)*256);

    for(i=0;i<strlen(del_chs);i++)

           hash[del_chs[i]]=1;

    while(*p_fast)

    {

        if(hash[*p_fast]==1)

            *p_fast++;

        *p_slow++=*p_fast++;

    }

     *p_slow='\0';

}

main()
{
char src[]="They are students";
char del_chs[]="aeious";
delete_ch(src,del_chs);
printf("%s\n",src);
}

 

#include<stdio.h>
#include<string.h>
void delete_ch(char *src,char *del_chs)
{
int i;
char *p_slow=src,*p_fast=src;
int num[256]={0};
int index[256]={0};
for(i=0;i<strlen(del_chs);i++)
num[del_chs[i]-'a']++;
while(*p_fast)
{
if(num[*p_fast-'a']!=0)
*p_fast++;
*p_slow++=*p_fast++;
}
*p_slow='\0';
}
main()
{
char src[]="They are students";
char del_chs[]="aeious";
delete_ch(src,del_chs);
printf("%s\n",src);
}

 
例如:str ="sssddddabcdef" ,则输出字串为:dddd;例如:str ="ccdfff"  则输出字串为:fff。
#include<malloc.h>
  1. char *GetSameSubStr(char *str)  
  2. {  
  3.     assert(str!=NULL);  
  4.     char *slow,*fast,ch,*substr;  
  5.     int count=0,max=0;  
  6.   
  7.     slow=fast=str;  
  8.       
  9.     while(*fast!=0)  
  10.     {  
  11.         if(*fast==*slow)  
  12.         {  
  13.             count++;  
  14.             fast++;  
  15.         }  
  16.         else  
  17.         {             
  18.             if(max<count)  
  19.             {  
  20.                 ch=*slow;  
  21.                 max=count;  
  22.             }  
  23.             slow=fast;  
  24.             count=0;  
  25.         }  
  26.   
  27.         if (*fast==0)//例如字符串为"mdd"的情况  
  28.         {  
  29.             if(max<count)  
  30.             {  
  31.                 ch=*slow;  
  32.                 max=count;  
  33.             }  
  34.             break;  
  35.         }  
  36.     }//end while  
  37.     if(max==0)//如果为空串  
  38.     {  
  39.         substr=(char *)malloc(sizeof(char));  
  40.         *substr=0;  
  41.     }  
  42.     else  
  43.     {  
  44.         substr=(char *)malloc(sizeof(char)*(max+1));  
  45.         memset(substr,ch,max);  
  46.         substr[max]=0;  
  47.     }  
  48.     return substr;  
  49. }  

最大公共字串分为两类,一类是我们大家所熟知的两个字符串的最大公共子串,另一个是我在搜索中发现的就是N个字符串的最大公共字串问题。

首先来看两个字符串的最大公共字串问题。这里我列出了两种解法,第一种就是暴力解法,第二种是动态规划来解的。还有一种解法就是我们数据结构书上会讲到的

第一种:暴力解法(c语言实现的)

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
char * longest(char *a,char *b)
{
int i,j,max=0,count=0;
int start1,start2,start;
int alen=strlen(a);
int blen=strlen(b);
for(i=0;i<alen;i++)
{
for(j=0;j<blen;j++)
{
start1=i;
start2=j;
while(a[start1++]==b[start2++])
count++;
if(max<count)
{
max=count;
start=i;
}
count=0;
}
}
char *str=(char *)malloc(max+1);
strncpy(str,a+start,max);
str[max]='\0'; /*为什么str[max+1]='\0'*/

return str;

}
main()
{
char a[]="abcdabcdcbadffdaccccafg";
char b[]="gfaccccadffdabcdcbadcba";
char *str;
str=longest(a,b);
printf("%s\n",str);
free(str);
/* system("pause");*/  /* 函数的作用*/
return 0;
}

 

4.字符串查找并记录出现次数(普通与kmp)(观察strstr实现),替代

看下标准实现,实际上是还是用的force-brute方法,并没有使用kmp这类的算法。看下lynx里的strstr.c

int find_int_str(const char *str_source,const  char *str_child)

{

  int len_str_source=strlen(str_source);

  int  len_str_child=strlen(str_child);

  int i,j;

  for(i=0;i<len_str_source;i++)

  {

     if (*(str_source+i)==*str_child) 

     {

         for(j=0;j<len_str_child;j++)

             {

                if(*(str_source+i+j)!=*(str_child+i))

                   break;  //跳出的哪层循环??

             }

         if(j==len_str_child)

            count++;

     }

  }

return count;

}

5     输出字符串的所有组合,如"abc"输出a、b、c、ab、ac、bc、abc。

http://blog.csdn.net/hackbuteer1/article/details/7462447

  1. #include<iostream>  
  2. using namespace std;  
  3. #include<assert.h>  
  4.   
  5. void Permutation(char* pStr, char* pBegin)  
  6. {  
  7.     assert(pStr && pBegin);  
  8.   
  9.     if(*pBegin == '\0')  
  10.         printf("%s\n",pStr);  
  11.     else  
  12.     {  
  13.         for(char* pCh = pBegin; *pCh != '\0'; pCh++)  
  14.         {  
  15.             swap(*pBegin,*pCh);  
  16.             Permutation(pStr, pBegin+1);  
  17.             swap(*pBegin,*pCh);  
  18.         }  
  19.     }  
  20. }

6     根据条件找出两个数。

7     求数组(或环状数组)的最大连续(或不连续)子序列和。

8.给出一个函数来输出一个字符串的所有排列

我们固定第一个字符b,求后面的字符串ac的排列。然后将c和第一个

位置的a交换,得到cab,我们固定c,求后面的字符串ab的排列,很显然我们在交换a和c的时候,首先要将b和a换回来,也就是说在求每个子串的排列之后,

我们应该将之前交换的字符串换回来。在这里我们需要维护两个字符串指针,一个pStr表示字符串的排列,一个pBegin表示需要固定字符的指针位置。

#include <iostream>

using namespace std;

void Permutation(char* pStr, char* pBegin);

/////////////////////////////////////////////////////////////////////////
// Get the permutation of a string,
// for example, input string abc, its permutation is
// abc acb bac bca cba cab
/////////////////////////////////////////////////////////////////////////
void Permutation(char* pStr)
{
    Permutation(pStr, pStr);
}

/////////////////////////////////////////////////////////////////////////
// Print the permutation of a string,
// Input: pStr   - input string
//        pBegin - points to the begin char of string
//                 which we want to permutate in this recursion
/////////////////////////////////////////////////////////////////////////
void Permutation(char* pStr, char* pBegin)
{
    if(!pStr || !pBegin)
        return;

    // if pBegin points to the end of string,
    // this round of permutation is finished, 
    // print the permuted string
    if( *pBegin == '/0')
    {
        printf("%s/n", pStr);
    }
    // otherwise, permute string
    else
    {
        for(char* pCh = pBegin; *pCh != '/0'; ++ pCh)
        {
            // swap pCh and pBegin
            char temp = *pCh;
            *pCh = *pBegin;
            *pBegin = temp;

            Permutation(pStr, pBegin + 1);

            // restore pCh and pBegin
            temp = *pCh;
            *pCh = *pBegin;
            *pBegin = temp;
        }
    }
}

int main()
{
    char strTemp[10] = "1234";
    Permutation( strTemp );
    system( "pause" );
    return 0;
}

 

8.从一个字符串中找出第一个不重复字符

这个也比较简单,类似于5的方法。

9.去除字符串中相邻两个字符的重复

这个应该等价于题目5

10.判断字符串是否含有回文字符子串

枚举字符串的每个位置,作为回文串的中间位置(分偶数奇数两种情况),如果找到或者找不到都会立即停止,所以总的复杂度不超过O(n)

11.求最长回文子串

12. 字符串移位包含的问题

 给定两个字符串S1与S2,要求判定S2是否能够被通过s1作循环移位得到的字符串包含,例如,给定s1=AABCD与S2=CDAA,返回true;给s1=ABCD 与s2=ACBD

,返回false. 直接枚举匹配或者比较s2能否匹配s1s1,以第一个为例也就是说比较AABCDAABCD和CDAA。

 

13.strlen strcpy(注意重叠) 

看glibc的实现,可以发现strlen它进行了加速处理,每次前进多个字节,将字符串转化为unsigned long类型,然后利用位运算判断该long型数据是否含有0字节。

 

14.去掉中文中的英文字符   
主要根据字节的第一位进行判断。   
15.求一个字符串中连续出现次数最多的子串  
http://hi.baidu.com/charles_zhang/blog/item/147a948227390d98f603a6ca.html   
转载请注明出处:http://bbs.xjtu.edu.cn 兵马俑bbs-算法与数据结构版  作者phylips@bmy 

 

posted on 2014-09-07 15:02  小西红柿  阅读(207)  评论(0)    收藏  举报

导航