.NET中是否有內置方法將數字轉換爲數字的字符串表示形式?例如,1變成一個,2個變成兩個,等.NET將數字轉換爲字符串表示形式(1對1,2對2等)
回答
我一直是粉絲遞歸方法的
public static string NumberToText(int n)
{
if (n < 0)
return "Minus " + NumberToText(-n);
else if (n == 0)
return "";
else if (n <= 19)
return new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"}[n-1] + " ";
else if (n <= 99)
return new string[] {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety"}[n/10 - 2] + " " + NumberToText(n % 10);
else if (n <= 199)
return "One Hundred " + NumberToText(n % 100);
else if (n <= 999)
return NumberToText(n/100) + "Hundreds " + NumberToText(n % 100);
else if (n <= 1999)
return "One Thousand " + NumberToText(n % 1000);
else if (n <= 999999)
return NumberToText(n/1000) + "Thousands " + NumberToText(n % 1000);
else if (n <= 1999999)
return "One Million " + NumberToText(n % 1000000);
else if (n <= 999999999)
return NumberToText(n/1000000) + "Millions " + NumberToText(n % 1000000);
else if (n <= 1999999999)
return "One Billion " + NumberToText(n % 1000000000);
else
return NumberToText(n/1000000000) + "Billions " + NumberToText(n % 1000000000);
}
很好地完成,你應該修改它,至少得到多頭。 +1 – BenAlabaster 2009-04-27 19:04:51
我喜歡你的代碼,因爲它比balabaster更容易遵循。我對它進行了一些修改,以解釋單個「0」參數(返回「Zero」),接受long而不是int,並且返回Billion而不是Billions,百萬而不是百萬等。好代碼! – 2009-04-27 20:49:25
查看我的帖子以獲取修改後的代碼。 – 2009-04-27 20:51:37
A conversion from integer to long form English... I could write that ;-)是關於這一主題的不錯的文章:
using System;
public class NumberToEnglish {
private static string[] onesMapping =
new string[] {
"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"
};
private static string[] tensMapping =
new string[] {
"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"
};
private static string[] groupMapping =
new string[] {
"Hundred", "Thousand", "Million", "Billion", "Trillion"
};
private static void Main(string[] args) {
Console.WriteLine(EnglishFromNumber(long.Parse(args[0])));
}
private static string EnglishFromNumber(int number) {
return EnglishFromNumber((long) number);
}
private static string EnglishFromNumber(long number) {
if (number == 0) {
return onesMapping[number];
}
string sign = "Positive";
if (number < 0) {
sign = "Negative";
number = Math.Abs(number);
}
string retVal = null;
int group = 0;
while(number > 0) {
int numberToProcess = (int) (number % 1000);
number = number/1000;
string groupDescription = ProcessGroup(numberToProcess);
if (groupDescription != null) {
if (group > 0) {
retVal = groupMapping[group] + " " + retVal;
}
retVal = groupDescription + " " + retVal;
}
group++;
}
return sign + " " + retVal;
}
private static string ProcessGroup(int number) {
int tens = number % 100;
int hundreds = number/100;
string retVal = null;
if (hundreds > 0) {
retVal = onesMapping[hundreds] + " " + groupMapping[0];
}
if (tens > 0) {
if (tens < 20) {
retVal += ((retVal != null) ? " " : "") + onesMapping[tens];
} else {
int ones = tens % 10;
tens = (tens/10) - 2; // 20's offset
retVal += ((retVal != null) ? " " : "") + tensMapping[tens];
if (ones > 0) {
retVal += ((retVal != null) ? " " : "") + onesMapping[ones];
}
}
}
return retVal;
}
}
顯然不是一個代碼高爾夫的競爭者:P – BenAlabaster 2009-04-27 18:30:37
@balabaster:不像代碼高爾夫版本那麼包容,但它*更容易閱讀 – BobTheBuilder 2009-04-27 18:36:58
@BBTheBuilder:是的,但就像我說的那樣,這不是代碼高爾夫的目的:P – BenAlabaster 2009-04-27 18:39:13
啊,有可能不是一個類來做到這一點,但有這是對我提供了一個C#示例代碼高爾夫球問題:
然而,這不是最容易閱讀,而且只上升到decimal.MaxValue,所以我寫了一個新的版本將會盡可能高。
我無法找到任何有關比靜態值更高的值的信息,但是如果將值附加到thou []數組中,則可以繼續向上,只要你喜歡。它仍然不支持分數,但我正考慮在某個時候添加。
static string NumericStringToWords(string NumericValue)
{
if ("0" == NumericValue) return "zero";
string[] units = { "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine" };
string[] teens = { "eleven", "twelve", "thirteen", "four", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen" };
string[] tens = { "ten", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety" };
string[] thou = { "thousand", "million", "billion", "trillion",
"quadrillion", "quintillion", "sextillion",
"septillion", "octillion", "nonillion", "decillion",
"udecillion", "duodecillion", "tredecillion",
"quattuordecillion", "quindecillion", "sexdecillion",
"septendecillion", "octodecillion", "novemdecillion",
"vigintillion" };
string sign = String.Empty;
if ("-" == NumericValue.Substring(0, 1))
{
sign = "minus ";
NumericValue = NumericValue.Substring(1);
}
int maxLen = thou.Length * 3;
int actLen = NumericValue.Length;
if(actLen > maxLen)
throw new InvalidCastException(String.Format("{0} digit number specified exceeds the maximum length of {1} digits. To evaluate this number, you must first expand the thou[] array.", actLen, maxLen));
//Make sure that the value passed in is indeed numeric... we parse the entire string
//rather than just cast to a numeric type to allow us to handle large number types passed
//in as a string. Otherwise, we're limited to the standard data type sizes.
int n; //We don't care about n, but int.TryParse requires it
if (!NumericValue.All(c => int.TryParse(c.ToString(), out n)))
throw new InvalidCastException();
string fraction = String.Empty;
if (NumericValue.Contains("."))
{
string[] split = NumericValue.Split('.');
NumericValue = split[0];
fraction = split[1];
}
StringBuilder word = new StringBuilder();
ulong loopCount = 0;
while (0 < NumericValue.Length)
{
int startPos = Math.Max(0, NumericValue.Length - 3);
string crntBlock = NumericValue.Substring(startPos);
if (0 < crntBlock.Length)
{
//Grab the hundreds tens & units for the current block
int h = crntBlock.Length > 2 ? int.Parse(crntBlock[crntBlock.Length - 3].ToString()) : 0;
int t = crntBlock.Length > 1 ? int.Parse(crntBlock[crntBlock.Length - 2].ToString()) : 0;
int u = crntBlock.Length > 0 ? int.Parse(crntBlock[crntBlock.Length - 1].ToString()) : 0;
StringBuilder thisBlock = new StringBuilder();
if (0 < u)
thisBlock.Append(1 == t? teens[u - 1] : units[u - 1]);
if (1 != t)
{
if (1 < t && 0 < u) thisBlock.Insert(0, "-");
if (0 < t) thisBlock.Insert(0, tens[t - 1]);
}
if (0 < h)
{
if (t > 0 | u > 0) thisBlock.Insert(0, " and ");
thisBlock.Insert(0, String.Format("{0} hundred", units[h - 1]));
}
//Check to see if we've got any data left and add
//appropriate word separator ("and" or ",")
bool MoreLeft = 3 < NumericValue.Length;
if (MoreLeft && (0 == h) && (0 == loopCount))
thisBlock.Insert(0, " and ");
else if (MoreLeft)
thisBlock.Insert(0, String.Format(" {0}, ", thou[loopCount]));
word.Insert(0, thisBlock);
}
//Remove the block we just evaluated from the
//input string for the next loop
NumericValue = NumericValue.Substring(0, startPos);
loopCount++;
}
return word.Insert(0, sign).ToString();
}
我測試了使用Decimal.MaxValue追加到自身,產生了大量的:
7 octodecillion,922 septendecillion,816 sexdecillion,二百五十一萬六千四百二十六萬億,十四億三千三十億,十五億九千五百九十億,三百五十四億十億,三十九億五十億,三十三億,五百億七百九十八,二百二十八,六百二十六,五百四十二,二十四四四獅子三百三十七萬億五十九億三十五億四千三百九十五萬三百三十五
爲了上升到目前爲止......你還應該添加小數位...... – BobTheBuilder 2009-04-27 18:35:43
@BobTheBuilder:大概,也許吧,但我不確定我怎麼寫大部分分數。你會把它們寫成百分之一千分之一,還是隻寫成「零五,三,九......」,或者你把它們寫成五分之三等實際分數? – BenAlabaster 2009-04-27 18:42:46
.1 =「十分之一」,.14 =「十四分之一」,.141 =「百分之一千分之一」等等? = P – 2009-04-27 19:20:24
這裏是修改後的代碼我使用:
//Wrapper class for NumberToText(int n) to account for single zero parameter.
public static string ConvertToStringRepresentation(long number)
{
string result = null;
if (number == 0)
{
result = "Zero";
}
else
{
result = NumberToText(number);
}
return result;
}
//Found at http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,cdceca73-08cd-4c15-aef7-0f9c8096e20a.aspx.
//Modifications from original source:
// Changed parameter type from int to long.
// Changed labels to be singulars instead of plurals (Billions to Billion, Millions to Million, etc.).
private static string NumberToText(long n)
{
if (n < 0)
return "Minus " + NumberToText(-n);
else if (n == 0)
return "";
else if (n <= 19)
return new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"}[n - 1] + " ";
else if (n <= 99)
return new string[] {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety"}[n/10 - 2] + " " + NumberToText(n % 10);
else if (n <= 199)
return "One Hundred " + NumberToText(n % 100);
else if (n <= 999)
return NumberToText(n/100) + "Hundred " + NumberToText(n % 100);
else if (n <= 1999)
return "One Thousand " + NumberToText(n % 1000);
else if (n <= 999999)
return NumberToText(n/1000) + "Thousand " + NumberToText(n % 1000);
else if (n <= 1999999)
return "One Million " + NumberToText(n % 1000000);
else if (n <= 999999999)
return NumberToText(n/1000000) + "Million " + NumberToText(n % 1000000);
else if (n <= 1999999999)
return "One Billion " + NumberToText(n % 1000000000);
else
return NumberToText(n/1000000000) + "Billion " + NumberToText(n % 1000000000);
}
public string IntToString(int number)//nobody really uses negative numbers
{
if(number == 0)
return "zero";
else
if(number == 1)
return "one";
.......
else
if(number == 2147483647)
return "two billion one hundred forty seven million four hundred eighty three thousand six hundred forty seven";
}
此主題是一個很好的幫助。我喜歡Ryan Emerle的解決方案,因爲它的清晰度最好。這裏是我認爲使結構清晰爲白天的版本:
public static class Number
{
static string[] first =
{
"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"
};
static string[] tens =
{
"Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety",
};
/// <summary>
/// Converts the given number to an english sentence.
/// </summary>
/// <param name="n">The number to convert.</param>
/// <returns>The string representation of the number.</returns>
public static string ToSentence(int n)
{
return n == 0 ? first[n] : Step(n);
}
// traverse the number recursively
public static string Step(int n)
{
return n < 0 ? "Minus " + Step(-n):
n == 0 ? "":
n <= 19 ? first[n]:
n <= 99 ? tens[n/10 - 2] + " " + Step(n % 10):
n <= 199 ? "One Hundred " + Step(n % 100):
n <= 999 ? Step(n/100) + "Hundred " + Step(n % 100):
n <= 1999 ? "One Thousand " + Step(n % 1000):
n <= 999999 ? Step(n/1000) + "Thousand " + Step(n % 1000):
n <= 1999999 ? "One Million " + Step(n % 1000000):
n <= 999999999 ? Step(n/1000000) + "Million " + Step(n % 1000000):
n <= 1999999999 ? "One Billion " + Step(n % 1000000000):
Step(n/1000000000) + "Billion " + Step(n % 1000000000);
}
}
+1爲了清楚起見,並將「常數」設置爲靜態值,而不是其他解決方案聲明它們爲內聯。 – drzaus 2013-02-15 16:52:42
這是我的第一個答案的改進版本。我希望這是有用的。
/// <summary>
/// Converts an <see cref="int"/> to its textual representation
/// </summary>
/// <param name="num">
/// The number to convert to text
/// </param>
/// <returns>
/// A textual representation of the given number
/// </returns>
public static string ToText(this int num)
{
StringBuilder result;
if (num < 0)
{
return string.Format("Minus {0}", ToText(-num));
}
if (num == 0)
{
return "Zero";
}
if (num <= 19)
{
var oneToNineteen = new[]
{
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Eleven",
"Twelve",
"Thirteen",
"Fourteen",
"Fifteen",
"Sixteen",
"Seventeen",
"Eighteen",
"Nineteen"
};
return oneToNineteen[num - 1];
}
if (num <= 99)
{
result = new StringBuilder();
var multiplesOfTen = new[]
{
"Twenty",
"Thirty",
"Forty",
"Fifty",
"Sixty",
"Seventy",
"Eighty",
"Ninety"
};
result.Append(multiplesOfTen[(num/10) - 2]);
if (num % 10 != 0)
{
result.Append(" ");
result.Append(ToText(num % 10));
}
return result.ToString();
}
if (num == 100)
{
return "One Hundred";
}
if (num <= 199)
{
return string.Format("One Hundred and {0}", ToText(num % 100));
}
if (num <= 999)
{
result = new StringBuilder((num/100).ToText());
result.Append(" Hundred");
if (num % 100 != 0)
{
result.Append(" and ");
result.Append((num % 100).ToText());
}
return result.ToString();
}
if (num <= 999999)
{
result = new StringBuilder((num/1000).ToText());
result.Append(" Thousand");
if (num % 1000 != 0)
{
switch ((num % 1000) < 100)
{
case true:
result.Append(" and ");
break;
case false:
result.Append(", ");
break;
}
result.Append((num % 1000).ToText());
}
return result.ToString();
}
if (num <= 999999999)
{
result = new StringBuilder((num/1000000).ToText());
result.Append(" Million");
if (num % 1000000 != 0)
{
switch ((num % 1000000) < 100)
{
case true:
result.Append(" and ");
break;
case false:
result.Append(", ");
break;
}
result.Append((num % 1000000).ToText());
}
return result.ToString();
}
result = new StringBuilder((num/1000000000).ToText());
result.Append(" Billion");
if (num % 1000000000 != 0)
{
switch ((num % 1000000000) < 100)
{
case true:
result.Append(" and ");
break;
case false:
result.Append(", ");
break;
}
result.Append((num % 1000000000).ToText());
}
return result.ToString();
}
基於瑞安Emerle的解決方案,這增加了短線在正確的位置,不包括尾隨空格,不以複數數字和妥善處理的輸入零(0):
public static string ToText(long n) {
return _toText(n, true);
}
private static string _toText(long n, bool isFirst = false) {
string result;
if(isFirst && n == 0) {
result = "Zero";
} else if(n < 0) {
result = "Negative " + _toText(-n);
} else if(n == 0) {
result = "";
} else if(n <= 9) {
result = new[] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" }[n - 1] + " ";
} else if(n <= 19) {
result = new[] { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }[n - 10] + (isFirst ? null : " ");
} else if(n <= 99) {
result = new[] { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }[n/10 - 2] + (n % 10 > 0 ? "-" + _toText(n % 10) : null);
} else if(n <= 999) {
result = _toText(n/100) + "Hundred " + _toText(n % 100);
} else if(n <= 999999) {
result = _toText(n/1000) + "Thousand " + _toText(n % 1000);
} else if(n <= 999999999) {
result = _toText(n/1000000) + "Million " + _toText(n % 1000000);
} else {
result = _toText(n/1000000000) + "Billion " + _toText(n % 1000000000);
}
if(isFirst) {
result = result.Trim();
}
return result;
}
.net
沒有內置的解決方案,但周圍有很好的庫。目前最好的肯定是Humanizr:
Console.WriteLine(794663.ToWords()); // => seven hundred and ninety-four thousand six hundred and sixty-three
它還支持順序和羅馬錶示:
Console.WriteLine(794663.ToOrdinalWords()); // => seven hundred and ninety-four thousand six hundred and sixty third
Console.WriteLine(794.ToRoman()); // => DCCXCIV
Humanizr
也有關於string
,DateTime
,TimeSpan
等範圍廣泛的工具。
Console.WriteLine(794.Seconds().Humanize().Underscore().Hyphenate()); // => 13-minutes
另一個在VB.NET中的版本,如果有人感興趣的話!只好用地板功能正確圓..
Public Function NumberToText(n As Integer) As String
Dim a As String() = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}
Dim tens As String() = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety"}
If (n < 0) Then
Return "Minus " + NumberToText(-n)
ElseIf (n = 0) Then
Return ""
ElseIf (n <= 19) Then
Return a(n - 1) + " "
ElseIf (n <= 99) Then
Return tens(Math.Floor(n/10) - 2) + " " + NumberToText(n Mod 10)
ElseIf (n <= 199) Then
Return "One Hundred " + NumberToText(n Mod 100)
ElseIf (n <= 999) Then
Return NumberToText(Math.Floor(n/100)) + "Hundreds " + NumberToText(n Mod 100)
ElseIf (n <= 1999) Then
Return "One Thousand " + NumberToText(n Mod 1000)
ElseIf (n <= 999999) Then
Return NumberToText(Math.Floor(n/1000)) + "Thousands " + NumberToText(n Mod 1000)
ElseIf (n <= 1999999) Then
Return "One Million " + NumberToText(n Mod 1000000)
ElseIf (n <= 999999999) Then
Return NumberToText(Math.Floor(n/1000000)) + "Millions " + NumberToText(n Mod 1000000)
ElseIf (n <= 1999999999) Then
Return "One Billion " + NumberToText(n Mod 1000000000)
Else
Return NumberToText(Math.Floor(n/1000000000)) + "Billions " + NumberToText(n Mod 1000000000)
End If
End Function
這是基於一對夫婦的想法在這裏還公佈了更完整的/改進的方案。包括語法/連字符修復,和可選的資本,長期支持,零支持,但仍然非常簡潔(VB.Net):
Function NumberToCapitalizedWords(ByVal n As Long) As String
Return New System.Globalization.CultureInfo("en-US", False).TextInfo.ToTitleCase(NumberToWords(n))
End Function
Function NumberToWords(ByVal n As Long) As String
Return LTrim(NumberToWords(n, False, False))
End Function
Function NumberToWords(ByVal n As Long, ByVal recursed As Boolean, ByVal iesLast As Boolean) As String
If (n < 0) Then
Return "negative" + NumberToWords(-n, False, False)
ElseIf (n = 0) Then
If recursed Then
Return ""
End If
Return "zero"
ElseIf (n < 20) Then
Return If(iesLast, "-", " ") + New String() {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}(n - 1)
ElseIf (n < 100) Then
Return " " + New String() {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}(n \ 10 - 2) + NumberToWords(n Mod 10, True, True)
ElseIf (n < 1000) Then
Return NumberToWords(n \ 100, True, False) + " hundred" + NumberToWords(n Mod 100, True, False)
Else
Dim log1000 As Integer = Math.Floor(Math.Log(n, 1000))
Return NumberToWords(n \ PowerNoFloat(1000, log1000), True, False) + " " + New String() {"thousand", "million", "billion", "trillion", "quadrillion", "quintillion"}(log1000 - 1) + NumberToWords(n Mod PowerNoFloat(1000, log1000), True, False)
End If
End Function
Function PowerNoFloat(ByRef base As Long, ByRef power As Integer) As Long
If power < 0 Then
Return 0
End If
Dim result As Long = 1
For i As Integer = 1 To power
result *= base
Next
Return result
End Function
我添加了額外的冪函數,因爲內置的語言函數返回一個可能導致差異的double。 – 2015-05-08 18:52:57
- 1. 將.net字符串對象轉換爲base64編碼字符串
- 2. 將表達式轉換爲字符串表示形式?
- 3. C# - 將字符串數據轉換爲實際字符串表示形式
- 4. 將輸入字符串轉換爲六位數表示形式
- 5. 將單詞的整數表示形式轉換爲字符串
- 6. 將對象類型列轉換爲數字,字符串等
- 7. 將表示對象的字符串轉換爲javascript對象
- 8. 將unicode字符串轉換爲十六進制表示形式
- 9. 將Python字符串轉換爲其ASCII碼錶示形式
- 10. Flex將數字字符串轉換爲指數形式
- 11. 將字符串「1/1/1970」轉換爲格式爲「19700101000000」的日期對象?
- 12. 將對象[,]轉換爲字符串
- 13. 將python'type'對象轉換爲字符串
- 14. 將字符串轉換爲JS對象
- 15. 將字符串轉換爲JavaScript對象
- 16. Jquery將字符串轉換爲對象
- 17. VBScript將對象轉換爲字符串?
- 18. 將對象轉換爲字符串(java)
- 19. 將對象[,]轉換爲字符串[,]
- 20. 將字符串轉換爲NSDate對象
- 21. 將字符串轉換爲對象
- 22. 將對象轉換爲XML字符串
- 23. 將字符串轉換爲JSON對象
- 24. 將字符串轉換爲對象
- 25. 將字符串對象轉換爲istringstream
- 26. 將JSON對象轉換爲字符串
- 27. 將對象轉換爲字符串
- 28. 將類對象轉換爲字符串
- 29. 將對象轉換爲字符串
- 30. 將XML對象轉換爲字符串
我想這是語言和技術(不僅是.NET)的獨立問題。 – 2012-11-07 13:20:04