师兄面试总结编程部分解答之一
2014-08-27 16:21
225 查看
首先感谢朱宏师兄给出的总结,是一些典型的内容。
最近将编程部分看了一遍,并给出了解答,整体内容可能会比较长,可能会分为两到三篇文章里介绍。
一、字符串
1、逆序(百度面试题,要求最小的时间复杂度,个人觉得应该是方法1了)
(1) 双指针头尾互换
(2) 递归互换
(3) STL入栈出栈
2、回文
(1)一个字符串,补充后面的字符组成回文字符串
(2)在一个字符串中,找出最长的回文字符串
(3)一个字符串中,最多有一个字符出现了奇数次,别的字符都出现了偶数次,要求将这个字符串变成回文字符串(要求最少的交换次数,不能开辟新的存储空间)(百度面试题)
3、左/右移动K位
(有时间复杂度的限制,要用三次交换法(剑指offer 221页)
4、itoa
atoi
strcpy
strcat等源代码
最近将编程部分看了一遍,并给出了解答,整体内容可能会比较长,可能会分为两到三篇文章里介绍。
一、字符串
1、逆序(百度面试题,要求最小的时间复杂度,个人觉得应该是方法1了)
(1) 双指针头尾互换
(2) 递归互换
(3) STL入栈出栈
void reverse(char *str) { int len = strlen(str); //双指针头尾互换 char tmp; int start = 0; int end = len - 1; while(start < end) { tmp = *(str + start); *(str + start) = *(str + end); *(str + end) = tmp; start++; end--; } }
2、回文
(1)一个字符串,补充后面的字符组成回文字符串
//对原始字符串继续补充成回文 char *palindromes(char* str) { int len = strlen(str); char* str2 = new char[len*2];//创建新的数组,用来对元素进行存放 for(int i = 0; i < len; i++) { *(str2 + i) = *(str + i); } for(int i = 0; i < len; i++) { *(str2 + len + i) = *(str + (len - 1 - i)); } *(str2 + 2*len) = '\0'; return str2; }
(2)在一个字符串中,找出最长的回文字符串
//找出一个字符串中最长的回文串,符合回文特征的字符子串 //aba & abba均为回文串,这个要首先明确的的一点 void findLongest(char* str) { //给出的思路1,是在字符之间插入'#'以统一奇数串和偶数串,均为奇数串 //利用现有最长子串为依据,由回文串的对称性,可以减少不必要的计算, //具体分析,对称点的最长子串已知,则当前最长子串的最小长度也就可以确定,对称性 int len = strlen(str); const int lenNew = 2 * len + 1; char* str2 = new char[lenNew]; int* p = new int[lenNew]; int max = 0; int id = 0; for(int i = 0; i < len; ++i) { *(str2 + 2 * i) = '#'; *(str2 + 2 * i + 1) = *(str + i); } *(str2 + 2 * len) = '#'; //完成插入操作 //进行统计过程 //p[i] 存储以i位置为中心的最长回文子串长度 //max存储当前最优结果,id存储单签最优结果对应的下标 for(int i = 1; i < lenNew; ++i) { if (max > i) p[i] = p[2 * id - i] > max - i ? max - i: p[2 * id - i];//由于关于id对称,已判断的回文部分不需要再次判断, else p[i] = 1; for(;str2[i - p[i]] == str2[i + p[i]]; p[i]++) ; p[i]--; if(p[i] > max) { max = p[i]; id = i; } } printf("the longest one is %d \n",max); }
(3)一个字符串中,最多有一个字符出现了奇数次,别的字符都出现了偶数次,要求将这个字符串变成回文字符串(要求最少的交换次数,不能开辟新的存储空间)(百度面试题)
//将原有字符串转换成回文串 //给出的测试字符串最多有一个出现奇数次,其他均出现偶数次,在不开辟新的存储空间的前提下,如何实现 //且交换次数尽可能少 void producePralindroms(char* str) { //连续交换,从前向后遍历,并与前面的内容进行比较,如果存在相同则交换到与之对称位置处 //交换的前提条件是对应位置的元素不同,否则,保持原位置继续向后遍历,直至结束 //缺陷,不能够将唯一的奇数元素放到中间位置 //改进,依然是从前向后遍历,在遍历位置,向后遍历到对称位置处,期间存在相同元素,则置换到对称位置,同时跳出内层遍历 //不存在相同元素,则将该元素置换到中间位置,并进行下一轮遍历(新一轮遍历起始位置不变) int len = strlen(str); for(int i = 0; i < (len / 2); i++) { char cur = *(str + i); bool change = false; for(int j = i + 1; j < len - i; j++) { if(*(str + j) == cur ) { //交换 if(j != len - i - 1) { char tmp = *(str + j); *(str + j) = *(str + len - i - 1); *(str + len - i - 1) = tmp; } change = true; break; } } if(!change)//只有在存在奇数个数元素时,才可能出现这个情况 { *(str + i) = *(str + len / 2); *(str + len / 2) = cur; --i; } } printf("%s\n",str); }
3、左/右移动K位
(有时间复杂度的限制,要用三次交换法(剑指offer 221页)
//向左或向右移动k位 //利用翻手法则,三次变换即可 //对[start,end]区间进行翻转操作 void reverse(char* start, char* end) { //最直接的头尾互换即可 while(start < end) { char tmp = *start; *start = *end; *end = tmp; start++; end--; } } void shiftK(char* str,int k) { int len = strlen(str); char* start = str; char* middle = str + len - k; char* end = str + len - 1; reverse(start,middle - 1); reverse(middle, end); reverse(start,end); printf("%s\n",str); }
4、itoa
atoi
strcpy
strcat等源代码
char* myitoa(int num, char* str,int radix) { char index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char* ptr = str; bool isNegative = false; if (num < 0) { num = -1 * num; isNegative = true; } while(num >= radix) { *ptr++ = index[num % radix]; num = num / radix; } if(num) { *ptr++ = index[num]; } if(isNegative) { *ptr++ = '-'; } *ptr='\0'; ptr--; //当前ptr指向内容为num的倒序存在,需要将其进行逆序 char* start = str; char* end = ptr; while(start < end) { char tmp = *start; *start = *end; *end = tmp; start++; end--; } printf("%s\n",str); return str; } //将string转化为整型输出 int myatoi(const char* str) { const char* ptr = str; int num = 0; bool isNegative = false; if(*ptr == '-') { ptr++; isNegative = true; } while(*ptr != '\0') { int tmp = *ptr++ - '0'; num = num * 10 + tmp; } if(isNegative) { num = num * -1; } printf("%d\n",num); return num; } char* myStrcpy(char* dest, char* src) { if(NULL == dest || NULL == src) return NULL; char* ret = dest; while((*dest++ = *src++) != '\0') ; return ret; }
相关文章推荐
- 师兄面试总结编程部分解答之三
- 师兄面试总结编程部分解答之五
- 师兄面试总结编程部分解答之二
- 师兄面试总结编程部分解答之四
- 系统编程部分知识点总结
- 微软面试、经典算法、编程艺术、红黑树4大系列总结
- 微软面试、经典算法、编程艺术、红黑树4大系列总结
- 微软面试、经典算法、编程艺术、红黑树4大系列总结
- Matlab 与 VC++ 混合编程过程详解(含问题部分解答)
- 【转】[IT综合面试]牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结
- 微软面试、经典算法、编程艺术、红黑树4大系列总结
- 关于09年迅雷面试+笔试+上机题目的总结(解答来自网络)
- 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结
- 《linux c 编程一站式学习》课后部分习题解答
- c++服务器编程面试总结
- erlang基础练习-编程指南习题部分解答
- 微软面试、经典算法、编程艺术、红黑树4大系列总结
- 【经验总结】服务器端编程部分概念理解
- 个人项目编程的部分总结1
- perl编程的部分问题总结