字符串是最常见的面试题目类型,应当分配最大的时间。
字符串本身很简单,但是相关的题目需要更复杂的算法来解决。比如说动态规划,搜索,等等。
字符串中常用到的函数有(C语言)
#include<string.h>
strlen
求字符串长度
strcmp
比较2个字符串是否一样
strcat
字符串连接操作
strcpy
字符串拷贝操作
strncat
字符串连接操作(前n个字符)
strncpy
字符串拷贝操作(前n个字符)
strchr
查询子串
strstr
查询字串
#include<stdlib.h>
atof
函数原型: double atof(char *str)
函数功能: 将字符串转换成一个双精度数值
atoi
函数原型: int atoi(char *str)
函数功能: 将字符串转换成一个整数值
atol
函数原型: long atol(char *str)
函数功能: 将字符串转换成一个长整数
itoa
函数原型:char*itoa(int value,char *string,int radix);
功能:将任意类型的数字转换为字符串
int value 被转换的整数,char *string 转换后储存的字符数组,int radix 转换进制数,如2,8,10,16 进制等
memset
void *memset(void *s,int ch,size_t n);
函数解释:将s中前n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快
面试题一:第一个只出现一次的字符
//解决方案:可以建立一个大小为256的哈希表,统计每个字符出现的次数
char firstChar(char *pString)
{
if(pString==NULL)
return '\0';
int hashTable[256];
// memset(hashTable,0,sizeof(hashTable));
for(int i=0;i<256;i++)
hashTable[i]=0;
char *temp=pString;
while(*temp!='\0')
{
hashTable[*temp]++;
temp++;
}
temp=pString;
while(*pString!='\0')
{
if(hashTable[*temp]==1)
return *temp;
temp++;
}
return '\0';
}
面试题二:输入两个字符串,从第一个字符串中删除第二个字符串中出现过的所有字符
<span style="font-family: Arial, Helvetica, sans-serif;">//在第二个字符中查找,如果是删除的字符直接在第一个字符中删掉</span>
//查找可以用哈希表;
//删除操作最好在O(N)时间内完成;
void deleteChars(char *source,char *deleteStr)
{
if(source==NULL||deleteStr==NULL)
return ;
int hashTable[256];
memset(hashTable,0,sizeof(hashTable));
char *ptemp = deleteStr;
while(*ptemp!='\0')
{
hashTable[*ptemp]=1;
ptemp++;
}
char *pSlow = source;
char *pFast = source;
while(*pFast!='\0')
{
if(hashTable[*pFast]!=1)
{
*pSlow = *pFast;
++pSlow;
}
++pFast;
}
*pSlow='\0';
}
面试题三:删除字符串中重复出现的字符。
//删除字符串中重复出现的字符
//同上体思路一样建立哈希表,然后删除重复字符
void deleteDuplicateChars(char *str)
{
if(str==NULL)
return ;
int hashTable[256];
memset(hashTable,0,sizeof(hashTable));
char *temp = str;
char *delete = str;
while('\0'!=*temp)
{
if(hashTable[*temp]==0)
{
hashTable[*temp]=1;
*delete=*temp;
delete++;
}
temp++;
}
*delete='\0';
}
面试题四:字符串的排列
//把字符串分两部分
//第一部分为字符串第一个字符
//第二部分为除了第一个字符外的剩下字符,接下来我们求剩下部分的排列
//拿第一个字符和它后面的字符逐个交换
void Permutation(char *str)
{
if(str==NULL)
return ;
else
permutation(str,str);
}
void permutation(char *str,char *begin)
{
if(*begin=='\0')
printf("%s\n",str);
else
{
for(char *ch=begin;*ch!='\0';++ch)
{
char temp=*ch;
*ch=*begin;
*begin=temp;
permutation(str,begin+1);
temp=*ch;
*ch=*begin;
*begin=temp;
}
}
}
面试题五:将字符串转换成整数
//写一个函数将字符串转换成整数;
//注意考虑空指针,空字符串"",正负号,溢出等测试用例;
//并在写代码的时候将对这些特殊的输入都定义好合理的输出;
//可以设置一个全局变量,当输入非法的时候修改全局变量的值;
//最后如果返回值相同,通过检查全局变量的值来看输入是否合法;
enum status{inputVaild,inputInvaild}
int strStatus=inputVaild;
int strToInt(const char *str)
{
strStatus=inputInvaild;
long long num=0;
if(str!=NULL&&*str!='\0')
{
bool minus = false;
if(*str=='+')
str++;
else if(*str=='-')
{
str++;
minus=true;
}
if(*str!='\0')
{
num = strToIntCore(str,minus);
}
}
return (int)num;
}
long long strToIntCore(const char* digit,bool minus)
{
long long num=0;
while(*digit!='\0')
{
if(*digit>='0'&&*digit<='9')
{
int flag=minus?-1:1;
num=num*10+flag*(*digit-'0');
//分两种情况判断是否溢出;
if((!minus&&num>0x7FFFFFFF)||(minus&&num<(signed int)0xB0000000))
{
num = 0;
break;
}
digit++;
}
//输出为0-9以外的字符;
else
{
num=0;
break;
}
}
if(*digit=='\0')
{
strStatus=inputVaild;
}
return num;
}
面试题六:将整数转换成字符串;
<pre name="code" class="cpp">//写一个函数,将整数转换成字符串
//整数转换成字符串可以通过加'0',再逆序的方法。
void intToStr(int n,char s[])
{
int sign=n;
char temp;
//记录字符串的符号;
if(sign<0)
n=-n;
int i=0,j,k;
//特殊输入0时;
if(n==0)
{
s[i]='0';
return;
}
while(n)
{
s[i]=n%10+'0';
i++;
n=n/10;
}
if(sign<0)
s[i++]='-';
s[i]='\0';
//将所得字符串逆序;
for(j=i-1,k=0;j>=k;j--,k++)
{
temp=s[j];
s[j]=s[k];
s[k]=temp;
}
}
面试题七:将字符串中的空格替换为%20
//注意数组从0开始计数;
//注意--和++的使用;
//测试时必须考虑特殊输入!!!
//要求时间复杂度为O(n)
void exchangSpace(char string[],int length)
{
int i=0;
int newLength = length;
int newLast;
if(string==NULL&&length<0)
return;
//每检测到一个空格将数组长度增加2
while(string[i]!='\0')
{
if(string[i]==' ')
newLength += 2;
i++;
}
newLast = newLength ;
if(newLength==length)
return ;
length -= 1;
newLast -= 1;
//设置两个指针分别指向新旧字符串的末尾
while( length >= 0)
{
if(string[length]!=' ')
{
string[newLast] = string[length];
}
else if(string[length]==' ')
{
string[newLast] = '0';
string[--newLast] = '2';
string[--newLast] = '%';
}
--newLast;
--length;
}
}
面试题八:翻转单词顺序
//输入一个英文句子,翻转句子中单词的顺序,单词中字符的顺序不变
//先翻转句子中的所有字符再翻转单个单词
void reverse(char *begin,char *end)
{
if(begin==NULL||end==NULL)
return;
while(begin<end)
{
char temp=*begin;
*begin=*end;
*end=temp;
begin++;
end--;
}
}
char *reverseSentence(char *str)
{
if(str==NULL)
return NULL;
char *begin=str;
char *end=str;
while(*end!='\0')
end++;
end--;
//翻转整个句子
reverse(begin,end);
//翻转单个单词
begin=end=str;
while(*begin!='\0')
{
if(*begin==' ')
{
begin++;
end++;
}
else if(*end==' '||*end=='\0')
{
reverse(begin,--end);
begin=++end;
}
else
end++;
}
return str;
}
面试题九:删除字符串中数字并压缩,要求时间复杂度为O(N)
//删除字符串中的数字并压缩字符串
void deleteNumInStr(char array[],int length)
{
int i;
int count =0 ;
for(i=0;i<=length-1;i++)
{
if(array[i]>='0'&& array[i]<='9')
count++;
else
array[i-count] = array[i];
}
}
面试题十:求两个串中的第一个最长子串
<span style="font-weight: normal;">//求两个字符串的第一个最长子串
char *findFirstMaxSubStr(char *str1,char *str2)
{
if(str1==NULL||str2==NULL)
return NULL;
int i,j,k;
int max=0,index;
for(i=0;i<strlen(str1);i++)
for(j=0;j<strlen(str2);j++)
{
//连续查找字符是否相同,并记录最长为多少个,和在str2中的起始位置
for(k=0;str1[i+k]==str2[j+k]&&(str1[i+k]||str2[j+k]);k++);
if(k>max)
{
index=j;
max=k;
}
}
char *strReturn=(char*)malloc(sizeof(char)*(max+1));
for(i=0;i<max;i++)
strReturn[i]=str2[index++];
strReturn[max]='\0';
return strReturn;
}</span>
面试题十一:实现strstr函数
//实现strstr函数;
//寻找子串在父串中首次出现的位置;
char *strstring(char *str,char *substr)
{
if(str==NULL||substr==NULL||*substr=='\0')
return NULL;
char *tempStr=str;
char *tempSub;
char *temp;
for(;*tempStr!='\0';tempStr++)
{
tempSub=substr;
temp=tempStr;
while(*tempSub==*temp&&*tempSub!='\0')
{
temp++;
tempSub++;
}
if(*tempSub=='\0')
return tempStr;
}
return NULL;
}
面试题十二:不开辟空间反转字符串
//不开辟空间实现字符串的反转
void reverse(char *str)
{
if(str==NULL)
return;
for(int i=0,j=strlen(str)-1;i<j;i++,j--)
str[i]^=str[j]^=str[i]^=str[j];
}
其它简单的面试题如求回文串,strcpy函数的实现等。