一面试题:
一个5位数字ABCDE*4=EDCBA,这5个数字不重复,请编程求出来这个数字是多少?
通过审题不难发现一个数字乘以4正好等于这个数字的反转。不妨先写出一个函数,求一数字的反转:
// 反转正整数num,返回反转后的数字。-1表示出错int ReverNum(int num){ if(0 > num) { return -1; } int i = 0; while(0 != num) { i = i*10 + num%10; num/=10; } return i;}
让一个数字乘以4,然后跟这个数字的反转相比较,如果相等,就是答案。
题目提到是一个5位数字。那么我们从[10000,100000]区间开始找:
我们给出完整代码:
#include#include //面试题:一个5位数字ABCDE*4=EDCBA,这5个数字不重复,请编程求出来这个数字是多少int ReverNum(int num);// 反转正整数num,返回反转后的数字。-1表示出错 int main(){ int i = 0; for(i = 10000; i <= 100000; i++) { if(i*4 == ReverNum(i)) { printf("这个数字是%d\n", i); break; } } return 0;}// 反转正整数num,返回反转后的数字。-1表示出错int ReverNum(int num){ if(0 > num) { return -1; } int i = 0; while(0 != num) { i = i*10 + num%10; num/=10; } return i;}
最后输出:这个数字是21978。
这个题目到此就算做完了。但我写这篇博文想说明的其实并不是这些。
我们也许经常遇到过这样的题目:请写一个函数,判断输入字符串是否是回文字符串,如“aabb”、“ABC123321CBA”是回文。
这样的题目解法也很简单:用两个指针分别指向字符串的第一个元素与最后一个元素(不妨叫做头指针与尾指针),比较两个元素的值,如果不相等则可以肯定不是回文;如果相等,头指针++,尾指针--,在头指针仍然大于尾指针的情况下继续比较元素。如果头指针小于等于尾指针时,则字符串是回文。
下面给出代码:
// 判断字符串是否是回文,返回-1表示出错,0表示不是回文,1表示是回文int IsPalindrome(const char *str){ if(NULL == str) { return -1; } // 头尾指针分别指向字符串首尾元素 const char *pHead = str; const char *pTail = str+strlen(str)-1; while(pHead < pTail) { if(*pHead != *pTail) { return 0; } pHead++; pTail--; } return 1;}
求是否是回文这类题目是很简单的,同时也是很熟悉的,而恰恰是因为熟悉才会在面试时失误。
如一道面试题:求一个正整数是否是回文数字(不能用库函数将数字转成字符串)。
当然,看到这里用上面int ReverNum(int num)函数很快就能得出答案,我们不妨称做方法一。
但正是因为题目中有了回文字样,再看了题目限制,不能使用库函数将数字转成字符串。很容易让人有以下思路,我们不妨称做方法二:
1、将数字按位存入字符串数组;(如数字12345转换成“54321”)
2、使用int IsPalindrome(const char *str)的方法检查是否是回文;
对比两个方法,显然方法一要好很多,时间复杂度、空间复杂度都要好。
方法二需要一个O(n)的存储,还需要O(2n)的遍历。
最后,总结一下。经常听说小题目能反映大问题,比如实现C语言库函数就是小题目,但能很大程度上看出一个人的编程素养。
2011-11-07 任洪彩 qdurenhongcai@163.com
转载请注明出处。