程序员面试秘笈之④"/>
C和C++程序员面试秘笈之④
本系列博客基于董山海的<C和C++程序员面试秘笈>,旨在记录,欢迎交流,可联系 zywang@shu.edu !
第四章:字符串
文章目录
- 1、面试题1
- 2、面试题2
- 3、面试题3
- 4、面试题4
- 5、面试题5
- 6、面试题6
- 7、面试题7
- 8、面试题8
- 9、面试题9
- 10、面试题10
- 11、面试题11
- 12、面试题12
- 13、面试题13
- 14、面试题14
- 15、面试题15
- 16、面试题16
- 17、面试题17
- 18、面试题18
- 19、面试题19
- 20、面试题20
- 21、面试题21
- 22、面试题22
- 23、面试题23
- 24、面试题24
- 25、面试题25
- 26、面试题26
- 27、面试题27
1、面试题1
使用库函数将数字转成字符串
itoa(): 将整型值转换为字符串;
ltoa(): 将长整型值转换成字符串;
ultoa(): 将无符号长整型转换为字符串;
gcvt(): 将浮点型数转化为字符串,取四舍五入;
ecvt(): 将双精度浮点型值转化为字符串;
fcvt(): 以指定位数为转换精度,其余同ecvt();
2、面试题2
不使用库函数将整数转化为字符串
#include <iostream>
using namespace std;
//
void int2str(int n, char *str) { //这边n表示整数char buf[10] = "";int i = 0;int len = 0;int temp = n < 0 ? -n : n; //temp为n的绝对值if (str == NULL) {return;}//while (temp) {buf[i++] = (temp % 10) + '0'; //把temp的每一位上的数存入buftemp = temp / 10;}//len = n < 0 ? ++i : i; //如果n为负数,则多一位来存储负号str[i] = 0; //末尾是结束符0while (1) {i--;if (buf[len - i - 1] == 0) {break;}str[i] = buf[len - i - 1]; //把buff数组里的字符拷到字符串}if (i == 0) {str[i] = '-'; //如果是负数,添加负号}
}int main() {int nNum;char p[10];cout << "Please input an integer:";cin >> nNum;cout << "output: ";int2str(nNum, p);cout << p << endl;system("pause");return 0;
}
3、面试题3
使用库函数将字符串转化为数字
atof():将字符串转化为双精度浮点型值;
atoi():将字符串转换为整型值;
atol():将字符串转换为长整型值;
strtod():将字符串转化为双精度浮点型值;
strtol():将字符串转换成长整型值;
strtoul():将字符串转换成无符号长整型值;
4、面试题4
不使用库函数将字符串转化为数字
#include <iostream>
using namespace std;
//将字符串转换为整数
int str2int(const char *str) {int temp = 0;const char *ptr = str; //ptr保存str字符串开头//if (*str == '-' || *str == '+') { //如果第一个字符是正负号,则移到下一个字符str++;}while (*str != 0) {if ((*str < '0') || (*str > '9')) { //如果当前字符不是数字,则退出循环break;}temp = temp * 10 + (*str - '0'); //如果当前字符是数字,则计算数值,str++;}if (*ptr == '-') { //如果字符串以'-'开头,则换成相反数temp = -temp;}return temp;
}int main() {int n = 0;char p[10] = "";//cin.getline(p, 20);n = str2int(p);cout << n << endl;system("pause");
}
5、面试题5
编程实现strcpy函数
strcpy函数的原型是:
c h a r ∗ s t r c p y ( c h a r ∗ s t r D e s t , c o n s t c h a r ∗ s t r S r c ) char *strcpy(char * strDest,const char *strSrc) char∗strcpy(char∗strDest,constchar∗strSrc)
#include <stdio.h>
#include <iostream>//实现strSrc到strDest的复制
char *strcpy(char *strDest, const char * strSrc) {//判断参数strDest和strSrc有效性,是否为空if ((strDest == NULL) || (strSrc == NULL)) {return NULL;}//保存目标字符串的首地址char *strDestCopy = strDest;//把strSrc字符串的内容复制到strDest下while ((*strDest++ = *strSrc++) != '\0');return strDestCopy;
}//
int getStrLen(const char *strSrc) {int len = 0;while (*strSrc++ != '\0') {len++;}return len;
}int main() {char strSrc[] = "Hello World";char strDest[20];int len = 0;len = getStrLen(strcpy(strDest, strSrc));//链式表达式,先复制再计算长度printf("strDest:%s\n", strDest);printf("Length of strDest:%d\n", len);system("pause");return 0;
}
为什么要返回 cha r*类型呢? 目的:为了能够使用链式表达式。
6、面试题6
编程实现memcpy函数:
#include <stdio.h>
#include <iostream>
#include <assert.h>void *memcpy2(void *memTo, const void *memFrom, size_t size) {//memTo和memFrom必须有效assert((memTo != NULL) && (memFrom != NULL));//保存memFrom的首地址char *tempFrom = (char *)memFrom;//保存memTo的首地址char *tempTo = (char *)memTo;//循环size次,复制memFrom的值到memTo中while (size-- > 0) {*tempTo++ = *tempFrom++;}return memTo;
}
//
int main() {char strSrc[] = "Hello World"; //将被复制的字符数组char strDest[20]; //目的字符数组memcpy2(strDest, strSrc, 4); //复制strSrc的前4个字符到strDest中strDest[4] = '\0';printf("strDest:%s\n", strDest);system("pause");return 0;
}
与strcpy函数不同,memcpy以参数size决定复制多少个字符(strcpy是遇见结束符’\0’),如:memcpy复制前四个
strcpy与memcpy的区别
①复制的内容不同;strcpy只能复制字符串,而memcpy可以复制任何内容,如字符数组、整型、结构体、类等;
②复制的方法不同:strcpy不需要指定长度,遇到’\0’就截止,而memcpy是根据其在第三个参数决定复制长度;
③用途不一样:一般字符串复制用strcpy;若需要复制其他类型数据,则一般用memcpy
7、面试题7
编程实现计算字符串的长度
//编程实现计算字符串的长度
#include <stdio.h>
#include <assert.h>
#include <iostream>int strlen1(const char* src) {assert(NULL != src); //src必须有效int len = 0; //保持src首地址while (*src++ != '\0') //遇到结束符'\0'时退出循环len++; //每循坏一次,len+1return len;
}int strlen2(const char* src) {assert(NULL != src);const char *temp = src;while (*src++ != '\0');return (src - temp - 1); //返回尾部指针与头指针之差,及程度
}int main() {char p[] = "Hello World";printf("strlen1 len:%d\n", strlen1(p));printf("strlen2 len:%d\n", strlen2(p));system("pause");return 0;
}
strlen2比strlen1效率更高,strlen2是指针之间的位置差。
8、面试题8
编程实现字符串中子串的查找:实现一个函数strtstr,即从一个字符串中,查找另一个字符串的位置,如strstr(“12345”,“34”),返回是2,在2号位置找到字符串34。
#include <stdio.h>
#include <iostream>
#include <assert.h>const char *strstr(const char* src, const char* sub) {const char *bp;const char *sp;//判断src与sub的有效性if (src == NULL || sub == NULL ) {return src;}//遍历src字符串,也就是src的子串挨个与sub比较while (*src) {bp = src; //用于src的遍历sp = sub; //用于sub的遍历//遍历sub字符串do { //如果到了sub字符串结束符位置,表示找到了sub字符串,退出if (!*sp)return src;} while (*bp++ == *sp++);src += 1;}return NULL;
}int main() {char p[] = "12345";char q[] = "34";char *r = strstr(p, q);printf("r:%s\n", r);system("pause");return 0;
}
9、面试题9
编程实现字符串中各单词的翻转:将句子中的单词位置倒置,而不改变单词内部的结构。
#include <iostream>
using namespace std;
//
void RevStr(char *src) {char *start = src;char *end = src;char *ptr = src;//while (*ptr++ != '\0') { //遍历字符串if (*ptr == ' ' || *ptr == '\0') { //找到一个单词end = ptr - 1; //end指向单词末尾//把单词的字母逆置while (start < end)swap(*start++, *end--);//指向下一个单词开头,单词之间间隔是空格不是'\0'start = end = ptr + 1;}}start = src; //start指向字符串开头end = ptr - 2; //end指向字符串末尾//把整个字符串逆置 while (start < end) {swap(*start++, *end--);}
}int main() {char src[] = "I am from Shanghai";cout << src << "\n";RevStr(src);cout << src << "\n";system("pause");return 0;
}
10、面试题10
**编程判断字符串是否是回文字符串 **。
#include <iostream>
using namespace std;
//
int IsRevStr(char *str) {int i, len;int found = 1;//if (str == NULL) {return -1;}//len = strlen(str); //获取字符串长度for (int i = 0; i < len / 2; i++) {if (*(str + i) != *(str + len - i - 1)) { //遍历中如果发现相应的头尾字符不等,则字符串不是回文字符串found = 0;break;}}return found;
}int main() {char str1[10] = "1234321";char str2[10] = "1234221";//int test1 = IsRevStr(str1);int test2 = IsRevStr(str2);//cout << "str1 is " << (test1 == 1 ? "" : " not") << " reverse string." << endl;cout << "str2 is " << (test2 == 1 ? "" : " not") << " reverse string." << endl;system("pause");return 0;
}
11、面试题11
编程实现stcmp库函数。对于两个字符串str1和str2,若相等,则返回0;若str1大于str2,则返回-1。
#include <iostream>
using namespace std;
//
int mystrcmp(const char *src, const char *dst) {int ret = 0;//循环比较两个字符是否相等,如果不等或者到了dst字符的末尾,则退出循环while (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) {++src;++dst;}//if (ret < 0) {ret = -1;}else if (ret > 0) {ret = 1;}return ret;
}int main() {char str[10] = "1234567";char str1[10] = "1234567"; //str1==strchar str2[10] = "12345678"; //str2 > str1char str3[10] = "1234566"; //str3 < str//测试int test1 = mystrcmp(str, str1);int test2 = mystrcmp(str, str2);int test3 = mystrcmp(str, str3);cout << "test1= " << test1 << endl;cout << "test2= " << test2 << endl;cout << "test3= " << test3 << endl;system("pause");return 0;
}
mystrcmp()函数对两个字符串同时进行一次遍历,当它们存在不同值时候就停止循环,最后根据他们最后一个字符的大小,返回相应的结果。
12、面试题12
编程查找两个字符串的最大公共子串:对于两个字符串A和B,如果A="“aocdfe”,B=“pmcdfa”,则输出"cdf"。
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;char *commonstring(char *str1, char *str2) {int i, j;char *shortstr, *longstr;char *substr;//判断两个字符的有效性if (str1 == NULL || str2 == NULL) {return NULL;}//两个指针分别指向较短和较长的字符串if (strlen(str1) <= strlen(str2)) {shortstr = str1;longstr = str2;}else {shortstr = str2;longstr = str1;}//如果在较长的字符串中找到较小的字符串,则返回短字符串if (strstr(longstr, shortstr) != NULL) {return shortstr;}//申请 堆内存 存放返回结果substr = (char *)malloc(sizeof(char)*(strlen(shortstr) + 1));//循环取短串的子串放入堆内存,调用strstr函数检查长串中是否包含这个子串,如果有,则返回堆内存。这个短串长度不断减少的for (i = strlen(shortstr) - 1; i > 0; i--) {for (j = 0; j <= strlen(shortstr) - i; j++) {//将短字符串的一部分复制到substr中memcpy(substr, &shortstr[j], i);substr[i] = '\0';//如果在较长的字符串中找到较小的字符串,则返回短字符串if (strstr(longstr, substr) != NULL) {return substr;}}return NULL;}
}//int main(){char *str1 = (char *)malloc(256);char *str2 = (char *)malloc(256);char *common = NULL;gets_s(str1,20);gets_s(str2,20);common = commonstring(str2, str1);printf("the longest common string is:%s\n", common);system("pause");return 0;}
13、面试题13
不使用printf,将十进制以二进制和十六进制的形式输出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
char *get2String(long num) { //得到二进制形式的字符串int i = 0;char *buffer;char* temp;//long型整数是4个字节,每个8位,一共32位。申请了33个字节(包括'\0')的堆内存存放结果buffer = (char*)malloc(33);temp = buffer; //temp//给数组的32个元素赋值0或者1for (i = 0; i < 32; i++) {temp[i] = num&(1 << (31 - i));temp[i] = temp[i] >> (31 - i);temp[i] = (temp[i] == 0) ? '0' : '1';}buffer[32] = '\0'; //字符串结束符return buffer;
}char *get16String(long num) {int i = 0;char *buffer = (char*)malloc(11); //这边申请了11个字节,包括'0','x','\0'char *temp;buffer[0] = '0';buffer[1] = 'x';buffer[10] = '\0';temp = buffer + 2;//for (i = 0; i < 8; i++) {temp[i] = (char)(num << 4 * i >> 28);temp[i] = temp[i] >= 0 ? temp[i] : temp[i] + 16;temp[i] = temp[i] < 10 ? temp[i] + 48 : temp[i] + 55;}return buffer;}int main() {char *p = NULL;char *q = NULL;int num = 0;printf("input num:"); //输入整数scanf_s("%d", &num);p = get16String(num); //得到十六进制的字符串q = get2String(num); //得到二进制形式的字符串printf("%s\n", p);printf("%s\n", q);system("pause");return 0;
}
14、面试题14
编程实现转换字符串、插入字符的个数:例如字符串 aaab,插入字符个数就变成 aaa3b1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAXCOUNT 2*100char *transformation(char *str) {int len = strlen(str);char *buf = new char[len + 1]; //申请llen(str)+1个堆内存来存放字符串数字相关的信息//char *p = str;char *q = p + 1;int count = 1;//这个str到结束符为止while (*q) {//如果前一个和后一个相等,指针后移,计数增加if (*p == *q) {count++;p++;q++;}else { //如果不等itoa(count, buf, 10); //把整数转成字符串int nbits = strlen(buf);strcat(buf, q); //buf里面保存3b*q = 0;strcat(str, buf); //str里面保存aaa q = q + nbits;p = q;q = p + 1;count = 1;}}itoa(count, buf, 10);strcat(str, buf);//释放堆内存delete[]buf;buf = NULL;return str;
}int main() {char str[MAXCOUNT];printf("please input a string:");scanf_s("%s", &str);printf("before transformation:%s\n", str);char *pstr = transformation(str);printf("after transformation:%s\n", pstr);system("pause");return 0;
}
遍历aaab,直到找到不同的字符,然后在buf中保存3b,把str变成aaa(字符‘b’的位置内存设为0)。然后执行strcat(str,buf),此时str变成aaa3b,计数设为1.如果退出循环,则将最后一个字符个数存入buf,此时str中为aaa3b,并且调用strcat,结果strbiancheng aaa3b1。
15、面试题15
字符串编码例题:把一个小于20的字符串 遵循三个规则:
- 把字符串中的字母替换成它的第4个字母,例如:a->e,A->E,X->b,y->c,z->d。
- 如果字符不是字母,则忽略替换;
- 翻转整个字符串;
#include <iostream>
using namespace std;char LowerCaseAlphabets[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};char UpperCaseAlphabets[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};char GetFourthChar(char chrSource, char alphabets[]) {for (int i = 0; i < 26; i++) {if (alphabets[i] == chrSource) {int index = (i + 4) % 26;return alphabets[index]; }}return '\0';
}void ReplaceChars(char chars[], int len) {for (int i = 0; i < len; i++) {if ('a' <= chars[i] && chars[i] <= 'z') {chars[i] = GetFourthChar(chars[i], LowerCaseAlphabets);}else if('A' <= chars[i] && chars[i] <= 'Z'){chars[i] = GetFourthChar(chars[i], UpperCaseAlphabets);}}
};
//翻转整个字符串
void ReverseString(char str[], int len) {int begin = 0;int end = len - 1;//if (str[end] == '\0') {end--;}//char hold;while (begin < end) {hold = str[begin];str[begin] = str[end];str[end] = hold;//begin++;end--;}
};void EncodeString(char str[], int len) {ReplaceChars(str, len); //替代字符ReverseString(str, len); //翻转整个字符串
}int main() {char hello[] = "hasd11H";EncodeString(hello, strlen(hello));cout << hello << endl;system("pause");return 0;
}
16、面试题16
反转字符串,但其指定的字符串的子串:给定一个字符串和一个子串,将第一个字符串反转,但保留子串的顺序 :
- 扫描一遍第一个字符串,然后用stack把它反转,同时记录下子串出现的位置;
- 扫描一遍把记录下来的子串再用stack反转;
- 将堆栈里面的字符弹出,这样子串又恢复了原来的顺序;
#include <iostream>
#include <cassert>
#include <stack>
using namespace std;const char* reverse1(const char* s1, const char* token) { //这边s1是字符串,token是字符串的子串stack<char> stack1; //这边建立一个堆const char* ptoken = token, *head = s1, *rear = s1;assert(s1 && token);//while (*head != '\0') { //表示该字符串没有到头//while (*head != '\0'&&*ptoken == *head) { //表示字符串里面与子串相等ptoken++;head++;}//这边表示子串已经走到最后了,走到最后则将它倒过来压入堆栈if (*ptoken == '\0') {const char* p;for (p = head - 1; p >= rear; p--) {stack1.push(*p);}ptoken = token;rear = head;} //否则直接压入堆栈else {stack1.push(*rear++);head = rear;ptoken = token;}}char *pReturn = new char[strlen(s1) + 1];int i = 0;while (!stack1.empty()) {pReturn[i++] = stack1.top();stack1.pop();}pReturn[i] = '\0';return pReturn;
}int main(int argc, char* argv[]) {char welcome[] = "Welcome you, my friend"; //字符串char token[] = "you"; //字符串的子串const char *pRev = reverse1(welcome, token);cout << "before reverse:" << endl;cout << welcome << endl;cout << "after reverse:" << endl;cout << pRev << endl;system("pause");return 0;
}
17、面试题17
编写字符串反转函数strrev。
//解法1:第一个和最后一个交换,依次
#include <string>
char* strrev1(const char* str) {int len = strlen(str);char* tmp = new char[len + 1];//strcpy(tmp, str);for (int i = 0; i < len / 2; ++i) {char c = tmp[i];tmp[i] = tmp[len - i - 1];tmp[len - i - 1] = c;}return tmp;
}//解法2:指针形式
char* strrev2(const char* str) {char* tmp = new char[strlen(str) + 1];strcpy(tmp,str);char* ret = tmp;char* p = tmp + strlen(str) - 1;while (p > tmp) {char t = *tmp;*tmp = *p;*p = t;--p;--tmp;}return ret;
}//解法3,优化,使用异或优化
char* strrev3(const char* str) {char* tmp = new char[strlen(str) + 1];strcpy(tmp, str);char* ret = tmp;char* p = tmp + strlen(str) - 1;while (p > tmp) {*p ^= *tmp;*tmp ^= *p;*p ^= *tmp;--p;++tmp;}return ret;}//解法4
char* strrev4(const char* str) {char* tmp = new char[strlen(str) + 1];strcpy(tmp, str);char* ret = tmp;char* p = tmp + strlen(str) - 1;while (p > tmp) {*p = *p + *tmp;*tmp = *p - *tmp;*p = *p - *tmp;--p;++tmp;}return ret;
}//解法5:使用递归
char* reverse5(char* str, int len) {if (len <= 1) {return str;}//char t = *str;*str = *(str + len - 1);*(str + len - 1) = t;return (reverse5(str + 1, len - 2) - 1);
}
18、面试题18
编程实现任意长度的两个正整数相加。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>char* addBigInt(char* num1, char* num2) {//c为进位,开始最低进位为0;//i指向第一个加数的最低位//j指向第二个加数的最低位int c = 0, i = strlen(num1) - 1, j = strlen(num2) - 1;//两个数中较大数的位数int maxLength = strlen(num1) >= strlen(num2) ? strlen(num1) + 1 : strlen(num2) + 1;//保留结果char* rst = (char*)malloc(maxLength + 1);//这边判断申请的内存是否成功if (rst == NULL) {printf("malloc error!\n");exit(1);}//字符串最后一位为'\0'rst[maxLength] = '\0';//指向结果数组的最低位int k;k = strlen(rst) - 1;//while ((i >= 0) && (j >= 0)) {rst[k] = ((num1[i] - '0') + (num2[j] - '0') + c) % 10 + '0';c = ((num1[i] - '0') + (num2[j] - '0') + c) / 10;--i;--j;--k;}//这边是个弥补while (i >= 0) {rst[k] = ((num1[i] - '0') + c) % 10 + '0';c = ((num1[i] - '0') + c) / 10;--i;--k;}//这边是个弥补while (j >= 0) {rst[k] = ((num1[j] - '0') + c) % 10 + '0';c = ((num2[j] - '0') + c) / 10;--j;--k;}//rst[0] = c + '0';//如果结果最高位不等于0,则输出结果if (rst[0] != '0') {return rst;}else {return rst + 1;}
}int main() {char num1[] = "123456789323";char num2[] = "45671254563123";char *result = NULL;result = addBigInt(num1, num2);printf("%s + %s = %s\n", num1, num2, result);system("pause");return 0;
}
19、面试题19
编程实现字符串的循环右移:编写函数把一个char组成的字符串循环右移n个。如:abdcefghi,若年,则为hiabcdefg:首先计算字符串尾部移到头部的字符个数,然后分配一个相同大小的堆内存来临时保存这些字符,最后做两次循环分别把头部字符移位到尾部,以及把堆内存中的内容复制到字符串头部。
#include <stdio.h>
#include <stdlib.h>void loopMove(char *str, int n) {int i = 0;char *temp = NULL;int strLen = 0;char *head = str; //指向字符串头//这边str走到字符串末尾了while (*str++);//计算字符串长度strLen = str - head - 1;//计算字符串尾部移到头部的字符n = n % strLen;//分配内存temp = (char *)malloc(n);//for (i = 0; i < n; i++) {temp[i] = head[strLen - n + i];}//for (i = strLen - 1; i >= n; i--) {head[i] = head[i - n];}//for (i = 0; i < n; i++) {head[i] = temp[i];}//消逝内存free(temp);
}int main() {char string[] = "123456789";int steps = 0;printf("string:%s\n", string);printf("input step:");scanf_s("%d", &steps);loopMove(string, steps);printf("after loopMove %d:%s\n", steps, string);system("pause");return 0;
}
20、面试题20
删除指定长度的字符。
#include <stdio.h>
#include <iostream>
#include <string.h>//str:字符串 pos:从该位置开始 len:删除的长度
char *deleteChars(char *str, int pos, int len) {char *p = str + pos - 1; //找到开始的位置int tt = strlen(str); //字符串的长度if ((pos < 1) || (p - str) > tt) {return str;}//if ((p + len - str) > tt) {*p = '\0';return str;}//删除len个字符while (*p & &*(p + len)) {*p = *(p + len);p++;}*p = '\0';return str;
}int main() {char string[] = "abcdefg";int pos = 0;int len = 0;int steps = 0;printf("string:%s\n", string);printf("input pos:");scanf_s("%d", &pos);printf("input len:");scanf_s("%d", &len);deleteChars(string, pos, len);printf("after delete %d chars behind pos %d:%s\n", len, pos, string);system("pause");return 0;
}
21、面试题21
字符串的排序以及交换: 编写一个函数将字符串分为两部分,将前半部分按升序排序,后半部分不变,若为奇数,则中间的字符不变。再将前后两部分交换,最后将字符串输出。
#include <stdio.h>
#include <stdlib.h>//冒泡排序算法
void mysort(char *str, int num) {int i, j;int temp = 0;//for (i = 0; i < num; i++) {for (j = i + 1; j < num; j++) {if (str[i] < str[j]) {temp = str[i];str[i] = str[j];str[j] = temp;}}}
}char *foo(char *str) {if (str == NULL)return NULL;// char *start = NULL;start = str; //这是头部的位置//此时str是尾部的位置 while (*str++);int len = 0;len = str - start - 1;len = len / 2;str = start;mysort(str, len);return str;
}int main() {char string[] = "ADZDDJKJFIEJHGI";printf("before transformation:%s\n", string);foo(string); //调用冒泡排序方法进行排序printf("after transformation:%s\n", string);system("pause");return 0;
}
22、面试题22
编程实现删除字符串中所有指定的字符:。
#include <stdio.h>
#include <iostream>char *deleteChar(char *str, char c) {//if (str == NULL) {return NULL;}//head与p都设置为头节点那边char *head = NULL;char *p = NULL;head = p = str;//while (*p++) {if (*p != c) {*str++ = *p;}}*str = '\0';return head;
}
//
int main() {char string[] = "cabcdefcgchci";char c = 0;printf("input char:");scanf_s("%c", &c);printf("before delete:%s\n", string);deleteChar(string, c); //删除所有的cprintf("after delete:%s\n", string);system("pause");return 0;
}
23、面试题23
使用strcat连接字符串,strcat的原型为:
e x t e r n c h a r ∗ s t r c a t ( c h a r ∗ d e s t , c o n s t c h a r ∗ s r c ) extern \ char \ *strcat(char \ *dest,\ const \ char \ *src) extern char ∗strcat(char ∗dest, const char ∗src)
#include <iostream>
using namespace std;int main() {char *str1 = "hello";char *str2 = "china";char *str3 = NULL;//这边用new申请的堆内存没有被初始化str3 = new char[strlen(str1) + strlen(str2) + 1];//str3[0] = '\n';str3[0] = '\0';//上面的堆内存没有初始化,不含有字符串结束符,输出的是随机值。strcat(str3, str1);strcat(str3, str2);cout << str3 << endl;system("pause");return 0;
}
24、面试题24
编程实现strcat。
#include <stdio.h>
#include <stdlib.h>char *mystrcat(char *dest, const char *src) {char *ret;//保存目的字符串首地址以便返回ret = dest;while (*dest++);//此时dest指向字符串结束符dest--;//循环复制while (*dest++ = *src++);return ret;
}int main() {char *dest = NULL;char *str1 = "Hello";char *str2 = "World!";dest = (char *)malloc(256);*dest = '\0';mystrcat(mystrcat(dest, str1), str2);printf("dest:%s\n", dest);free(dest);dest = NULL;system("pause");return 0;
}
25、面试题25
**编程计算含有汉字的字符串长度:编写gbk_strlen函数,计算含有汉字的字符串长度,汉字作为一个字符处理,已知:汉字编码为双字节,其中首字节<0,尾字节在063以外(如果一个字节是-128127) **。
#include <iostream>
using namespace std;int gbk_strlen(const char *str) {const char *p = str; //头节点,p也用于后面的遍历//使用两个指针指向的地址之差来获取字符串长度//若是结束符0,则结束循环while (*p) {//汉字编码为双字节,其中首字节<0,尾字节在0~63以外if (*p < 0 && (*(p + 1) < 0 || *(p + 1) > 63)) { //中文汉字情况str++; //str移动一位,p移动两位,因此长度+1p = p + 2;}else {p++;}}return p - str;
}int main() {char str[] = "abc你好123中国456";int len = gbk_strlen(str);cout << str << endl;cout << "len = " << len << endl;system("pause");return 0;
}
26、面试题26
找出01字符串中0和1连续出现的最大次数。
#include <iostream>
using namespace std;void Calculate(const char *str, int *max0, int *max1) {int temp0 = 0; //保存连续是'0'的最大长度int temp1 = 0; //保存连续是'1'的最大长度while (*str) { //遍历字符串if (*str == '0') { //当前字符为‘0’(*max0)++; //‘0’的计算长度加1if (*(++str) == '1') { //如果下一个字符是'1'//判断当前最大长度是否需要保存if (temp0 < *max0) {temp0 = *max0;}*max0 = 0;}}else if (*str == '1') {(*max1)++;if (*(++str) == '0') {if (temp1 < *max1) {temp1 = *max1;}*max1 = 0;}}}*max0 = temp0;*max1 = temp1;
}int main() {char string[] = "000011101100000001100110101101001010101011111010";int max0 = 0; //保存连续是'0'的最大长度int max1 = 0; //保存连续是'1'的最大长度Calculate(string, &max0, &max1);cout << "max0 = " << max0 << endl;cout << "max1 = " << max1 << endl;system("pause");return 0;
}
27、面试题27
编程实现字符串的替换:用户输入3个字符串,然后把在第一个字符串中出现的所有第2个字符串替换成第三个字符串,最后输出新的字符串。
#include <iostream>
using namespace std;//str为原字符串,sub1:为第2个字符串,sub2为第3个字符串,output为结果
char *replace(const char *str, const char *sub1, const char *sub2, char *output) {char *pOutput = NULL;const char *pStr = NULL;int lenSub1 = strlen(sub1); //子串sub1的长度int lenSub2 = strlen(sub2);//子串sub2的长度pOutput = output;pStr = str; //用于寻找子串while (*pStr != 0) {pStr = strstr(pStr, sub1); //在str中寻找sub1子串if (pStr != NULL) { //找到sub1子串memcpy(pOutput, str, pStr - str); //复制str的前一部分outputpOutput += pStr - str;memcpy(pOutput, sub2, lenSub2); //复制sub2子串到outputpOutput = pOutput + lenSub2;pStr = pStr + lenSub1;str = pStr;}else {break;}}*pOutput = '\0';if (*str != '\0') {strcpy(pOutput, str);}return output;
}int main() {char str[50] = "";char sub1[10] = "";char sub2[10] = "";char output[100] = "";cout << "str:";cin >> str;cout << "sub1:";cin >> sub1;cout << "sub2:";cin >> sub2;cout << replace(str, sub1, sub2, output) << endl;system("pause");return 0;
}
更多推荐
C和C++程序员面试秘笈之④
发布评论