[算法题] 人民币大小写转换(阿拉伯数字和汉字转换)

简介: 在一次面试中遇到一个有意思的小算法题:要求将阿拉伯数字转为汉字显示出来(包含单位)。 当时虽然实现出来,但是代码写的有点凌乱。所以回家后,重新整理了一下。   这个算法有几个小的注意点: 1、中文字符占两个字节,所以如果用C语言实现,需要用char数组的形式保存单个汉字。

在一次面试中遇到一个有意思的小算法题:要求将阿拉伯数字转为汉字显示出来(包含单位)。

当时虽然实现出来,但是代码写的有点凌乱。所以回家后,重新整理了一下。

 

这个算法有几个小的注意点:

1、中文字符占两个字节,所以如果用C语言实现,需要用char数组的形式保存单个汉字。

2、如果数字中出现连续的零,需要把它替换为单一的零。

3、在亿、万、元的前面一个汉字不可以为零(人民币读取方式决定)。

4、double数值可分为整数部分和小数部分。小数部分较简单,整数部分需要根据这个数字所在的位数匹配上对应的单位。

具体方法是:设置一个单位映射字符串表g_strUnit,可视为一个简单的HashTable。然后从头开始读取整数字符串的每个

字符,若这个字符在整数字符串的位置为i,这个字符后面的单位就是g_strUnit[length-1-i]。

 

代码如下

/*******************************************************************************
Project Code  : Account
File name     : 
Author        : Latte
Description   : 阿拉伯数字转为中文字符串
Function List :
--------------------------------------------------------------------------------
History:
Date            Author          Modification
20140703        Latte           created file.
******************************************************************************
*/

#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;

#define MAX 100
string g_strDigit[] = {""""""""""""""""""""};

