编程之美一——字符串

    字符串是最常见的面试题目类型,应当分配最大的时间。 字符串本身很简单,但是相关的题目需要更复杂的算法来解决。比如说动态规划,搜索,等等。

字符串中常用到的函数有(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函数的实现等。
















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值