用C++语言模拟实现"逢10进1"的计算法则
来源:互联网 发布:淘宝权冠军打野 编辑:程序博客网 时间:2024/05/17 04:20
[作者]
常用网名: 猪头三
出生日期: 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();
0 0
- 用C++语言模拟实现"逢10进1"的计算法则
- c语言的左右法则
- 用C语言实现距离向量算法的过程模拟
- 用C语言模拟实现通讯录的文件版本
- String函数的模拟实现(c语言)
- 计算整数中1的个数的C语言实现
- 用c语言实现数学多项式的计算
- 用经纬度计算两地之间的距离, C 语言实现。
- 用c语言实现 计算两个数的最大公约数
- 用C语言模拟实现C++多态
- 名列前茅的C语言之算术法则1
- 用C语言实现计算鞍点
- C语言的位运算法则
- C语言或者OC的命名法则
- 模拟实现C语言库函数
- C语言:模拟实现memmove
- C语言:模拟实现memcpy
- C语言:模拟实现strcpy
- 第四十四讲 线程池 (最后一讲)
- 嵌入式Linux之我行——ARM MMU工作原理剖析
- Linux(centos) 中jdk 下载与安装
- 【存储管理】页面的定期换出do_try_to_free_pages()
- gedit不能保存时 提示 gedit 无法在保存新文件时备份原来的文件。您可以忽略此警告继续保存操作,但如果在保存过程中发生了错误,您可能会丢失原文件的副本。仍然要保存吗?
- 用C++语言模拟实现"逢10进1"的计算法则
- getBytes()和ByteArrayInputStream
- java 字符流writer、reader基本操作及理解
- linux arm mmu基础
- linux arm的存储分布那些事之一
- T420s成功加装固态硬盘(SSD)
- [BZOJ1022][SHOI2008][博弈论][Nim游戏]小约翰的游戏
- 经筵日讲
- 兼容的动态载入JS【原】