C#中如何将整数转换为完整序数词?
在C#中将整数转换为完整英文序数词的实现方案
嘿,这个需求很实际——要把整数转成完整的英文序数词(比如1→First、21→Twenty-First),还不能靠无限字典堆所有可能的映射对吧?其实咱们可以利用英文序数词的规则,拆分数字的不同数位来实现,不用硬存所有组合。
核心规则梳理
英文序数词的规律其实挺清晰的,主要分这几类:
- 1-19是完全特殊的,每个都有单独的序数词(First, Second... Nineteenth)
- 整十数(20,30...90)的序数词是在基数词后加-th,但要注意拼写变化(比如Twenty→Twentieth,Thirty→Thirtieth)
- 非整十的两位数(比如21,32):十位用基数词,个位用序数词,中间加连字符(Twenty-First)
- 三位数及以上:只有最后一部分(最右边的两位或一位)用序数词,前面的部分都用基数词(比如123→One Hundred Twenty-Third,1001→One Thousand First)
代码实现
下面是一个可直接用的C#静态方法,结合递归和基础映射来处理任意正整数:
public static string ConvertToFullOrdinal(int number) { if (number <= 0) throw new ArgumentOutOfRangeException(nameof(number), "只支持正整数转换"); // 1-19的序数词映射 string[] ordinals1To19 = { "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth", "Eleventh", "Twelfth", "Thirteenth", "Fourteenth", "Fifteenth", "Sixteenth", "Seventeenth", "Eighteenth", "Nineteenth" }; // 整十数的序数词映射(索引对应十位数字,比如索引2对应20) string[] ordinalsTens = { "", "", "Twentieth", "Thirtieth", "Fortieth", "Fiftieth", "Sixtieth", "Seventieth", "Eightieth", "Ninetieth" }; // 十位的基数词映射(用于组合非整十数) string[] cardinalTens = { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; // 处理1-19的特殊情况 if (number < 20) return ordinals1To19[number - 1]; // 处理两位数 if (number < 100) { int tens = number / 10; int remainder = number % 10; if (remainder == 0) return ordinalsTens[tens]; else return $"{cardinalTens[tens]}-{ordinals1To19[remainder - 1]}"; } // 处理三位数及以上,递归拆分高位和末尾部分 int divisor = 100; string unit = "Hundred"; if (number >= 1000) { divisor = 1000; unit = "Thousand"; } else if (number >= 1000000) { divisor = 1000000; unit = "Million"; } // 可按需扩展更大单位:Billion、Trillion等 int highPart = number / divisor; int remainder = number % divisor; string highPartStr = ConvertToCardinal(highPart); if (remainder == 0) return $"{highPartStr} {unit}th"; else return $"{highPartStr} {unit} {ConvertToFullOrdinal(remainder)}"; } // 辅助方法:将整数转换为基数词(用于高位部分) private static string ConvertToCardinal(int number) { if (number <= 0) return ""; string[] cardinals1To19 = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }; string[] cardinalTens = { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; if (number < 20) return cardinals1To19[number - 1]; if (number < 100) { int tens = number / 10; int remainder = number % 10; if (remainder == 0) return cardinalTens[tens]; else return $"{cardinalTens[tens]}-{cardinals1To19[remainder - 1]}"; } int hundreds = number / 100; int remainder = number % 100; string remainderStr = ConvertToCardinal(remainder); if (string.IsNullOrEmpty(remainderStr)) return $"{cardinals1To19[hundreds - 1]} Hundred"; else return $"{cardinals1To19[hundreds - 1]} Hundred {remainderStr}"; }
代码逻辑说明
这个方案的核心是只存最基础的映射集合,通过拆分数字+递归组合处理任意大的正整数:
- 优先处理1-19的特殊序数词,直接返回对应值
- 两位数分两种情况:整十数用预存的序数词,非整十数则组合十位基数词和个位序数词
- 三位数及以上时,先把高位转成基数词(比如123的「One Hundred」),再处理末尾的序数部分;如果末尾是0(比如100),就在单位后加-th变成「One Hundredth」
你可以根据需求扩展更大的单位(比如Billion),只需在ConvertToFullOrdinal里新增对应判断即可,不用新增大量映射。
内容的提问来源于stack exchange,提问作者love2code




