Skip to content

Instantly share code, notes, and snippets.

@kirinboy
Created April 24, 2012 14:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kirinboy/2480122 to your computer and use it in GitHub Desktop.
Save kirinboy/2480122 to your computer and use it in GitHub Desktop.
Parse a Chinese number to an arabic number
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChineseNumberParser
{
internal class ChineseNumber
{
private int value;
public int Value
{
get
{
// 小于10的直接返回值
if (Factor <= 1)
{
return value;
}
else
{
int left = (Left != null ? Left.Value : 1) * Factor;
int right = Right != null ? Right.Value : 0;
// 处理”一百七“这种缩写
if (Right != null && Right.Factor == 1 && Right.Left == null && this.Factor > 10)
{
right = right * (this.Factor / 10);
}
return left + right;
}
}
set { this.value = value; }
}
public int Factor { get; private set; }
public ChineseNumber Left { get; set; }
public ChineseNumber Right { get; set; }
public string Text {get;private set;}
private ChineseNumber() { }
public static ChineseNumber Zero { get { return new ChineseNumber { Value = 0, Factor = 0, Text = "零" }; } }
public static ChineseNumber One { get { return new ChineseNumber { Value = 1, Factor = 1, Text = "一" }; } }
public static ChineseNumber Two { get { return new ChineseNumber { Value = 2, Factor = 1, Text = "二" }; } }
public static ChineseNumber Three { get { return new ChineseNumber { Value = 3, Factor = 1, Text = "三" }; } }
public static ChineseNumber Four { get { return new ChineseNumber { Value = 4, Factor = 1, Text = "四" }; } }
public static ChineseNumber Five { get { return new ChineseNumber { Value = 5, Factor = 1, Text = "五" }; } }
public static ChineseNumber Six { get { return new ChineseNumber { Value = 6, Factor = 1, Text = "六" }; } }
public static ChineseNumber Seven { get { return new ChineseNumber { Value = 7, Factor = 1, Text = "七" }; } }
public static ChineseNumber Eight { get { return new ChineseNumber { Value = 8, Factor = 1, Text = "八" }; } }
public static ChineseNumber Nine { get { return new ChineseNumber { Value = 9, Factor = 1, Text = "九" }; } }
public static ChineseNumber Ten { get { return new ChineseNumber { Factor = 10, Text = "十" }; } }
public static ChineseNumber Hundred { get { return new ChineseNumber { Factor = 100, Text = "百" }; } }
public static ChineseNumber Thousand { get { return new ChineseNumber { Factor = 1000, Text = "千" }; } }
public static ChineseNumber TenThousand { get { return new ChineseNumber { Factor = 10000, Text = "万" }; } }
public static ChineseNumber HundredMillion { get { return new ChineseNumber { Factor = 100000000, Text = "亿" }; } }
public static ChineseNumber Parse(char number)
{
return Parse(number.ToString());
}
public static ChineseNumber Parse(string number)
{
switch (number)
{
case "零" : return Zero;
case "一" : return One;
case "二" : return Two;
case "三" : return Three;
case "四" : return Four;
case "五" : return Five;
case "六" : return Six;
case "七" : return Seven;
case "八" : return Eight;
case "九" : return Nine;
case "十" : return Ten;
case "百" : return Hundred;
case "千" : return Thousand;
case "万" : return TenThousand;
case "亿" : return HundredMillion;
default: throw new ArgumentException("not a chinese number");
}
}
public override string ToString()
{
return Value.ToString();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChineseNumberParser
{
public static class Parser
{
public static int ToArabicNumber(this string chineseNumber)
{
if (string.IsNullOrEmpty(chineseNumber))
throw new ArgumentException("not a chinese number");
ChineseNumber root = null;
foreach (var arbic in chineseNumber)
{
var current = ChineseNumber.Parse(arbic);
if (root == null)
{
root = current;
}
else
{
if (current.Factor == root.Factor)
throw new ArgumentException("not a chinese number");
root = BuildChineseNumberTree(root, current);
}
}
return root.Value;
}
private static ChineseNumber BuildChineseNumberTree(ChineseNumber root, ChineseNumber current)
{
if (current.Factor > root.Factor)
{
current.Left = root;
return current;
}
else
{
if (root.Right == null)
{
root.Right = current;
return root;
}
else
{
root.Right = BuildChineseNumberTree(root.Right, current);
return root;
}
}
}
}
}
public void ToArbicNumberTest()
{
Assert.AreEqual(25, "二十五".ToArabicNumber());
Assert.AreEqual(107, "一百零七".ToArabicNumber());
Assert.AreEqual(170, "一百七十".ToArabicNumber());
Assert.AreEqual(513, "五百一十三".ToArabicNumber());
Assert.AreEqual(365894, "三十六万五千八百九十四".ToArabicNumber());
Assert.AreEqual(670000000, "六亿七千万".ToArabicNumber());
Assert.AreEqual(100700000, "一亿零七十万".ToArabicNumber());
Assert.AreEqual(100700000, "一亿七十万".ToArabicNumber());
Assert.AreEqual(170000000, "一亿七".ToArabicNumber());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment