面试题 字符串专题---转载
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; }#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);
}
- char *GetSameSubStr(char *str)
- {
- assert(str!=NULL);
- char *slow,*fast,ch,*substr;
- int count=0,max=0;
- slow=fast=str;
- while(*fast!=0)
- {
- if(*fast==*slow)
- {
- count++;
- fast++;
- }
- else
- {
- if(max<count)
- {
- ch=*slow;
- max=count;
- }
- slow=fast;
- count=0;
- }
- if (*fast==0)//例如字符串为"mdd"的情况
- {
- if(max<count)
- {
- ch=*slow;
- max=count;
- }
- break;
- }
- }//end while
- if(max==0)//如果为空串
- {
- substr=(char *)malloc(sizeof(char));
- *substr=0;
- }
- else
- {
- substr=(char *)malloc(sizeof(char)*(max+1));
- memset(substr,ch,max);
- substr[max]=0;
- }
- return substr;
- }
最大公共字串分为两类,一类是我们大家所熟知的两个字符串的最大公共子串,另一个是我在搜索中发现的就是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
- #include<iostream>
- using namespace std;
- #include<assert.h>
- void Permutation(char* pStr, char* pBegin)
- {
- assert(pStr && pBegin);
- if(*pBegin == '\0')
- printf("%s\n",pStr);
- else
- {
- for(char* pCh = pBegin; *pCh != '\0'; pCh++)
- {
- swap(*pBegin,*pCh);
- Permutation(pStr, pBegin+1);
- swap(*pBegin,*pCh);
- }
- }
- }
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
浙公网安备 33010602011771号