计算2的1000次方的面试题
昨天逛脉脉,看见有人发了一道腾讯的面试,计算2 的 1000次方。时间要求20分钟。
觉得这个题有点意思。想尝试做一做。只求作对,不求效率。汗。
计算结果肯定很大。没有任何数值能保存的下。之前用过python,python可以计算相乘。推测结果保存到字符串中。然后输出。
本来想用c++,定义自己的字符串类。然后定义一个*运算符。计算 2 字符串 乘以 0 到 9的字符串。计算结果保存到字符串中。迭代使用字符串。来计算最终结果。唯一注意的是要设计一个标记,看有没有进位。还没动手就想了很多,要考虑很多问题。有些复杂。
后来还是考虑用c语言来实现。无论如何,都要使用容器来保存运行结果。容器最常使用的是vector。存放的元素我存放了int.那数值怎么存呢。比如说 123这个数字。vector 里面第0个元素存1 还是存 3. 存1的话,符合使用数值的习惯。
但是对于有进位的处理会麻烦一点。要申请一个新空间。比现在的多。拷贝原有的。再存进位。原不如存1方便。只需要考虑边界,是不是最后一个元素,乘法有进位。有进位的push 进1 ,否则修改原有vector 值。
代码写的比较随意。
先定义一个函数。存入一个数值,要求0-9。输出 2 * 这个数值的结果 。 这个结果 小于 10.如果 大于9.设置进位
代码如下
1 int CalcNum(int nNum, bool& bOverFlag) 2 { 3 if ((nNum < 0 ) || (nNum > 9)) 4 { 5 return -1; 6 } 7 8 int nCalcNum = 2 * nNum; 9 bOverFlag = nCalcNum > 9; 10 return nCalcNum % 10; 11 }
现在假想一个容器中,存放 123,要计算乘以2的结果。那得遍历容器中的每一位,乘以2 .然后考虑进位。
进位要考虑首和尾,首元素肯定没有进位。因为第一个。尾元素如果进位的话,只需要在容器末尾push(1)进去就可以 了。 对于中间的任意一位。要考虑它的前一位有没有进位。
针对以上的考虑。写出代码如下。
1 void CalcVector(std::vector<int> & vecNums) 2 { 3 bool bPreOverFlag = false; 4 bool bCurrentOverFlag = false; 5 int nResult = 0; 6 int nMaxSize = vecNums.size(); 7 8 for (int i = 0; i < nMaxSize; i++) 9 { 10 bCurrentOverFlag = false; 11 12 nResult = CalcNum(vecNums.at(i), bCurrentOverFlag); 13 if (-1 == nResult) 14 { 15 printf("error happens\n"); 16 break; 17 } 18 19 if (bPreOverFlag) 20 { 21 vecNums.at(i) = nResult + 1; 22 bPreOverFlag = false; 23 } 24 else 25 { 26 vecNums.at(i) = nResult; 27 } 28 29 if (bCurrentOverFlag) 30 { 31 if (i == (nMaxSize - 1)) 32 { 33 vecNums.push_back(1); 34 } 35 else 36 { 37 bPreOverFlag = true; 38 } 39 } 40 } 41 }
最后就是调用和输出了。
1 std::vector<int> vecResult; 2 vecResult.push_back(1); 3 4 for (int i = 0; i < 1000; i++) 5 { 6 CalcVector(vecResult); 7 } 8 9 10 printf("the result is :\n"); 11 12 for (std::vector<int>::reverse_iterator it = vecResult.rbegin(); it != vecResult.rend(); ++it) 13 { 14 printf("%d", *it); 15 } 16 printf("\n");
如果你有更好的办法,留个言。