字符串笔试题

1、输入一个整数的字符串,把该字符串转换成整数并输出。例如输入字符串“345”,则输出整数345
思路:依次扫描字符串,每扫到一个字符,把之前的得到的数字乘以10再加上当前字符表示的数字。
注意:还可能包括‘+’或‘-’,表示整数的正负。需要特殊处理
考虑非法输入:
1)判断指针是否为空
2)输入的字符串可能不是数字的字符,碰到则停止
3)溢出问题,若溢出,返回0
enum Status{kValid,KInvalid};
int g_nStatus=kValid;
int StrToInt(const char* str)
{
	g_nStatus=KInvalid;
	long long num=0;
	if(str!=NULL)
	{
		const char* digit=str;
		bool minus=fasle;
		if(*digit=='+')//正负判断,特殊处理
			digit++;
		else if(*digit=='-')
		{
			digit++;
			minus=true;
		}
		while(*digit!='\0')
		{
			if(*digit>='0'&&*digit<='9')
			{
				num=num*10+(*digit-'0');
				if(num>std::numeric_limit<int>::max())//溢出处理
				{
					num=0;
					break;
				}
				digit++;
			}
			else //非数字字符处理
			{
				num=0;
				break;
			}
		}
		if(*digit=='\0')
		{
			g_nStatus=kValid;
			if(minus)
				num=0-num;
		}
	}
	return num;
}


2、在一个字符串中找到第一个只出现一次的字符
ASCII字符是一个长度为8的数据类型总共可能是256种可能
void FirstNotRepeatingChar(const char* pString)
{
	assert(pString!=NULL);
	const int tableSize=256;
	unsigned int hashTable[tableSize];
	for(unsigned int i=0;i<tableSize;++i)
		hashTable[i]=0;
	const char* pHashKey=pString;
	while(*(pHashKey)!='\0')
		hashTable[*(pHashKey++)]++;
	pHashKey=pString;
	while(*pHashKey!='\0')
	{
		if(hashTable[*pHashKey]==1)
		{
			printf("%c",*pHashKey);
			return;
		}
		pHashKey++;
	}
}


3、判断一个字符串中所有字符是否都不同,复杂度O(n)
bool char_set[256];
int isUniqueCharString(const char* str)
{
	assert(str!=NULL);
	int len=strlen(str);
	for(int i=0;i<len;++i)
	{
		int val=str[i];
		if(char_set[val])return 0;//有相同值的就会返回0
		char_set[val]=true;
	}
	return 1;
}

假设字符串仅包括‘a’到‘z’
int isUniqueCharString(const char* str)
{
	assert(str!=NULL);
	int checker=0;
	int len=strlen(str);
	for(int i=0;i<len;i++)
	{
		int val=str[i]-'a';
		if((checker&(1<<val))>0)return 0;
		checker |=(1<<val);
	}
	return 1;
}



4、输入两个很大的正数(c字符串表示),输出他们的乘积,假设不考虑非法输入
void mutiply(const char* a,const char* b)
{
	assert(a!=NULL&&b!=NULL);
	int i,j,ca,cb,*s;
	ca=strlen(a);
	cb=strlen(b);
	s=(int*)malloc(sizeof(int)*(ca+cb));
	for(i=0;i<ca+cb;i++)
		s[i]=0;
	for(i=0;i<ca;i++)
		for(j=0;j<cb;j++)
			s[i+j+1]+=(a[i]-'0')*(b[j]-'0');
	for(i=ca+cb-1;i>=0;i--)
		if(s[i]>=10)
		{
			s[i-1]+=s[i]/10;
			s[i]%=10;
		}
	char *c=(char*)malloc((ca+cb)*sizeof(char));
	i=0;
	while(s[i]==0)i++;//跳过头部0
	for(j=0;i<ca+cb;i++,j++)c[j]=s[i]+'0';
	c[j]='\0';
	for(i=0;i<ca+cb;i++)cout<<c[i];
	cout<<endl;
	free(s);
	free(c);
}


5、字符串中单词的逆转,即将单词出现的顺序进行逆转。如“Today is Friday!”逆转为“Friday! is Today”
思路:不使用额外空间完成,先将字符串全部逆转,然后空格分割单词,单词自身进行逆转
void Reverse(char* pb,char *pe)
{
	if(pb==NULL||pe==NULL)return;
	while(pb<pe)
	{
		char temp=*pb;
		*pb=*pe;
		*pe=tmp;
		pb++,pe--;
	}
}
char* ReaverseSentence(char *pData)
{
	if(pData==NULL)return NULL;
	char *pBegin=pData;char *pEnd=pData;
	while(*pEnd!='\0')
		pEnd++;
	pEnd--;
	Reverse(pBegin,pEnd);//先逆转整条句子
	pBegin=pEnd=pData;
	while(*pBegin!='\0')
	{
		if(*pBegin=='')
		{
			pBegin++;
			pEnd++;
			continue;
		}
		else if(*pEnd==''||*pEnd=='\0')
		{
			Reverse(pBegin,--pEnd);
			pBegin=++pEnd;
		}
		else
			pEnd++;
	}
	return pData;
}
 

char *LeftRotateString(char * pStr,int n)
{
	if(pStr!=NULL)
	{
		int nLength=static_cast<int >(strlen(pStr));
		if(nLength>0&&n>0&&n<nLength)
		{
			char *pFirstStart=pStr;
			char* pFirstEnd=pStr+n-1;
			char* pSecondStart=pStr+n;
			char* pSecondEnd=pStr+nLength-1;
			Reverse(pFirstStart,pFirstEnd);
			Reverse(pSecondStart,pSecondEnd);
			Reverse(pFirstStart,pSecondEnd);
		}
	}
	return pStr;
}


6、删除字符串开始及末尾的空白符(若干空格),并且把数组中间的多个空格(如果有)符转化为1个

void fun(char *s)
{
	int i=0,j=0;
	while(s[j]=='')//删除头部的空白符
		j++;
	int len=strlen(s)-1;
	while(s[len]=='')len--;//删除尾部的空白符
	s[len+1]='\0';
	while(s[j]!='\0')
	{
		while(s[j]=='')
			j++;
		if(s[j-1]==''&&s[j-2]==''&&i!=0)
			s[i++]='';
		s[i++]=s[j++];
	}
	s[i]='\0';
}


7、删除模式串中出现的字符,如“welcome to asted”,模式串为“aeiou”,那么得到的字符串为“wlcm t std”,要求性能最优,字符串全部为小写字母
思路:依次遍历,如是则删除

void fun(char *s)
{
	assert(s!=NULL);
	int i=0,j=0;
	while(s[j]!=NULL)
	{
		while(s[j]=='a')||s[j]=='e'||s[j]=='i'||s[j]=='o'||s[j]=='u')
			j++;
		s[i++]=s[j++];
	}
	s[i]='\0';
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值