基本上求职者进行笔试没有不考字符串的。字符串也是一种相对简单的数据结构,容易被考。事实上,字符创也是一个考验程序猿编程规范和编程习惯的重要考点。

  

1、替换空格:实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“we are happy。”则输出“we%20are%20happy。”

    答案:用一个空的字符串去替换%,2,0三个字符,那么原字符就会变长从而覆盖掉后面的字符,我么可以考虑创建一个新的字符串并在新的字符串上面做替换,那样就能够分配足够的内存了。在这里我们可以考虑从后往前去替换字符串。这里创建两个指针

    

 #include<iostream>
#include <string>
#include<cstring>
#include<cstdio>
#include<stdlib.h>
using namespace std;
/*
算法原理:准备两个指针p1,p2;p1指向原始字符串的末尾,p2指向替换之后的字符串的末尾。接下来我们向前移动指针p1,
逐个把它指向的字符复制到p2指向的位置,知道碰到第一个空格为止,
算法:先遍历一次字符串,记录空格的数目,在计算新的字符数组的长度
在从后往前进行替换
*/
char *copystr(char *s)
{
int len=strlen(s);//字符串的长度
int blank=;//表示空格的数目
if(len==)
{
return NULL;
}
if(s==NULL)
{
return NULL;
} for(int i=; i<len; i++) //判断字符串,确定空格的数目,从而确定新的字符串所需的个数
{
if(s[i]==' ')
blank++;
}
if(blank==)
return s;
int new_len=blank*+len;//计算新的字符数组的长度(本来不该加一,但是最后的输出要求加一)
int l=new_len+;//这里'\0'也算一个长度
char *str1;
for(int i=len; i>=; i--)//算法:有空格就赋值,没有空格直接复制,从后往前复制
{
if(s[i]!=' ')//从后往前复制
{
str1[l-]=s[i];
l--;
}
else//转换空格
{
str1[l-]='';
str1[l-]='';
str1[l-]='%';
l-=;
}
}
return str1;
}
int main()
{
static char str[];
gets(str);
char *dest = copystr(str);
if(dest != NULL)
puts(dest);
dest = NULL;
return ; }
 #include<iostream>
#include <string>
#include<cstring>
#include<cstdio>
#include<stdlib.h>
using namespace std;
/*
算法原理:准备两个指针p1,p2;p1指向原始字符串的末尾,p2指向替换之后的字符串的末尾。接下来我们向前移动指针p1,
逐个把它指向的字符复制到p2指向的位置,知道碰到第一个空格为止,
算法:先遍历一次字符串,记录空格的数目,在计算新的字符数组的长度
在从后往前进行替换
*/
char *copystr(char *s)
{
int len=strlen(s);//字符串的长度
int blank=;//表示空格的数目
if(len==)
{
return NULL;
}
if(s==NULL)
{
return NULL;
}
for(int i=; i<len; i++) //判断字符串,确定空格的数目,从而确定新的字符串所需的个数
{
if(s[i]==' ')
blank++;
}
if(blank==)
return s;
int new_len=blank*+len;//计算新的字符数组的长度(本来不该加一,但是最后的输出要求加一)
int l=new_len+;
// char *str1 = (char *)malloc(new_len*sizeof(char)+1);
char *str1;
for(int i=len; i>=; i--)//算法:有空格就赋值,没有空格直接转换
{
if(s[i]!=' ')
{
str1[l-]=s[i];
l--;
}
else
{
str1[l-]='';
str1[l-]='';
str1[l-]='%';
l-=;
}
}
return str1;
}
int main()
{
static char str[];
gets(str);
char *dest = copystr(str);
if(dest != NULL)
puts(dest);
dest = NULL;
return ; }

2、字符串的排列:输入一个字符串,打印出该字符串中字符的所有排列。例如:输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab,cba

 答案:递归的过程和这个图差不多。首先我们先固定第一个字符,后面的剩余字符是一部分。第一步我么先把第一个字符和后面的所有字符进行交换,得出第一个字符的所有可能(第一个字符可能出现的情况列出),之后我们在后面的字符部分当做一个字符串重复前面的方法,把第二个字符和后面的所有字符进行交换,得出其他的情况,依次递归重复上面的方法,直到最后一位字符停止。

 
 #include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;
