几道面试题,附源码(待续)

来源:互联网 发布:李凌 知象 编辑:程序博客网 时间:2024/06/05 22:39

之前找实习,面试官给的几道面试题,分享一下我的具体做法。

1. 给一串数,把其中多余的空格去掉,比如“I am        leader”,输出的结果是“I am leader”,要求占用内存最小,速度最快。

分析:

要求占用内存最小,肯定要求循环次数最少,拷贝字符串次数最少,至于循环次数的话,我们只想循环一次,至于怎么做呢?我们可以判断空格后面是否还有空格,如果有的话,我们在这里做一个标记mark,利用另外一个标记k记录有多少个多余空格,直到遇到不是空格的字符,这里的关键在于如何判断连续的空格,以及如何越过,关键问题是这个条件怎么写?如果遇到一个空格,假设他的下标是i,我们用while循环挨个去判断接下来有多少空格,累计共k个空格,那怎么把这些空格复制到前面呢?

源码实现:

#include <stdio.h>#include <stdlib.h>#include <string.h>int pickout(char *data, int length) {int mark = 0;int spaces = 0;int i;for (i = 0; i < length; i++) {if (data[i] == ' ') {spaces++;} else {spaces = 0;}if (spaces < 2) {if (mark != i) {data[mark] = data[i];}mark++;}}data[mark] = '\0';return mark;}int main(void) {char data[] = "I am        leader   h! as   ASD";int length = strlen(data);pickout(data, length);printf("%s\n", data);return 0;}

另外一种实现:

#include <stdio.h>#include <stdlib.h>#include <string.h>int pickout(char*data, int length) {int i, k;int mark;for (i = 0, mark = 0; i < length; i++) {if (data[i] == ' ') {k = 0;while (data[i + k + 1] == ' ') {k++;}if (k > 0) {i = i + k;}}if (i > mark) {data[mark] = data[i];}mark++;}data[mark] = '\0';return 0;}int main(void) {char data[] = "I am        leader   h! as   ASD";int length = strlen(data);pickout(data, length);printf("%s\n", data);return 0;}

输出结果是

I am leader h! as ASD

由于只循环一次,所以计算复杂度是n。


2. 给两串按照升序排序好的数列,要求只利用一个循环找出它们中相同的个数,要求占用内存最小,算法复杂度最小。

源码实现:

#include <stdio.h>#include <stdlib.h>#include <string.h>int CalSameNum(int *data1, int length1, int *data2, int length2) {int i = 0, j = 0;int count = 0;if (data1[0] > data2[length2 - 1] || data1[length1 - 1] < data2[0]) {return count;}while (i < length1 && j < length2) {while (data1[i] > data2[j]) {j++;}if (data1[i] == data2[j]) {count++;j++;}i++;}return count;}int main(void) {int data1[] = { 1, 3, 5, 6, 9, 10, 12, 24, 45, 46 };int data2[] = { 1, 4, 6, 7, 9, 12, 32, 45, 46, 50, 102, 345 };int length1 = sizeof(data1) / sizeof(int);int length2 = sizeof(data2) / sizeof(int);int num = 0;num = CalSameNum(data1, length1, data2, length2);printf("%d\n", num);return 0;}


输出结果是:

6

由于只循环一次,所以计算复杂度是n。

3. 给一串数,它们除以4取余,按照余数的大小排列,比如10,3,32,45,65,12...,取余是2,3,0,1,1,0...,那排序的结果是32,12,45,65,10,3...,要求算法复杂度最低。他的复杂度是nlg(n)么?还能否提高?


4. 要求把源码中的注释去掉,比如'/* */',以及“//”。

大体上是字符串匹配。

源代码如下(linux平台):

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <assert.h>#include <sys/mman.h>int EraseNotes(char *path){int fdin;int size = 0, i = 0, mark = 0, p = 0;char *str = NULL;struct stat statbuf;if ((fdin = open(path, O_RDWR)) == -1) {printf("no such file!\n");return 1;}assert(fstat(fdin, &statbuf) == 0);//获取文件大小size = statbuf.st_size;//把c文件map到内存中。str = (char *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fdin, 0);if (str == MAP_FAILED ) {printf("map failed!\n");return 1;}//printf("%s\n", str);for (i = 0; i < size; i++) {if (str[i] == '/' && str[i + 1] == '*') {mark = 1;p = i;} else if (str[i] == '/' && str[i + 1] == '/') {mark = 2;p = i;}if (mark == 1) {if ((str[i] == '*' && str[i + 1] == '/')) {memset(str + p, ' ', i - p + 2);mark = 0;}} else if (mark == 2) {if (str[i] == 0xa) {memset(str + p, ' ', i - p + 1);mark = 0;}}}printf("%s\n", str);//call of mmapmunmap(str, size);close(fdin);return 0;}int main(void) {char *path = "123";EraseNotes(path);return 0;}



123文件中的内容是

//as//* * * * as */main()as12//as//asddasd/* * */

输出结果是

                        main()as12                        


0 0
原创粉丝点击