用C++语言模拟实现"逢10进1"的计算法则
2014-05-02 20:46
330 查看
[作者]
常用网名: 猪头三
出生日期: 1981.XX.XX
生理特征: 男
婚姻状况: 已婚
个人网站: http://www.x86asm.com
Email: pliceman_110@163.com
QQ交流: 643439947
编程生涯: 2001年~至今[13年]
职业生涯: 11年
开发语言: C/C++、80x86ASM、Object Pascal、C#
开发工具: VC++、VC#、Delphi
技能种类: 逆向 驱动 磁盘 文件
研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全
项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测
[序言]
记得在10多年前, 我的编程基本功不是很扎实, 有时想实现一些有趣的功能, 就不知如何下手. 其实造成这种情况有很多因素比如: 数据结构理论 数学理论 操作系统理论...等等这些理论水平的高低都会影响你的代码功能的实现.10多年过去了, 就在去年我突然灵感大发, 终于知道如何用代码模拟实现“逢10进1“手工计算法则, 关于这个问题我一直都很感兴趣, 但偏偏没有认真去研究也没当回事,
所以一直搁置了10多年. 这个问题是一个比我小5岁的编程高手在10多前留给我的, 按照我10多年前的功力, 肯定没法实现, 但作为高中生的他, 轻松搞定. 当时是非常佩服他. 不过, 现在我也可以搞定了. ^_^
[实现原理]
比如给你一个很大的数字字符串比如: 9999999999999999999999999 实现 + 1 之后等于 10000000000000000000000000,这个就涉及很多编程知识点了, 比如: 类型最大数值 字符串遍历 字符转换等等... 如果你用C语言来实现“逢10进1“手工计算法则那将是非常繁琐的, 需要实现一个动态字符数组存放大数据计算之后的结果,
但是如果用C++就简单了, 可以避免重复设计动态字符数组.解决这个核心问题之后, 那么剩下就好办多了. 由于很久不用C++了, 在std::string的遍历代码写法上研究了很久, 反正实现这个功能花费了4个小时, 不过最终实现了“逢10进1“手工计算法则的原理, 心情大爽.
[2014年04月20日更新并优化]
1个星期过去了, 心里还是放不下第一个版本的代码, 因为写得太差了, 今日2014年-04月-20日花费20分钟重新改写, 把原来一共70多行的代码优化到50行代码, 现在干净清爽, 执行效率也比之前快了1秒. 下面的代码重新更新并发布, 同时显示2个版本的代码逻辑思路, 可见第一个版本的代码实在太丑陋, 并附上我电脑的运行效率, 计算1千万耗时12秒左后, 其他朋友也可以玩玩一下,
尝试写一个出来, 然后在比拼一下速度哦, 注意 我的程序耗时结果不能用下面的截图来比较, 应该把我的代码编译发行版之后, 然后在你的机器运行为准.
![](http://img.blog.csdn.net/20140502204230859)
[代码如下]
常用网名: 猪头三
出生日期: 1981.XX.XX
生理特征: 男
婚姻状况: 已婚
个人网站: http://www.x86asm.com
Email: pliceman_110@163.com
QQ交流: 643439947
编程生涯: 2001年~至今[13年]
职业生涯: 11年
开发语言: C/C++、80x86ASM、Object Pascal、C#
开发工具: VC++、VC#、Delphi
技能种类: 逆向 驱动 磁盘 文件
研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全
项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测
[序言]
记得在10多年前, 我的编程基本功不是很扎实, 有时想实现一些有趣的功能, 就不知如何下手. 其实造成这种情况有很多因素比如: 数据结构理论 数学理论 操作系统理论...等等这些理论水平的高低都会影响你的代码功能的实现.10多年过去了, 就在去年我突然灵感大发, 终于知道如何用代码模拟实现“逢10进1“手工计算法则, 关于这个问题我一直都很感兴趣, 但偏偏没有认真去研究也没当回事,
所以一直搁置了10多年. 这个问题是一个比我小5岁的编程高手在10多前留给我的, 按照我10多年前的功力, 肯定没法实现, 但作为高中生的他, 轻松搞定. 当时是非常佩服他. 不过, 现在我也可以搞定了. ^_^
[实现原理]
比如给你一个很大的数字字符串比如: 9999999999999999999999999 实现 + 1 之后等于 10000000000000000000000000,这个就涉及很多编程知识点了, 比如: 类型最大数值 字符串遍历 字符转换等等... 如果你用C语言来实现“逢10进1“手工计算法则那将是非常繁琐的, 需要实现一个动态字符数组存放大数据计算之后的结果,
但是如果用C++就简单了, 可以避免重复设计动态字符数组.解决这个核心问题之后, 那么剩下就好办多了. 由于很久不用C++了, 在std::string的遍历代码写法上研究了很久, 反正实现这个功能花费了4个小时, 不过最终实现了“逢10进1“手工计算法则的原理, 心情大爽.
[2014年04月20日更新并优化]
1个星期过去了, 心里还是放不下第一个版本的代码, 因为写得太差了, 今日2014年-04月-20日花费20分钟重新改写, 把原来一共70多行的代码优化到50行代码, 现在干净清爽, 执行效率也比之前快了1秒. 下面的代码重新更新并发布, 同时显示2个版本的代码逻辑思路, 可见第一个版本的代码实在太丑陋, 并附上我电脑的运行效率, 计算1千万耗时12秒左后, 其他朋友也可以玩玩一下,
尝试写一个出来, 然后在比拼一下速度哦, 注意 我的程序耗时结果不能用下面的截图来比较, 应该把我的代码编译发行版之后, 然后在你的机器运行为准.
[代码如下]
#include <iostream> #include <fstream> #include <algorithm> #include <iterator> #include <string> #include <sstream> #include <time.h> // 模拟手工加法方式: 逢10进1 [原始版] void fun_Count_Carry_old(std::string & str_param_AddResulte); // 模拟手工加法方式: 逢10进1 [优化版] void fun_Count_Carry(std::string & str_param_AddResulte); int _tmain(int argc, _TCHAR* argv[]) { clock_t time_Start, time_Finish; time_Start = clock(); std::string str_Reslut = "0"; for (__int64 int64_Add_Index = 0; int64_Add_Index < 10000000; int64_Add_Index++) { fun_Count_Carry(str_Reslut); } time_Finish = clock(); std::cout << "模拟手工计算: 逢10进1 完成: " << str_Reslut << std::endl; std::cout << "耗时: " << (double)(time_Finish - time_Start) / CLOCKS_PER_SEC << " 秒" << std::endl; getchar(); return 0; } // 模拟手工加法方式: 逢10进1 [原始版] void fun_Count_Carry_old(std::string & str_param_AddResulte) { std::string::reverse_iterator str_iterator_rebegin; std::string::iterator str_iterator_Current; std::string str_Current_Value; std::ostringstream str_itos; int int_Current_Value; bool bool_Next_IsCarry = false; // false 表示不用进位 ture 表示进位 for (str_iterator_rebegin = str_param_AddResulte.rbegin(); str_iterator_rebegin != str_param_AddResulte.rend(); ++str_iterator_rebegin) { // 获取当前位数的数值 str_Current_Value = *str_iterator_rebegin; int_Current_Value = std::stoi(str_Current_Value); // 判断是否进位 if (bool_Next_IsCarry == true) { int_Current_Value++; } else { // 当前位数且不是最高位时, 经过+1处理后,没有进位时则退出 if (str_iterator_rebegin != str_param_AddResulte.rbegin()) { break; } } // 处理逢10进1的逻辑处理 if (int_Current_Value == 10) { // 设置进位标志位 bool_Next_IsCarry = true; // 替换当前位数的数值为0 *str_iterator_rebegin = '0'; } else { if (bool_Next_IsCarry == false) { int_Current_Value++; } // int to string str_itos.str(""); str_itos << int_Current_Value; if (int_Current_Value == 10) { // 设置进位标志位 bool_Next_IsCarry = true; // 替换当前位数的数值为0 *str_iterator_rebegin = '0'; } else { // 替换当前位数的数值 *str_iterator_rebegin = str_itos.str()[0]; bool_Next_IsCarry = false; } } // 处理最高位的添加逻辑 比如: 99 + 1 = 100 需要添加1 if ((str_iterator_rebegin.base() - 1 == str_param_AddResulte.begin()) && (bool_Next_IsCarry == true)) { str_param_AddResulte = "1" + str_param_AddResulte; break; } } return; }// End fun_Count_Carry_old(); // 模拟手工加法方式: 逢10进1 [优化版] void fun_Count_Carry(std::string & str_param_AddResulte) { std::string::reverse_iterator str_iterator_rebegin; std::string::iterator str_iterator_Current; std::string str_Current_Value; std::ostringstream str_itos; int int_Current_Value; for (str_iterator_rebegin = str_param_AddResulte.rbegin(); str_iterator_rebegin != str_param_AddResulte.rend(); ++str_iterator_rebegin) { // 获取当前位数的数值, 并加1 str_Current_Value = *str_iterator_rebegin; int_Current_Value = std::stoi(str_Current_Value) + 1; // 判断是否等于10 if (int_Current_Value == 10) { // 替换当前位数的数值为0 *str_iterator_rebegin = '0'; // 处理最高位的添加逻辑 比如: 99 + 1 = 100 需要添加1 if ((str_iterator_rebegin.base() - 1 == str_param_AddResulte.begin())) { str_param_AddResulte = "1" + str_param_AddResulte; return; } else { continue; } } else { // 替换当前位数的数值 str_itos.str(""); str_itos << int_Current_Value; *str_iterator_rebegin = str_itos.str()[0]; return; } } return; }// End fun_Count_Carry();
相关文章推荐
- 使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数--在实际中的应用
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 数据结构之应用"栈(Stack)"实现: 解析算术表达式及计算
- 数据结构之应用"栈(Stack)"实现: 解析算术表达式及计算
- 安卓上层代码通过onTouch事件模拟实现"onClick"的动作,以及触屏灵敏度的设置
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (转载)
- 计算二进制位"1"的个数
- 10_9_2从类MyClass中派生一个类MyDervedClass,重写GetString(),使用该方法的基类实现代码从基类中返回一个字符串,但在返回的字符串中添加文本"(output fro)"
- 一行代码实现星级评分 "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);
- 【c语言】 模拟实现printf,要求功能: my_printf("dc\ts\ndc\ndc\ts!", ...)
- 给定一个十进制的整数,写下从1开始到N的所有整数,计算其中出现的所有"1"的个数
- 通过javascript直接实现jQuery的$(".class1")方法
- [翻译] Effective C++, 3rd Edition, Item 38: 通过 composition(复合)模拟 "has-a"(有一个)或 "is-implemented-in-terms-of"(是根据……实现的)
- 使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数
- C语言:模拟实现printf,要求功能:print(&quot;ccc\ts!&quot;,&#39;b&#39;,&#39;i&#39;,&#39;t&#39;,&quot;welcome to you&quot;);
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- c语言:模拟实现printf,要求功能:print(&quot;ccc\ts!&quot;,&#39;b&#39;,&#39;i&#39;,&#39;t&#39;,&quot;welcome to you&quot;);
- Struts target is null for setProperty(null, "x", [Ljava.lang.String;@179da9f)以及图片实现提交造成出现重复提交的现象
- Android提高第十篇之AudioRecord实现"助听器"
- js实现"replaceAll"