Recently, due to project reasons, you need to write a currency number to convert Chinese Algorithm First, I searched for it on the Internet and found that all of them are implemented by replace. Therefore, I want to write another algorithm; because I learned mathematics, I used pure mathematics.
Note: The algorithm in this article supports digital conversion of less than 1023 (that is, 999.9 billion MB) currencies.
Currency Description: DescriptionCodeBefore that, let's review the currency reading method.
10020002.23 million yuan reading: million yuan reading
1020 million yuan reading is a collection of Yuan.
100000 million yuan reading
0.13 reading points
Code:
Test Project
Static void main (string [] ARGs)
{
Console. writeline ("Enter the amount ");
String inputnum = console. Readline ();
While (inputnum! = "Exit ")
{
// Currency digital conversion class
Numcast NC = new numcast ();
If (nc. isvalidated <string> (inputnum ))
{
Try
{
String chinesecharacter = nC. converttochinese (inputnum );
Console. writeline (chinesecharacter );
}
Catch (exception ER)
{
Console. writeline (ER. Message );
}
}
Else
{
Console. writeline ("invalid number or format ");
}
Console. writeline ("\ n enter the amount ");
Inputnum = console. Readline ();
}
Console. Readline ();
}
The test results are as follows:
Introduction to the numcast Function
1 constant
/// <Summary>
/// Digit
/// </Summary>
Public Enum numlevel {cent, Chiao, Yuan, ten, hundred, thousand, tenthousand, hundredmillon, trillion };
/// <Summary>
/// Digital Index
/// </Summary>
Private int [] numlevelexponent = new int [] {-2,-1, 0, 1, 2, 3, 4, 8, 12 };
/// <Summary>
/// Chinese characters of digits
/// </Summary>
Private string [] numleverchinesesign = new string [] {"points", "Corner", "Yuan", "pick up", "yellow", "yellow", "Ten Thousand ", "billion", "MB "};
/// <Summary>
/// Uppercase characters
/// </Summary>
Private string [] numchinesecharacter = new string [] {"zero", "one", "two", "three", "Si", "Wu", "Lu ", "identifier", "identifier", "identifier "};
/// <Summary>
/// INTEGER (when there is no corner score)
/// </Summary>
Private const string endofint = "integer ";
2: digit validity verification, using regular expression Verification
/// <Summary>
/// Regular expression to verify whether the number is valid
/// </Summary>
/// <Param name = "num"> </param>
/// <Returns> </returns>
Public bool isvalidated <t> (T num)
{
RegEx Reg = new RegEx (@ "^ ([0]) | ([1-9] \ D {0, 23}) (\. \ D {1, 2 })? $ ");
If (Reg. ismatch (Num. tostring ()))
{
Return true;
}
Return false;
}
3: obtain the number of digits. For example, the number of digits 1000 is numlevel. Thousand.
/// <Summary>
/// Use log to obtain digits
/// </Summary>
/// <Param name = "num"> </param>
/// <Returns> </returns>
Private numlevel getnumlevel (double num)
{
Double numlevellength;
Numlevel nlvl = new numlevel ();
If (Num> 0)
{
Numlevellength = math. Floor (math. log10 (Num ));
For (INT I = numlevelexponent. Length-1; I> = 0; I --)
{
If (numlevellength> = numlevelexponent [I])
{
Nlvl = (numlevel) I;
Break;
}
}
}
Else
{
Nlvl = numlevel. Yuan;
}
Return nlvl;
}
4: determine whether there is a hop between numbers, that is, whether to add zero in the center of Chinese characters. For example, 1020 should be added to zero.
/// <Summary>
/// Skip
/// </Summary>
/// <Returns> </returns>
Private bool isdumplevel (double num)
{
If (Num> 0)
{
Numlevel? Currentlevel = getnumlevel (Num );
Numlevel? Nextlevel = NULL;
Int numexponent = This. numlevelexponent [(INT) currentlevel];
Double postfixnun = math. Round (Num % (math. Pow (10, numexponent), 2 );
If (postfixnun> 0)
Nextlevel = getnumlevel (postfixnun );
If (currentlevel! = NULL & nextlevel! = NULL)
{
If (currentlevel> nextlevel + 1)
{
Return true;
}
}
}
Return false;
}
5. Divide long numbers into two smaller numeric arrays. For example, divide 999.9 billion MB into 999.9 billion MB and 0 MB,
the computer does not support too long numbers.
///
// whether the value is greater than MB. If the value is greater than MB, the string is divided into two parts,
// a part of the data is a digit before the MB.
// another part is a digit after the MB.
///
// /
//
private bool isbigthantillion (string num)
{< br> bool isbig = false;
If (Num. indexof ('. ')! =-1)
{< br> // if it is greater than MB
If (Num. indexof ('. ')> numlevelexponent [(INT) numlevel. trillion])
{< br> isbig = true;
}< BR >}< br> else
{< br> // if it is greater than MB
If (Num. length> numlevelexponent [(INT) numlevel. trillion])
{< br> isbig = true;
}< br> return isbig;
}
/// <Summary>
/// Separate the number string from the 'megabits'
/// </Summary>
/// <Returns> </returns>
Private double [] splitnum (string num)
{
// Start position of the MB
Double [] tillionlevelnums = new double [2];
Int trillionlevellength;
If (Num. indexof ('.') =-1)
Trillionlevellength = num. Length-numlevelexponent [(INT) numlevel. trillion];
Else
Trillionlevellength = num. indexof ('.')-numlevelexponent [(INT) numlevel. trillion];
// Megabytes or more
Tillionlevelnums [0] = convert. todouble (Num. substring (0, trillionlevellength ));
// Numbers below 1 MB
Tillionlevelnums [1] = convert. todouble (Num. substring (trillionlevellength ));
Return tillionlevelnums;
}
6. Is it starting with "pick up"? If so, you can change it to "pick up"
Bool isstartoften = false;
While (Num> = 10)
{
If (num = 10)
{
Isstartoften = true;
Break;
}
// Num Digit
Numlevel currentlevel = getnumlevel (Num );
Int numexponent = This. numlevelexponent [(INT) currentlevel];
Num = convert. toint32 (math. Floor (Num/Math. Pow (10, numexponent )));
If (currentlevel = numlevel. Ten & num = 1)
{
Isstartoften = true;
Break;
}
}
Return isstartoften;
7. Merge currency strings converted from arrays larger than a trillion sign
/// <Summary>
/// Merge the Chinese currency characters of the separate Array
/// </Summary>
/// <Param name = "tillionnums"> </param>
/// <Returns> </returns>
Private string contactnumchinese (double [] tillionnums)
{
String uptillionstr = calculatechinesesign (tillionnums [0], numlevel. trillion, true, isstartoften (tillionnums [0]);
String downtrillionstr = calculatechinesesign (tillionnums [1], null, true, false );
String chinesecharactor = string. empty;
// Whether the character after separation has a hop
If (getnumlevel (tillionnums [1] * 10) = numlevel. trillion)
{
Chinesecharactor = uptillionstr + numleverchinesesign [(INT) numlevel. trillion] + downtrillionstr;
}
Else
{
Chinesecharactor = uptillionstr + numleverchinesesign [(INT) numlevel. trillion];
If (downtrillionstr! = "Zero RMB ")
{
Chinesecharactor + = numchinesecharacter [0] + downtrillionstr;
}
Else
{
Chinesecharactor + = "Yuan ";
}
}
Return chinesecharactor;
}
8: recursive Calculation of Chinese currency numbers
/// <Summary>
/// Calculate the Chinese String
/// </Summary>
/// <Param name = "num"> Number </param>
/// <Param name = "NL"> for example, the digital level of 10 million is </param>
/// <Param name = "isexceptten"> indicates whether to start with 'snapshot' </param>
/// <Returns> uppercase </returns>
Public String calculatechinesesign (double num, numlevel? NL, bool isdump, bool isw.tten)
{
Num = math. Round (Num, 2 );
Bool isdump = false;
// Num Digit
Numlevel? Currentlevel = getnumlevel (Num );
Int numexponent = This. numlevelexponent [(INT) currentlevel];
String result = string. empty;
// result after Division
int prefixnum;
// when the remainder is a decimal number, the denominator of the numerator is multiplied by 100
double postfixnun;
If (Num> = 1)
{< br> prefixnum = convert. toint32 (math. floor (Num/math. pow (10, numexponent);
postfixnun = math. round (Num % (math. pow (10, numexponent), 2);
}< br> else
{< br> prefixnum = convert. toint32 (math. floor (Num * 100/math. pow (10, numexponent + 2);
postfixnun = math. round (Num * 100% (math. pow (10, numexponent + 2), 2);
postfixnun * = 0.01;
}
If (prefixnum <10)
{
// Avoid starting with 'restart'
If (! (Numchinesecharacter [(INT) prefixnum] = numchinesecharacter [1]
& Currentlevel = numlevel. Ten & isw.tten ))
{
Result + = numchinesecharacter [(INT) prefixnum];
}
Else
{
Isexceptten = false;
}
// Add Unit
If (currentlevel = numlevel. yuan)
{
/// When the value is "Yuan", add "Yuan" when the value is not zero ".
If (NL = NULL)
{
Result + = numleverchinesesign [(INT) currentlevel];
// Add "integral" when the decimal point is zero"
If (postfixnun = 0)
{
Result + = endofint;
}
}
}
Else
{
Result + = numleverchinesesign [(INT) currentlevel];
}
// Add "Yuan" when the real single digit is zero"
If (NL = NULL & postfixnun <1 & currentlevel> numlevel. Yuan & postfixnun> 0)
{
Result + = numleverchinesesign [(INT) numlevel. Yuan];
}
}
Else
{
// Recursion when the prefix number is not exhausted
Numlevel? Nextnl = NULL;
If (INT) currentlevel> = (INT) (numlevel. tenthousand ))
Nextnl = currentlevel;
Result + = calculatechinesesign (double) prefixnum, nextnl, isdump, isw.tten );
If (INT) currentlevel> = (INT) (numlevel. tenthousand ))
{
Result + = numleverchinesesign [(INT) currentlevel];
}
}
// Skip
// Determine whether to add zero. For example, if 302 is used, add zero to the end of three hundred and change to three hundred and two.
If (isdumplevel (Num ))
{
Result + = numchinesecharacter [0];
Isdump = true;
}
// Whether recursion is required for the remainder
If (postfixnun> 0)
{
Result + = calculatechinesesign (postfixnun, NL, isdump, false );
}
Else if (postfixnun = 0 & currentlevel> numlevel. yuan)
{
// When the number ends with zero yuan, add the yuan, for example, 1000000 1 million yuan.
If (NL = NULL)
{
Result + = numleverchinesesign [(INT) numlevel. Yuan];
Result + = endofint;
}
}
Return result;
}
9: external call conversion method.
/// <Summary>
/// External call Conversion Method
/// </Summary>
/// <Param name = "num"> </param>
/// <Returns> </returns>
Public String converttochinese (string num)
{
If (! Isvalidated <string> (Num ))
{
Throw new overflowexception ("the value format is incorrect. Enter a number smaller than 999.9 billion MB and the maximum accurate score! ");
}
String chinesecharactor = string. empty;
If (isbigthantillion (Num ))
{
Double [] tillionnums = splitnum (Num );
Chinesecharactor = contactnumchinese (tillionnums );
}
Else
{
Double dnum = convert. todouble (Num );
Chinesecharactor = calculatechinesesign (dnum, null, true, isstartoften (dnum ));
}
Return chinesecharactor;
}
Summary:
I personally thinkProgramThe soul of an algorithm is the business logic of a system, the algorithm of converting a currency number to a Chinese character, which embodies a logic idea everywhere.
whether to abstract requirements into a good mathematical model is directly related to the complexity and Stability of program implementation. It is helpful for us to think about different algorithms in some common functions.
This article is reposted from 'China it Labs'