Created
April 24, 2012 14:31
-
-
Save kirinboy/2480122 to your computer and use it in GitHub Desktop.
Parse a Chinese number to an arabic number
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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