/*
解题思路:
1.就是将字符串从第一个字符开始,依次和后面的字符进行交换,知道交换到末尾为止
① ②
2.比如:abcd--acbd,a,a,a,--
bacd--bcad--
cbad--cabd--
dbca--dcba--
3.但是这个算法是不能有重复的字符的操作
*/
/*
交换函数:将前后两个字符进行交换
*/
int swap_str(char *str1,char *str2){
char temp=*str1;
*str1=*str2;
*str2=temp;
}
/*这个函数是输出排列的函数*/
void permutation(char *str1,char *begin){
if(*begin=='\0')//当递归到末尾的时候,输出该排列
cout<<str1<<endl;
else{
for(char *ch=begin;*ch!='\0';*ch++){//从子字符串进行递归
swap_str(ch,begin);
permutation(str1,begin+);
swap_str(ch,begin);
}
}
}
void permutation(char *str){
if(str==NULL)
return ;
permutation(str,str);
} int main(){
char str[]="abc";
permutation(str,str);
return ;
}

3、第一个只出现一次的字符:在字符串中找出第一个只出现一次的字符。如输入“abaccdeff”则输出b

 答案:由于题目出现了与字符出现次数相关。我们可以利用一个容器来存放每个字符出现的次数,也就是说这个容器的作用是把一个字符隐射成一个数字。所以我们利用哈希表。

 #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
char Find_Only_one_char(char *string){
/*①:字符char是一个长度为8的数据类型,一个字节,在32位的操作系统中有256中可能组合。
我们创建一个长度为256的数组,每个字母根据其ASSIC码作为数组的下标对应数组的一个数字
而数组中存储的是每个字符穿线的次数。
②:复杂度:第一次遍历数组更新一个字符出现次数的时间为O(1),N个就是O(N),第二次遍历读取一个字符
的时间是O(1),N个就是O(N),所以总的是O(N)*/
if(string==NULL)
return '\0';
const int hashsize=;//表示256个字符的Assic
unsigned int hashtable[hashsize];//哈希容器
for(unsigned int i=;i<hashsize;i++)
hashtable[hashsize]=;//初始化哈希数组 //开始进行第一次的遍历,如果出现一个字符,则将改字符对应的hash数加1,创建一个字符指针进行遍历
char *string1=string;
while(*(string1)!='\0'){
//这里string1++:string1最后地址会加1,但是*(string1++)还是当前的地址不会加1,所以a++是后加,++a是先加
hashtable[*(string1++)]++;//地址加加,对应的字符的hash数也是加加
}
//重新让指针指向字符串首部再进行一次遍历
string1=string; while(*string1!='\0'){
if(hashtable[*string]==)
return *string;
string++;//地址加加,继续遍历下一个字符
}
return '\0';
}
int main(){
char string[];
while(scanf("%s",string)!=EOF){
cout<<Find_Only_one_char(string)<<endl;
}
// delete []string;
}

4、翻转单词顺序VS左旋转字符串:题目一:输入一个英语句子,翻转句子中单词的顺序,但是单词的字符的顺序不变。变电符号和普通字符一样处理。

 答案:这里我们可以考虑一种两次翻转字符串的方法:第一次先是将字符串全部翻转,然后第二次将每个单词翻转,这样就实现了题目的要求。全部翻转比较容易实现就是首尾字符交换就行了,给出两个指针指向首尾,进行交换。

 #include<iostream>
#include<stdlib.h>
#include<cstring>
#include<cstdio>
using namespace std;
/*这里我们可以通过单词的空格来确定某个单词的起始位置和终止位置。然后在调用change函数就行了,这个方法相当于分治法。
先是整体,然后分成每个单词部分翻转。*/
void Change_Oneword_Order(char *begin,char *behind){
if(begin>behind)
return ;
while(begin<behind){//遍历一个单词,前后顺序调换
char temp=*begin;
*begin=*behind;
*behind=temp;
begin++,behind--;//遍历到单词中间位置
} }
char *Change_Onestr_Order(char *str){
if(str==NULL)
return '\0'; char *behind=str;
char *begin=str;
while(*behind!='\0')
behind++;
behind--;//第二指针向前移动一位 Change_Oneword_Order(begin,behind); begin=str;//第二次进行单词的翻转
behind=str; while(*begin!='\0'){//临界条件:第一指针走到字符串的末尾结束
if(*begin==' '){
//找到空格,跳过
begin++;
behind++;
}
else if(*behind==' '|| *behind=='\0'){
Change_Oneword_Order(begin,--behind);//从空格前面一个字符开始翻转
begin=++behind;//翻转完成回到同一个起跑线
}
else
behind++;
}
return str;
}
void print(char *str){
cout<<str;
}
int main(){
char s[];
gets(s);
char *ss=Change_Onestr_Order(s);
print(ss);
}

    题目二:字符串的左旋转操作是吧字符串前面的若干个字符转移到字符串的尾部。定义一个函数实现字符串左旋转操作功能。比如输入字符串“abcdef”和2,返回cdefab.

 答案:这个题目其实和上面那个差不多,我们可以这样处理:我们先分别把前面后面两部分进行翻转,得到bafedc,然后我们在翻转整个字符串得到cdefab,这样就行了。其实我们也是可以先整体翻转然后在局部翻转,但是在局部反转的时候不好找到翻转位置,实现不如前面方法好。

 #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