string g_strUnit[] = {"""""""""""""""""亿"
                      """"""""""""};

string g_strUnit2[] = {""""};

/*******************************************************************************
Func Name       : ReplaceSubStr
Date Created    : 2014-07-03
Author          : Latte
Description     : 将源字符串strOrig中第一个匹配strSub的子串部分替换为strReplace
Input           : 
                  string &strOrig, 
                  string strSub, 
                  string strReplace
Output          : 
                  string &strOrig
Return          : 
                  int
Caution         : 返回值如果为-1,则表示替换失败或未找到替换项
******************************************************************************
*/
int ReplaceSubStr(string &strOrig, string strSub, string strReplace)
{
    int pos = (int)strOrig.find(strSub);
    int length = (int)strSub.length();
    
    if (pos >= 0)
    {
        strOrig.replace(pos, length, strReplace);
        return 0;
    }
    
    return -1;
}

/*******************************************************************************
Func Name       : NumToChineseStr
Date Created    : 2014-07-03
Author          : Latte
Description     : 
                  将人民币double数值转化为人民币汉字string
Input           : 
                  double money
Output          : 
Return          : 
                  string
Caution         :
******************************************************************************
*/
string NumToChineseStr(double money)
{
    int i               = 0;
    int ret             = 0;
    int length          = 0;
    char *p             = NULL;
    char *pcDecimal     = NULL; //保存小数部分字符
    char czNumber[MAX]  = {0};  //保存完整数字部分字符
    string strResult;

    cout << "======================================" << endl;
    cout << money << endl;

    //判断是否为小数
    if (money < 0)
    {
        strResult = "不支持读负数";   
        return strResult;   
    }

    //将数字转为数字字符串,利用sprintf_s的正则转换
    sprintf_s(czNumber, MAX, "%.15lg", money);
    printf("[No.0]%s\n", czNumber); 

    //如果数字是太大或太小的数,因为已经转为科学计数,所以会含有e字符
    p = strchr(czNumber,'e');  
    if (NULL!=p) 
    {
        strResult = "不支持读太大或太小的数";
        return strResult;
    }
    
    p = strchr(czNumber, '.');  
    if (NULL != p) 
    {       
        p[0] = 0;    
        pcDecimal = p + 1;   
    }    
    length = (int)strlen(czNumber);  
    
    for (i = 0; i<length; i++) 
    {        
        if ('0' == czNumber[i] && 0 != ((length-1-i) % 4))
        {
            strResult += g_strDigit[czNumber[i] - '0'];
        } 
        else 
        {
            strResult += g_strDigit[czNumber[i] - '0'] + g_strUnit[length-1-i];
        }   
    }
    cout << "[No.1]把数字直接替换为汉字: \n" << strResult << endl;

    //把strResult中的所有"零零"子串替换为"零"
    while (1)
    {
        ret = ReplaceSubStr(strResult, "零零""");
        if (ret < 0)
        {
            break;
        }
    }
    cout << "[No.2]替换所有零零为零: \n" << strResult << endl;

    ReplaceSubStr(strResult, "零亿""亿");
    ReplaceSubStr(strResult, "零万""");
    if (strResult != "零圆")    //如果整数部分全为0,则不要去除元单位前面的零
    {
        ReplaceSubStr(strResult, "零圆""");
    }
    
    cout << "[No.3]去除零亿、零万、零圆前面的零: \n" << strResult << endl;

    //小数精确到两位数,即精确到单位分
    if (NULL != pcDecimal) 
    {
        //如果小数部分有数值而整数部分为0,则删除字符串中的零元
        if (strResult == "零圆")
        {
            strResult.clear();
        }
        i = 0;
        while (1
        {           
            if (0 == pcDecimal[i] || i >= 2
                break;   
            strResult += g_strDigit[pcDecimal[i] - '0'] + g_strUnit2[i];
            i++;      
        }   
    }
    cout << "[No.4]小数精确到两位数,即精确到单位分: \n" << strResult << endl;
    
    return strResult;
}

int main(void)
{
    //cout << "Result: " << NumToChineseStr(0.00) << endl;
    
//cout << "Result: " << NumToChineseStr(-345.67) << endl;
    
//cout << "Result: " << NumToChineseStr(1000.0) << endl;
    cout << "Result: " << NumToChineseStr(130040600090.012) << endl;

    return 0;
}

 

结果

目录
相关文章
|
算法 测试技术 Python
算法分析:阿拉伯数字与罗马数字的互相转换
算法分析:阿拉伯数字与罗马数字的互相转换
158 0
|
算法 iOS开发
iOS 算法之:阿拉伯数字转化为汉语数字
**阿拉伯数字转化为汉语数字** +(NSString *)translation:(NSString *)arebic { NSString *str = arebic; NSArray *arabic_numer...
834 0
|
9天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
15天前
|
机器学习/深度学习 算法 Serverless
基于WOA-SVM的乳腺癌数据分类识别算法matlab仿真,对比BP神经网络和SVM
本项目利用鲸鱼优化算法(WOA)优化支持向量机(SVM)参数,针对乳腺癌早期诊断问题,通过MATLAB 2022a实现。核心代码包括参数初始化、目标函数计算、位置更新等步骤,并附有详细中文注释及操作视频。实验结果显示,WOA-SVM在提高分类精度和泛化能力方面表现出色,为乳腺癌的早期诊断提供了有效的技术支持。
|
3天前
|
存储 算法
基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真
本项目基于HMM模型实现金融数据预测,包括模型训练与预测两部分。在MATLAB2022A上运行,通过计算状态转移和观测概率预测未来值,并绘制了预测值、真实值及预测误差的对比图。HMM模型适用于金融市场的时间序列分析,能够有效捕捉隐藏状态及其转换规律,为金融预测提供有力工具。
|
3天前
|
机器学习/深度学习 算法 信息无障碍
基于GoogleNet深度学习网络的手语识别算法matlab仿真
本项目展示了基于GoogleNet的深度学习手语识别算法,使用Matlab2022a实现。通过卷积神经网络(CNN)识别手语手势,如&quot;How are you&quot;、&quot;I am fine&quot;、&quot;I love you&quot;等。核心在于Inception模块,通过多尺度处理和1x1卷积减少计算量,提高效率。项目附带完整代码及操作视频。
|
11天前
|
算法
基于GA遗传算法的PID控制器参数优化matlab建模与仿真
本项目基于遗传算法(GA)优化PID控制器参数,通过空间状态方程构建控制对象,自定义GA的选择、交叉、变异过程,以提高PID控制性能。与使用通用GA工具箱相比,此方法更灵活、针对性强。MATLAB2022A环境下测试,展示了GA优化前后PID控制效果的显著差异。核心代码实现了遗传算法的迭代优化过程,最终通过适应度函数评估并选择了最优PID参数,显著提升了系统响应速度和稳定性。