C++面试笔记--字符串
基本上求职者进行笔试没有不考字符串的。字符串也是一种相对简单的数据结构,容易被考。事实上,字符创也是一个考验程序猿编程规范和编程习惯的重要考点。
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++面试笔记--字符串的更多相关文章
- php面试笔记(5)-php基础知识-自定义函数及内部函数考点
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而函数相关的考点 ...
- php面试笔记(2)-php基础知识-常量和数据类型
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 面试是每一个PHP初学者到PHP程序员必不可少的一步,冷 ...
- GitHub标星125k!阿里技术官用3个月总结出的24万字Java面试笔记
最近收到一位粉丝的回馈! 这位粉丝已经成功入职阿里了小编很是羡慕啊! 今天就把这份30w字Java面试笔记给大家分享出来,说来也巧这份资料也是由一位阿里技术官整理出来的这算不算是"搬起石头砸 ...
- Java高级开发工程师面试笔记
最近在复习面试相关的知识点,然后做笔记,后期(大概在2018.02.01)会分享给大家,尽自己最大的努力做到最好,还希望到时候大家能给予建议和补充 ----------------2018.03.05 ...
- 《python基础教程(第二版)》学习笔记 字符串(第3章)
<python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:格式化输出字符 ...
- php面试笔记(3)-php基础知识-运算符
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而运算符相关的考 ...
- es6学习笔记--字符串&数值&数组&函数&对象的扩展
这几天抽空学习了es6语法,关于字符串,数值,数组,函数以及对象的扩展,看到es6标准入门这本书,里面讲的扩展特别多,我认为有几部分在项目上用不到,就挑有用的当笔记学习了. 字符串的扩展 str.in ...
- 【Redis】命令学习笔记——字符串(String)(23个超全字典版)
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 本篇基于redis 4.0.11版本,学习字符串( ...
- <转载> C++笔试、面试笔记
这些东西有点烦,有点无聊.如果要去C++面试就看看吧.几年前网上搜索的.刚才看到,就整理一下,里面有些被我改了,感觉之前说的不对或不完善. 1.求下面函数的返回值( 微软) int func(x) ...
随机推荐
- Technocup 2019 C. Compress String
一个字符串 $s$,你要把它分成若干段,有两种合法的段 1.段长为 $1$,代价为 $a$ 2.这个段是前面所有段拼起来组成的字符串的字串,代价为 $b$ 问最小代价 $|s| \leq 5000$ ...
- swing之borderlayout
import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JFrame; //1.继承 JFrame类 ...
- 修改git commit 最后一次提交的注释信息 以及如何退出git bash vim编辑器
https://www.cnblogs.com/sandy-happyhour/p/5950084.html 今天用git commit -m “注释”提交的时候,注释写错了,于是各种查资料开始了和g ...
- php之laravel学习
http://laravel-china.github.io/php-the-right-way/#composer_and_packagist laravel 添加 dingoapi路由插件 并运用 ...
- 蓝桥杯 基础练习 BASIC-19 完美的代价
基础练习 完美的代价 时间限制:1.0s 内存限制:512.0MB 问题描述 回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的.小龙龙认为回文串才是完美的.现在给你一个串,它不一定 ...
- ThreadPoolTaskExecutor的配置解释
ThreadPoolTaskExecutor的配置在网上找了很多解释没找到,看了下ThreadPoolExecutor的配置,名字差不多,应该含义也差不多.只不过ThreadPoolTaskExecu ...
- mybatis---demo1--(单表增删改查)----bai
实体类: package com.etc.entity; public class News { private int id; private String title; private Strin ...
- 2016.5.30实现透明Panel及控件置顶的方法
想放置一个透明Panel在某控件上端,实现效果是可透过此Panel看见下面控件,但鼠标点击却无任何反应. 1.新建置自定义Panel类 using System; using System.Colle ...
- HDLM命令dlnkmgr详解之四_monitor/offline/online
1. monitor 以一定的时间间隔监控hba或cha口的IO信息. 命令格式 监控hba口的IO信息: dlnkmgr monitor -hbaid HBA_ID [-intvl Interval ...
- JavaScript语言基础-对象与数组