void Change_Oneword_Order(char *begin,char *behind){
if(begin>behind)
return ;
while(begin<behind){//遍历一个单词,前后顺序调换
char temp=*begin;
*begin=*behind;
*behind=temp;
begin++,behind--;//遍历到单词中间位置
} }
char *Left_Revolve_Str(char *str,int number){
if(str!=NULL){
int length=static_cast<int>(strlen(str)); if(length> &&number> &&number<length){
//第一部分:0->n
char *firststart=str;
char *firstend=str+number-;
//第二部分:n->length
char *secondstart=str+number;
char *secondend=str+length-;
//翻转前半部分
Change_Oneword_Order(firststart,firstend);
//翻转后半部分
Change_Oneword_Order(secondstart,secondend);
//翻转整体
Change_Oneword_Order(firststart,secondend);
}
}
return str;
}
void print(char *str){
cout<<str;
}
int main(){
int number;
cin>>number;
char s[];
cin>>s;
char *ss=Left_Revolve_Str(s,number);
print(ss);
}

5、怎样将整数转换成字符串数,并且不用函数 itoa ?

    答案:这个题目看上去十分简单,但是如果仔细考虑很多情况的也不是很简单,比如一些特殊情况:空指针NULL,空字符串,正负号,溢出等方面的测试

  详细版本:

 #include<iostream>
using namespace std;
long long strToCore(const char *,bool );
enum status{valid=,invalid=};
int g_status=valid; int strToInt(const char *str){
g_status=invalid;
long long num=; if(str!=NULL && *str!='\0'){//不为空也没溢出
bool minus=false;
if(*str=='+')
str++;
else if(*str=='-'){
str++;
minus=true;
}
num=strToCore(str,minus);
}
return num;
}
long long strToCore(const char *digit,bool minus){
long long num=;
while(*digit!='\0'){
if(*digit>='' &&*digit<=''){
int flag=minus?-:;
num=num*+flag*(*digit-'');
//这里没有考虑溢出的情况
digit++;
}
else{
num=;
break;
}
}
if(*digit=='\0')
g_status=valid;
return num;
}
int main(){
int num=;
num=strToInt("");
cout<<num;
}

 itao版本:

 #include <iostream>

 #include <stdlib.h>

 using namespace std;

 //使用itoa函数

 int main ()

 {

     int num=;

     char str[];

     itoa(num,str,);

     cout<<"integer:"<<num<<endl<<"string:"<<str<<endl;

     return ;

 }

6、已知函数原型是 char *strcpy(char *strDest,const char *strSrc);,其中strDest是目的字符串,strSrc是源字符串。

(1)不调用C++/C的字符串库函数,请编写strcpy函数。

(2)strcpy函数把strSrc的内容复制到strDest,为什么还要char *类型返回值?

答案:

  

char *strcpy(char *strDest,const char *strSrc)
{
assert((strDest!=NULL)&&(strSrc!=NULL));
char *address=strDest;
while((*strDest++=*strSrc++)!='\0')
NULL;
return address;
}

(2)为了实现链式表达式,返回具体值。

例如:

int length=strlen(strcpy(strDest,"hello world"));

7、下面程序输出是什么?

  

 #include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int main(){
char s[]="";
char d[]="";
strcpy(d,s);
cout<<d<<endl<<s<<endl;
}

    答案:输出结果是1234567890,567890.原因:当初分配的内存地址是连续内存的关系(从后往前存储),原来是:123\01234567890\0,strcpy变成了1234567890\0567890\0,所以在分配空间的时候要给源字符串和目标字符串留有足够的空间。

