1、输入一个整数的字符串,把该字符串转换成整数并输出。例如输入字符串“345”,则输出整数345
思路:依次扫描字符串,每扫到一个字符,把之前的得到的数字乘以10再加上当前字符表示的数字。
注意:还可能包括‘+’或‘-’,表示整数的正负。需要特殊处理
考虑非法输入:
1)判断指针是否为空
2)输入的字符串可能不是数字的字符,碰到则停止
3)溢出问题,若溢出,返回0
2、在一个字符串中找到第一个只出现一次的字符
ASCII字符是一个长度为8的数据类型总共可能是256种可能
3、判断一个字符串中所有字符是否都不同,复杂度O(n)
假设字符串仅包括‘a’到‘z’
4、输入两个很大的正数(c字符串表示),输出他们的乘积,假设不考虑非法输入
5、字符串中单词的逆转,即将单词出现的顺序进行逆转。如“Today is Friday!”逆转为“Friday! is Today”
思路:不使用额外空间完成,先将字符串全部逆转,然后空格分割单词,单词自身进行逆转
思路:依次扫描字符串,每扫到一个字符,把之前的得到的数字乘以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';
}