[作者]
常用网名: 猪头三
出生日期: 1981.XX.XX
生理特征: 男
婚姻状况: 已婚
个人网站: http://www.x86asm.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();