C++面试笔记--字符串的更多相关文章

  1. php面试笔记(5)-php基础知识-自定义函数及内部函数考点

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而函数相关的考点 ...

  2. php面试笔记(2)-php基础知识-常量和数据类型

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 面试是每一个PHP初学者到PHP程序员必不可少的一步,冷 ...

  3. GitHub标星125k!阿里技术官用3个月总结出的24万字Java面试笔记

    最近收到一位粉丝的回馈! 这位粉丝已经成功入职阿里了小编很是羡慕啊! 今天就把这份30w字Java面试笔记给大家分享出来,说来也巧这份资料也是由一位阿里技术官整理出来的这算不算是"搬起石头砸 ...

  4. Java高级开发工程师面试笔记

    最近在复习面试相关的知识点,然后做笔记,后期(大概在2018.02.01)会分享给大家,尽自己最大的努力做到最好,还希望到时候大家能给予建议和补充 ----------------2018.03.05 ...

  5. 《python基础教程(第二版)》学习笔记 字符串(第3章)

    <python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:格式化输出字符 ...

  6. php面试笔记(3)-php基础知识-运算符

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而运算符相关的考 ...

  7. es6学习笔记--字符串&数值&数组&函数&对象的扩展

    这几天抽空学习了es6语法,关于字符串,数值,数组,函数以及对象的扩展,看到es6标准入门这本书,里面讲的扩展特别多,我认为有几部分在项目上用不到,就挑有用的当笔记学习了. 字符串的扩展 str.in ...

  8. 【Redis】命令学习笔记——字符串(String)(23个超全字典版)

    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 本篇基于redis 4.0.11版本,学习字符串( ...

  9. <转载> C++笔试、面试笔记

    这些东西有点烦,有点无聊.如果要去C++面试就看看吧.几年前网上搜索的.刚才看到,就整理一下,里面有些被我改了,感觉之前说的不对或不完善. 1.求下面函数的返回值( 微软) int func(x)  ...

随机推荐

  1. 转载:关于消息队列的使用----ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ

    转载: http://blog.csdn.net/konglongaa/article/details/52208273

  2. UDP打洞原理及代码

    来源:http://www.fenbi360.net/Content.aspx?id=1021&t=jc UDP"打洞"原理 1.       NAT分类 根据Stun协议 ...

  3. 通过Azure File Service搭建基于iscsi的共享盘

    在Azure上目前已经有基于Samba协议的共享存储了. 但目前在Azure上,还不能把Disk作为共享盘.而在实际的应用部署中,共享盘是做集群的重要组件之一.比如仲裁盘.Shared Disk等. ...

  4. Azure CLI的版本问题

    Azure支持多种管理方法.命令行方法有: PowerShell,PowerShell只能运行在Windows上 Azure CLI,而Azure CLI可以运行在Windows.MAC以及Linux ...

  5. hihoCoder#1068(RMQ-ST算法)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在美国旅行了相当长的一段时间之后,终于准备要回国啦!而在回国之前,他们准备去超市采购一些当地特产——比如汉堡 ...

  6. Windows Server 2008 R2换SID要注意

    今天刚装Windows2008R2,准备做实验.同样,我对虚拟机采用了母盘和差异磁盘.在新建好的虚拟机上使用NewSID执行更新SID操作时,一切正常,但当更新完并重启进入系统后,竟然蓝屏了.   原 ...

  7. VI与VIM区别

    Vim是从 vi 发展出来的一个文本编辑器 .代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用.和Emacs 并列成为类Unix系统 用户最喜欢的编辑器. Vim的第一个版本由B ...

  8. Python操作Excel,并结合unittest单元测试框架

    第一步:写Excel操作方法 excel_operate.py文件 from openpyxl import load_workbook #引入模块 class MyExcel: def __init ...

  9. Java 的三个注释

    单行注释 // 这是名为 a 的类 class a{ } 多行注释 /* 这是多行注释 可以注释多行 */ class a{ } 文档注释 /** 这是文档注释 可以注释多行 */ class a{ ...

  10. Python类(五)-反射

    反射即通过字符串映射或修改程序运行时的状态.属性.方法 有4个方法: hasattr(): hasattr(object,string):object为实例化的对象,string为字符串 判断对象ob ...