2010年11月12日

數字轉中文的程式段

為了嘗試TDD(測試導向開發, Test-Driven development)
寫了一個數字轉中文的函式

在網路上意外發現,要用這個題目找個簡短一點的C#程式段好像沒想像中多
雖不敢說自己寫的是最好
但可讀性應該還可以
扣掉註解後程式約30行
提供需要的人參考(不考慮小數部分)

有空再寫以測試導向的思維,進行以下開發的過程
也歡迎先進不吝指點一二


public string ConvertNum2CString(int intNum)
{
    if (intNum == 0) return ("零");

    string[] strPosition = {"", "萬", "億"};
    string strTheValue = "";
    string strReturn = ""; //傳回值
    string strMod = "";

    //從尾巴開始,每次處理四個位數
    for (int i = intNum, j = 0; i >= 1; i = i / 10000, j++)
    {
        strTheValue = ConvertNum2CString1000(i % 10000);
        if (!string.IsNullOrEmpty(strTheValue))
        {
            strReturn = strTheValue + strPosition[j] + strMod + strReturn;
        }
        else if (strReturn.Length > 0 && strReturn.Substring(0, 1) != "零") //本位數雖空白 但後面有數字
        {
            strReturn = "零" + strReturn;
        }

        //如果本四個位數不滿四位且非0 則 上一級尾數需加 "零" 如: 五萬零三
        strMod = (i % 10000 > 0 && i % 10000 < 1000) ? "零" : "";
    }
    return (strReturn);
}

/// <summary>
/// 處理千位以下 數字轉中文
/// </summary>
/// <param name="intNum"></param>
/// <returns></returns>
private string ConvertNum2CString1000(int intNum)
{
    string strCString = "零一二三四五六七八九";
    string[] strPosition = {"", "十", "百", "千" };
    string strReturn = ""; //傳回值
    int intTheValue;
    int intPosition = 0; //目前處理到幾位數

    //從尾巴開始,每次處理一個位數
    for (int i = intNum; i >= 1; i = i / 10)
    {
        intTheValue = i % 10; //目前處理數值

        if (intTheValue > 0)    //目前數字 > 0才需加位數
        {
            strReturn = strCString.Substring(intTheValue, 1) + strPosition[intPosition] + strReturn;
        }
        else if (strReturn.Length > 0 && strReturn.Substring(0, 1) != "零")  //目前數字雖為0但後面有數字,且下一位不是零 則加"零"
        {
            strReturn = "零" + strReturn;
        }

        intPosition++;
    }
    return (strReturn);
}





================================================================


附上測試程式

public void ConvertNum2CStringTest1()
{
    BaseUtility objUtility = new BaseUtility();
    Assert.AreEqual("一", objUtility.ConvertNum2CString(1), "未傳回預期的值。");
    Assert.AreEqual("五", objUtility.ConvertNum2CString(5), "未傳回預期的值。");
    Assert.AreEqual("一十", objUtility.ConvertNum2CString(10), "未傳回預期的值。");
    Assert.AreEqual("八十六", objUtility.ConvertNum2CString(86), "未傳回預期的值。");
    Assert.AreEqual("二百五十", objUtility.ConvertNum2CString(250), "未傳回預期的值。");
    Assert.AreEqual("四千二百七十九", objUtility.ConvertNum2CString(4279), "未傳回預期的值。");
    Assert.AreEqual("零", objUtility.ConvertNum2CString(0), "未傳回預期的值。");
    Assert.AreEqual("三百零五", objUtility.ConvertNum2CString(305), "未傳回預期的值。");
    Assert.AreEqual("三千零五", objUtility.ConvertNum2CString(3005), "未傳回預期的值。");
    Assert.AreEqual("一萬", objUtility.ConvertNum2CString(10000), "未傳回預期的值。");
    Assert.AreEqual("五萬三千零五", objUtility.ConvertNum2CString(53005), "未傳回預期的值。");
    Assert.AreEqual("五千萬三千零五", objUtility.ConvertNum2CString(50003005), "未傳回預期的值。");
    Assert.AreEqual("五千二百萬三千零五", objUtility.ConvertNum2CString(52003005), "未傳回預期的值。");
    Assert.AreEqual("五千二百零九萬三千零七十五", objUtility.ConvertNum2CString(52093075), "未傳回預期的值。");
    Assert.AreEqual("五千二百零九萬", objUtility.ConvertNum2CString(52090000), "未傳回預期的值。");
    Assert.AreEqual("一億", objUtility.ConvertNum2CString(100000000), "未傳回預期的值。");
    Assert.AreEqual("五十萬零三", objUtility.ConvertNum2CString(500003), "未傳回預期的值。");
    Assert.AreEqual("二十億零一", objUtility.ConvertNum2CString(2000000001), "未傳回預期的值。");
    Assert.AreEqual("二十億零三百萬零一", objUtility.ConvertNum2CString(2003000001), "未傳回預期的值。");
}

沒有留言:

張貼留言