asp教程.net c# 中文字符与整数之间的互相转换
数字转中文基本思路:
即进行分解
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,一万)区间的翻译*/
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;
}