秋季面试准备(1)——atoi的实现以及C++库函数stringstream
记得去年9月28日赶到交大去听july的算法面试讲座,他给我们出的第一个题目就是用代码实现atoi,限时10mins。由于当时很久没接触编程,当堂没写出来。记得当时讲解的时候就是要我们特别注意边界条件。写程序就像砌围墙,得先把边界条件弄好。转眼一年过去了,再过几个月就要出去hunting job了,现在回顾下atoi这个函数。
1 //判断字符是否是空格等特殊转义字符,这些输入没有显式输入 2 isspace(int x) 3 { 4 if(x==' '||x=='/t'||x=='/n'||x=='/f'||x=='/b'||x=='/r') 5 return 1; 6 else 7 return 0; 8 } 9 //判断是否是数字,过滤掉其他字符如字母,@等符号 10 isdigit(int x) 11 { 12 if(x<='9'&&x>='0') 13 return 1; 14 else 15 return 0; 16 17 } 18 19 //atoi的实现 20 int atoi(const char *nptr) 21 { 22 int c; /* current char */ 23 int total; /* current total */ 24 int sign; /* if '-', then negative, otherwise positive */ 25 26 27 /* skip whitespace */ 28 while ( isspace((int)(unsigned char)*nptr) ) 29 ++nptr; 30 31 //处理正负符号 32 c = (int)(unsigned char)*nptr; 33 sign = c; /* save sign indication */ 34 if (c == '-' || c == '+') 35 c = (int)(unsigned char)*nptr++; //遇到正负号则从下一位开始转换 36 37 38 total = 0; 39 while (isdigit(c)) { 40 total = 10 * total + (c - '0'); /* accumulate digit */ 41 c = (int)(unsigned char)*nptr++; /* get next char */ 42 } 43 44 //负数情况 45 if (sign == '-') 46 return -total; 47 else 48 return total; /* return result, negated if necessary */ 49 } 50
这个函数考察的还是对临界条件的判断,整个代码处理字符串到整型数字的转换只有4行(38-42),其余代码都在处理异常情况。
百度了下,很多IT公司面试算法的第一题都是这个函数,足见其重要性。
PS:扩展(以下内容来源http://www.cppblog.com/Sandywin/archive/2007/07/13/27984.html)
C++中string to int的函数stringstream
头文件<sstream>
e.g:
string result=”10000”;
int n=0;
stream<<result;
stream>>n;//n等于10000
重复利用stringstream对象
如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法;
在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。
在类型转换中使用模板
你可以轻松地定义函数模板来将一个任意的类型转换到特定的目标类型。例如,需要将各种数字值,如int、long、double等等转换成字符串,要使用以一个string类型和一个任意值t为参数的to_string()函数。to_string()函数将t转换为字符串并写入result中。使用str()成员函数来获取流内部缓冲的一份拷贝:
1 template<class T> 2 3 void to_string(string & result,const T& t) 4 5 { 6 7 ostringstream oss;//创建一个流 8 9 oss<<t;//把值传递如流中 10 11 result=oss.str();//获取转换后的字符转并将其写入result 12 }
这样,你就可以轻松地将多种数值转换成字符串了:
to_string(s1,10.5);//double到string
to_string(s2,123);//int到string
to_string(s3,true);//bool到string
可以更进一步定义一个通用的转换模板,用于任意类型之间的转换。函数模板convert()含有两个模板参数out_type和in_value,功能是将in_value值转换成out_type类型:
1 template<class out_type,class in_value> 2 3 out_type convert(const in_value & t) 4 5 { 6 7 stringstream stream; 8 9 stream<<t;//向流中传值 10 11 out_type result;//这里存储转换结果 12 13 stream>>result;//向result中写入值 14 15 return result; 16 17 }
这样使用convert():
double d;
string salary;
string s=”12.56”;
d=convert<double>(s);//d等于12.56
salary=convert<string>(9000.0);//salary等于”9000”
注意:在进行多次转换的时候,必须调用stringstream的成员函数clear()和str("");
#include <sstream> #include <iostream> int main() { std::stringstream stream; int first, second; stream<< "456"; //插入字符串 stream >> first; //转换成int std::cout << first << std::endl; //在进行多次转换前,必须清除stream stream.clear();//清除错误标志 stream.str("");//清除内容“456” stream << true; //插入bool值 stream >> second; //提取出int std::cout << second << std::endl; }