Re: [闲聊] 中文数字转阿拉伯数字

楼主: poewar (☺☻)   2021-11-18 17:06:33
因为在弄ansi绘图软件
所以这边也提供一个尝试用类似的处理方式来转换文字
由左往右逐个char处理,并以万、亿、兆等来结算区块
public ulong GetValue(string s)
{
ulong totalValue = 0;
ulong blockValue = 0;
ulong cellValue = 0;
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
var checkout = Checkout(c); //看是否结算区块
if (checkout.Item1)
{
totalValue += (blockValue + cellValue) * checkout.Item2;
blockValue = 0;
cellValue = 0;
continue;
}
var v = Conv(c);
if (v.Item1)
{
cellValue = v.Item2;
}
else
{
blockValue += (cellValue == 0) ? 1 * v.Item2
: cellValue * v.Item2;
cellValue = 0;
}
}
totalValue += blockValue + cellValue;
return totalValue;
}
//转换判断
public (bool, ulong) Conv(char c) => c switch
{
'零' => (true, 0),
'一' => (true, 1),
'二' => (true, 2),
'两' => (true, 2),
'三' => (true, 3),
'四' => (true, 4),
'五' => (true, 5),
'六' => (true, 6),
'七' => (true, 7),
'八' => (true, 8),
'九' => (true, 9),
'十' => (false, 10),
'百' => (false, 100),
'千' => (false, 1000),
_ => (false, 1),
};
//结算判断
public (bool, ulong) Checkout(char c) => c switch
{
'万' => (true, 10000),
'亿' => (true, 100000000),
'兆' => (true, 1000000000000),
'京' => (true, 10000000000000000),
_ => (false, 1),
};
//Test cases
//string cNum = "一亿两千五百五十万三千三百三十三"; // 125503333 pass
//string cNum = "一亿两千零五万三百零三"; // 120050303 pass
//string cNum = "十五亿零八万一千二百零五"; //1500081205 pass
//string cNum = "两亿"; // 200000000 pass
//string cNum = "三亿零二十六"; // 300000026 pass
//string cNum = "三亿十六"; // 300000016 pass
//string cNum = "三亿零十六"; // 300000016 pass
//string cNum = "百万"; // 1000000 pass
//string cNum = "百八十"; // 180 pass
//string cNum = "千万";
// 10000000 pass (Elapsed = {00:00:00.0006638})
//string cNum = "五亿五百万五百";
// 505000500 pass (Elapsed = {00:00:00.0007338})
//string cNum = "一千八百四十四京六千七百四十四兆
零七百三十七亿零九百五十五万一千六百一十五";
//18,446,744,073,709,551,615 pass (Elapsed = {00:00:00.0008699})
两个字跟37个字基本上没差太多
不确定有没有小问题,不过大致上应该可以用
如果要判断负的话就改一下单位,开头多判断个'负'就好
作者: tsetsethatha (吉星麦造~~~我来了)   2021-11-18 19:22:00
感谢分享

Links booklink

Contact Us: admin [ a t ] ucptt.com