现在的位置: 首页 > 综合 > 正文

我的第一个C#程序,中文与整数互译

2012年09月19日 ⁄ 综合 ⁄ 共 4745字 ⁄ 字号 评论关闭

原创文章如转载请注明:转自¥忘%风 {http://www.cnblogs.com/slave_wc}

本文地址: 我的第一个C#程序,中文与整数互译


测试情况:

1:输入异常判断:

     

  

2:简单数据测试

        

 

  

代码说明概要:

数字转中文基本思路:

  即进行分解

  1:计算最基本的[0,9999]的数字翻译

  2:通过 '万' 字连接两个相邻的由(1)式计算所得的结果,得到[0,99999999]范围的翻译。

  3:通过 '亿' 字连接,得到大数范围内的翻译。

  

中文转数字基本思路:

  主要问题:1:在哪里进行乘法?2:乘法的作用范围呢?

  容易进入的误区:

  1:只考虑在哪里进行乘法,如一千万

    (容易想到如,当计算到'万'字时,离它最近的单位为'千',这种情况下进行乘法,而除乘法外,则进行顺序计算)。 

    **测试数据:一亿三千万。由该算法得到表达式为:1e8 + 3000 * 10000。由于是顺序计算,实际计算时为 (1e8 + 3000) * 10000

          得到了错误答案。

   2:考虑到了(1)中遇到的问题,但对乘法作用范围判断出错。如数据一亿三千万,正确表达式为1e8 + (3000 * 10000)

     误以为进行类似只有 '+' 与 '*' 的算式表达式的计算即可,即考虑了 '*' 与 '+' 的优先级。

    如此如“一亿三千万”能得到正确答案了。

    **测试数据:一亿零一百二十万。按(2)的算法,则为:1e 8 + 100 + (20 * 10000)。

        而实际结果应为:1e8 + (100 + 20) * 10000,得到了错误答案。

  总结出的解法:即考虑1:在哪里进行乘法?2:乘法的作用范围呢?

    **如一亿零一百二十万。当遇到‘万’时,由前面的‘百’<‘万’决定了当前需要进行乘法。

    **再由‘万’之前遇到的第一个 > ‘万’的单位(此处为亿),决定了 乘法的作用范围在两者之间。

    得到该翻译的正确表达式:1e8 + (100 + 20) * 10000。

路过看到有异议欢迎来拍砖

代码简要框架:

private class num2Chinese
{
	private static readonly string unit = "个十百千";
	private static readonly string ala = "0123456789";
	private static readonly string ch = "零一二三四五六七八九";

	private static string transSmall(string num)
	{/*[0,一万)区间的翻译*/
	}

	private static string trans(string num, int range, char ss)
	{/*递归求解。[0,千]通过'万'字可拼接成[0,千万],同理[0,千万]通过亿字连接。
参数含义:
	将num字串按每range作为一组进行分解,并通过ss字符进行连接。(4位一组或八位一组)*/
	}

	public static string transBigInteger(string ss)
	{/*调用trans进行翻译与异常处理,支持大数*/
	}
}

private class ChineseNumConvert
{/*整数转数字类,不支持大数
  关键点:在哪里进行乘法?计算乘法的范围?*/
	private static readonly string Digit = "零一二三四五六七八九";
	private static readonly string Unit = "个十百千万亿";
	private static readonly int[] num = { 1, 10, 100, 1000, 10000, 100000000 };

	private static bool checkString(string word)
	{/*简单判断输入是否合法  1;其他字符。 2:有非零数字相邻*/
	}

	public static long ChineseNum2Int(string word)
	{
	} 
}

代码及必要注释如下:

       private class num2Chinese
        {
            private static readonly string unit = "个十百千";
            private static readonly string ala = "0123456789";
            private static readonly string ch = "零一二三四五六七八九";

            private static string transSmall(string num)
            {/*[0,一万)区间的翻译*/
                string str = "";
                string nn = num.TrimStart('0');
                bool flag = false;
                int j = 0;
                for (int i = nn.Length - 1; i >= 0; i--, j++)
                {
                    int no = ala.IndexOf(nn[i]);
                    if (no != 0) flag = true;
                    if (flag)
                    {
                        if (j != 0 && no != 0)
                            str += unit[j];
                        if (!(no == 0 && str[str.Length - 1] == '零'))
                            str += ch[no];
                    }
                }
                char[] s = str.ToCharArray();
                Array.Reverse(s);
                str = new string(s);
                return str;
            }

            private static string trans(string num, int range, char ss)
            {/*递归求解。[0,千]通过'万'字可拼接成[0,千万],同理[0,千万]通过亿字连接。
			参数含义:
				将num字串按每range作为一组进行分解,并通过ss字符进行连接。(4位一组或八位一组)*/
                string ret = "";
                string input = num.TrimStart('0');

                for (int i = input.Length - range; i > -range; i -= range)
                {
                    int st = i, len = range;/*st与len分别表示每组串的起始位置及长度*/
                    if (i < 0)
                    {
                        st = 0;
                        len = range + i;
                    }
                    string tmp = input.Substring(st, len);
                    long nn = long.Parse(tmp);
                    string cur = "";
                    if (nn == 0)
                    {
                        ret = ss + ret;
                        continue;
                    }
                    if (ss == '万')
                    {
                        cur = transSmall(tmp) + ss;
                    }
                    else
                    {
                        cur = trans(tmp, 4, '万') + ss;
                    }/*计算得到每组的值后,拼接ss字符到末尾*/
                    if (nn % 10 == 0 && ret.Length > 0 && ret[0] != '零')
                    {/*当前组末尾有零时判断是否+零*/
                        int ll = num.Length - st - len;
                        ll = ll > 8 ? 8 : ll;/
						/*最大单位为亿,则当前组之后8位范围内无零则不输出零
						例:一亿零五,零需要输出,一亿亿零五(而非一亿零亿零五)*/
                        string tt = num.Substring(st + len, ll);
                        if (tt.Trim('0') != "")//后八位存在非0值
                            cur += '零';
                    }
                    if (ss == '万' && nn < 1000 ||
                        ss == '亿' && nn < (long)1e7)
                    {/*当前组前位空缺时,前位补零*/
                        cur = '零' + cur;
                    }
                    ret = cur + ret;
                }

                int s = 0, _len = ret.Length - 1;
                if (ret[0] == '零')
                {
                    s = 1;
                    _len--;
                }
                if (ret[ret.Length - 2] == '零')
                {
                    _len--;
                }/*去掉多余的前位零和后位的ss单位符之后的子串*/
                ret = ret.Substring(s, _len);
                return ret;
            }

            public static string transBigInteger(string ss)
            {/*调用trans进行翻译与异常处理,支持大数*/
                string ret = ss.TrimStart('0');
                string tt = "0123456789";
                char[] ch = tt.ToCharArray();
                ret = ret.Trim(' ');
                if (ret.Trim(ch) != "")
                {
                    MessageBox.Show("输入数据非法!");
                    return "";
                }
                if (ret == "")
                {
                    return "零";
                }
                ret = trans(ret, 8, '亿');
                return ret;
            }
        }

        private class ChineseNumConvert
        {/*整数转数字类,不支持大数
		   关键点:在哪里进行乘法?计算乘法的范围?*/
            private static readonly string Digit = "零一二三四五六七八九";
            private static readonly string Unit = "个十百千万亿";
            private static readonly int[] num = { 1, 10, 100, 1000, 10000, 100000000 };

            private static bool checkString(string word)
            {/*简单判断输入是否合法  1;其他字符。 2:有非零数字相邻*/
                word = word.Trim(' ');
                string tt = Digit + Unit;
                string tmp = word.Trim(tt.ToCharArray());
                if (tmp != "")
                    return false;
                for (int i = 0; i < word.Length - 1; i++)
                {
                    if (Digit.IndexOf(word[i]) >= 1
                        && Digit.IndexOf(word[i + 1]) >= 1)
                    {
                        return false;
                    }
                }
                return true;
            }

            public static long ChineseNum2Int(string word)
            {
                if (!checkString(word))
                {
                    MessageBox.Show("输入数据非法!");
                    return 0;
                }
                long sum = 0;
                long tmp = 0;
                long[] tt = new long[150];

                int dig = -1, unit0 = -1, unit1 = -1, unit2 = -1;
                if (Unit.IndexOf(word[0]) >= 0)
                {
                    word = "一" + word;
                }
                if (Unit.IndexOf(word[word.Length - 1]) < 0)
                {
                    if (word.Length >= 2 && (tmp = Unit.IndexOf(word[word.Length - 2])) > 0)
                    {
                        word = word + Unit.ToCharArray()[tmp - 1];
                    }
                    else
                    {
                        word += '个';
                    }
                }
                for (int i = 1; i < word.Length; i++)
                {
                    dig = Digit.IndexOf(word[i - 1]);
                    unit0 = Unit.IndexOf(word[i]);

                    if (unit0 >= 0)
                    {
                        unit1 = -1; unit2 = -1;
                        int idx = -1;
                        for (int j = i - 1; j >= 0; j--)
                        {
                            unit1 = Unit.IndexOf(word[j]);
                            if (unit1 >= 0) break;
                        }//是否需要做乘法
                        for (int j = i - 1; j >= 0; j--)
                        {
                            unit2 = Unit.IndexOf(word[j]);
                            if (unit2 > unit0)
                            {
                                idx = j;
                                break;
                            }
                        }//决定乘法的作用范围
                        if (unit1 >= 0 && unit0 >= unit1)
                        {
                            if (dig >= 0) sum += dig;
                            if (unit2 == -1)
                            {
                                sum *= num[unit0];
                            }
                            else
                            {
                                sum = (sum - tt[idx]) * num[unit0] + tt[idx];
                            }
                        }
                        else
                        {
                            if (dig < 0) dig = 1;
                            sum += dig * num[unit0];
                        }
                    }
                    tt[i] = sum;
                }
                return sum;
            }
        }

抱歉!评论已关闭.