数组和字符串是密切相互的。从抽象的意义上说,字符串只是一个(可能是只读的)字符数组。
进入正题,这方面的经典面试问题有哪些呢?
- 编写strcpy函数
问题描述:编写c语言的strcpy函数,完成字符数组复制功能。
代码及分析如下:
#include <iostream>
char* str_cpy(char *dis_str,const char *sou_str)
{
if((!dis_str)||(!sou_str)) return NULL;//指针一定要判空
char *tem=dis_str;//千万不要忘
while((*dis_str++=*sou_str++)!='\0');
return tem;//能用到链式语句中
}
/*
要点:
1. const char *sou_str 因为不能改变 sou_str所指的内容
2. if((!dis_str)||(!sou_str)) return NULL;指针一定要判空
3. while((*dis_str++=*sou_str++)!='\0');后面分号不能省,为了使'\0'也顺利复制
4. 返回 char*,便于链式操作语句,注意要先存 :char *tem=dis_str;//千万不要忘
5. if(str_cpy(cpy_str,str))判断复制是否成功
*/
int main()
{
char *str="123456";
char *cpy_str=new char[10];
if(str_cpy(cpy_str,str))//表示复制成功
std::cout<<cpy_str<<std::endl;
}
- 找第一个不重复字符
问题描述:编写一个高效的函数用于在字符串中找到第一个不重复的字符。
代码及分析如下:
#include <iostream>
char firstNonRepeated(char *data)
{
unsigned p[128]={0};//用于存储字符出现个数,当然了如果是hash_map,会更省空间
char *tem=data;
while(*tem!='\0')
{
++p[*tem++];
}
tem=data;
while(*tem!='\0')
{
if(p[*tem]==1) return *tem;//找到第一个不重复的字符
else ++tem;
}
return NULL;
}
int main()
{
char *str="abdcefbae";
std::cout<<firstNonRepeated(str)<<std::endl;
}
- 整数/字符串类型转换
问题描述:编写两个转换程序。第一个将一个字符转化成有符号整数,第二个讲一个有符号整数转化成字符串。
代码及分析如下:
#include <iostream>
#include <algorithm>
using namespace std;
//将字符串转化为整数
int stringToInt(string str)
{
int length=str.length();
int begin=0;//数字开始的地方
int sig=1;//数字的正负号
if(str.at(0)=='-')
{
begin=1;
sig=-1;
}
int res=0;//数字不得绝对值
while(begin<length)
{
res=res*10+str.at(begin)-'0';
++begin;
}
return res*sig;
}
//将字符串转化为整数
/*
策略:
由于不知道总共有多少位,可以将数字由低向高位存储,然后再颠倒
*/
string intToString(int i)
{
string res;
int begin=0;//数字开始的地方
if(i<0)
{
res+='-';
begin=1;
i=-i;
}
while(i)//从低位向高位存入字符串
{
res+='0'+i%10;
i=i/10;
}
//数字部分进行反转
int end=res.size()-1;
while(begin<end)
swap(res.at(begin++),res.at(end--));
return res;
}
int main()
{
std::cout<<stringToInt("-456230")<<std::endl;
std::cout<<intToString(-956453)<<std::endl;
}
- 删除指定字符
问题描述:编写一个高效的函数,从一个字符串中删除指定的字符,如“abcdeaf”,删除其中“af”,变成“bcde”。
代码及分析如下:
#include <iostream>
using namespace std;
string removeChars(string str,string removeChars)
{
int length_str=str.size();
int length_rem=removeChars.size();
int length_dst=0;//存储最终字符串长度
bool flags[128]={0};//记录那些字符需要删除
for(int i=0;i<length_rem;++i) flags[removeChars[i]]=true;
for(int i=0;i<length_str;++i)//删除字符
{
if(!flags[str[i]]) str[length_dst++]=str[i];
}
str.resize(length_dst);
return str;
}
int main()
{
std::cout<<removeChars("123456789987546133","936")<<std::endl;
}
- 反转单词
问题描述:编写一个函数,将一个字符串中单词的顺序反转,如“never give up”,反转之后“up give never”。
代码及分析如下:
#include <iostream>
#include <algorithm>
#include <cstring>
/*
有两种思路实现这一目标:
1.定义一个临时字符串,将原字符串从后到前读,从后从前到后写入临时字符串
2.不用临时变量,先整个字符串直接反转,然后再反转各个单词
这儿使用第二种方法
*/
//反转字符串
void reverseString(char *begin,char *end)
{
while(begin<end)
std::swap(*begin++,*end--);
}
//反转单词
void reverseWords(char *str)
{
int length=strlen(str);
reverseString(str,str+length-1);//反转整个字符串
char *pos=str;//遍历的位置
char *wordBegin=str;//记录单词开始
char *wordEnd=str; //记录单词结尾
while(pos<str+length)
{
while((pos<str+length)&&(*pos==' ')) ++pos;
wordBegin=pos;
while((pos<str+length)&&(*pos!=' ')) ++pos;//(pos<str+length)防止向后时内存泄露
wordEnd=pos-1;
reverseString(wordBegin,wordEnd);
}
}
int main()
{
char str[]="me? love you Do";
reverseWords(str);
std::cout<<str<<std::endl;
}