用C++语言模拟实现"逢10进1"的计算法则

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




你可能感兴趣的:(用C++语言模拟实现"逢10进1"的计算法则)