诺基亚的面试题,考得很深!!!
题目很简单,但是考的很深:
设计一个算法,输入一个字符串,转化为一个整数。
如何设计上面的算法?
我的解决方法:
函数原型:
int atoi(char* pnum, int & error);
需要考虑:
1. 字符串中正负号的考虑。
===》略掉正负号,先转化,转化结果乘上1或-1.
2. 字符串中有不合法字符,如何处理?
===》传入参数中加一个是否正常转化的参数,如果没有错误发生正常转化,参数为0,否则为一个代表某种错误代码的负数。
3. 字符串长度不确定,存储整数的空间不够用,怎么办?
===》存储转化后结果的空间根据字符串长度动态申请。
4. 字符串很长(比如1K个字符),超过整数的最大值,该如何存储?
===》重新定义一个结构体,分别存储大数的高位和低位。
5. 如何知道字符串的长度?
===》通过strlen获得长度或增加参数直接传递。
上面是我能想到的问题以及解决方法,肯定不全面,也有不对的地方,欢迎拍砖!!!
[解决办法]
人家说了是转化成整数了, 你考虑的问题有点多了, 接口还没设计好, 就考虑些有的没得, 你能写出这种实现足够了.
[User:root Time:22:14:20 Path:/home/liangdong/c]$ ./output 0 0 01 -1 12 -2 23 -3 34 -4 45 -5 56 -6 67 -7 78 -8 89 -9 910 -10 1011 -11 1112 -12 1213 -13 1314 -14 1415 -15 1516 -16 1617 -17 1718 -18 1819 -19 1920 -20 2021 -21 2122 -22 2223 -23 2324 -24 2425 -25 2526 -26 2627 -27 2728 -28 2829 -29 2930 -30 3031 -31 3132 -32 3233 -33 3334 -34 3435 -35 3536 -36 3637 -37 3738 -38 3839 -39 3940 -40 4041 -41 4142 -42 4243 -43 4344 -44 4445 -45 4546 -46 4647 -47 4748 -48 4849 -49 49[User:root Time:22:14:21 Path:/home/liangdong/c]$ cat src/main.c #include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>int atoi(const char *nptr) { int factor = 1; if (strncmp(nptr, "+", 1) == 0) { nptr += 1; } else if (strncmp(nptr, "-", 1) == 0) { nptr += 1; factor = -1; } int n = 0; while (*nptr != '\0') { if (!isdigit(*nptr)) { break; } n = (n * 10) + (*nptr - '0'); ++ nptr; } return factor * n;}int main(int argc, char* const argv[]) { char number[20]; int i; for (i = 0; i < 50; ++ i) { snprintf(number, 20, "+%d", i); printf("%d ", atoi(number)); snprintf(number, 20, "-%d", i); printf("%d ", atoi(number)); snprintf(number, 20, "%d", i); printf("%d\n", atoi(number)); } return 0;}
[解决办法]
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>// never return an error int atoi(const char *nptr) { if (nptr == NULL) { return 0; } int factor = 1; if (strncmp(nptr, "+", 1) == 0) { nptr += 1; } else if (strncmp(nptr, "-", 1) == 0) { nptr += 1; factor = -1; } int n = 0; while (*nptr != '\0') { if (!isdigit(*nptr)) { break; } n = (n * 10) + (*nptr - '0'); ++ nptr; } return factor * n;}int main(int argc, char* const argv[]) { char number[20]; int i; for (i = 0; i < 50; ++ i) { snprintf(number, 20, "+%d", i); printf("%d ", atoi(number)); snprintf(number, 20, "-%d", i); printf("%d ", atoi(number)); snprintf(number, 20, "%d", i); printf("%d\n", atoi(number)); } return 0;}
[解决办法]
楼主考虑的还是很多的,嗨,我只考虑整数了
int atoi(u_char *line, size_t n)
{
int value;
if (n == 0) {
return -1;
}
for (value = 0; n--; line++) {
if (*line < '0' || *line > '9') {
return -1;
}
value = value * 10 + (*line - '0');
}
if (value < 0) {
return -1;
} else {
return value;
}
}
[解决办法]
格式化一下代码,
int atoi(u_char *line, size_t n){ int value; if (n == 0) { return -1; } for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return -1; } value = value * 10 + (*line - '0'); } if (value < 0) { return -1; } else { return value; }}
[解决办法]
K&R第二版有这个
[解决办法]
楼主想法不错!
[解决办法]
LZ真的想多了 int返回就表明了
下面是本人版本:
int atoi(char* str,int *err){ int len=lstrlenA(str); int ret=0; int i=0; if('-'==str[0]||'+'==str[0]) { i=1; } for(;i<len;++i) { if(str[i]<'0'||str[i]>'9') { *err=1; ret=0; break; } ret=ret*10+(str[i]-'0'); } if('-'==str[0]) { ret=~ret+1; } return ret;}
[解决办法]
楼主运气好,我去nokia面试的时候的题目是atoi的加强版,
除了传入字符外,还需要一个表示N进制的传入参数,意思是返回任意进制的整数。
表示在半个小时内想出很OK的方案并用英语跟老外沟通解释压力很大。
[解决办法]
#include <stdio.h>#include <ctype.h>int zsh_atoi(const char *str){ int ret = 0; int tmp; int flag = 0; if(!str) return 0; while(isspace(*str)) ++ str; if('-' == *str) { flag = 1; ++str; } while(isdigit(*str)) { tmp = ret * 10 + (*str - '0'); ret = tmp; ++str; } if(flag) return -ret; return ret;}int main(int argc, char *argv[]){ fprintf(stdout, "%d ...\n", zsh_atoi(" 1237891234567788324"));//有没有好的方法判断是否溢出 fprintf(stdout, "%d ...\n", zsh_atoi(" -456")); fprintf(stdout, "%d ...\n", zsh_atoi("789abc")); fprintf(stdout, "%d ...\n", zsh_atoi("abc789")); fprintf(stdout, "%d ...\n", zsh_atoi("-abc")); fprintf(stdout, "%d ...\n", zsh_atoi("-789abc")); fprintf(stdout, "%d ...\n", zsh_atoi("abc789abc")); fprintf(stdout, "%d ...\n", zsh_atoi("-abc789abc")); return 0;}
[解决办法]
先
http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express
右边Visual C++ 2010 Express下面的Select language...下拉选‘简体中文’,再按Install Now按钮
再参考
C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\xtoa.c
[解决办法]
int atoi(const char* string){ if(string == NULL) return 0; int flag = 1; int value = 0; while(isspace(*string)) ++string; if(*string == '-') { flag = -1; ++string; } else if (*string == '+') ++string; while(*string >= '0' && *string <= '9') { value = value *10 + (*string - '0'); ++string; } return value *= flag;}
[解决办法]
思想与下面的代码相似
double filter_f(char *str)//filter input except postive float
{
char str2[10];
double d;
int flag=2,i=0;
for(;str[i]!='\0';i++)
{
switch(str[i])
{case '0':str2[i]='0';break;
case '1':str2[i]='1';break;
case '2':str2[i]='2';break;
case '3':str2[i]='3';break;
case '4':str2[i]='4';break;
case '5':str2[i]='5';break;
case '6':str2[i]='6';break;
case '7':str2[i]='7';break;
case '8':str2[i]='8';break;
case '9':str2[i]='9';break;
case '.':{str2[i]='.';
if(--flag==0)
goto End;}
break;//only permit one '.'
default:{flag=0;goto End;}
}
}
End:
if(!flag)
{cout<<"input error in column:"<<i+1<<endl;//figure out error place
return 0;
}
else
{d=atof(str2);
return d;
}
}
[解决办法]
各位为什么就那么肯定「整数」就一定指「int」?上面的函数原型是楼主的设计,并不是题干给出的。
而且就算int,按照诺记蛋疼又偏执的习惯,它其实是想让你用int32、int64、int128、int256、intxxxx都有可能,区区一个atoi顶个p用
[解决办法]