Recursion | currency | chinese | conversion
Recently because of the project reason, need to write a currency number conversion Chinese algorithm, first in the net looked for a moment, the results found that none of the columns are replaced by the way to achieve, so want to write a different algorithm; because I was a math-born, so the method of pure mathematics to achieve.
Note: The algorithm in this article supports the conversion of currency numbers less than 1023 (that is, 999.9 billion trillion).
Currency Chinese Note: Before you explain the code, let's review the currency reading method first.
10020002.23 read as one thousand 0 million zero, three points
1020 read the whole of 0 yuan.
100000 read to collect million Yuan whole
0.13 read for one corner three points
Code:
Test Engineering
static void Main (string[] args)
{
Console.WriteLine ("Please enter 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 ("Unlawful Number or form");
}
Console.WriteLine ("Please enter Amount");
Inputnum = Console.ReadLine ();
}
Console.ReadLine ();
}
The test results are as follows:
Introduction to the function of currency conversion class (Numcast Class)
1 Rule of constant
<summary>
Digit
</summary>
public enum Numlevel {Cent, Chiao, Yuan, Ten, Hundred, Thousand, Tenthousand, Hundredmillon, trillion};
<summary>
Index of digits
</summary>
Private int[] numlevelexponent = new int[] {-2,-1, 0, 1, 2, 3, 4, 8, 12};
<summary>
Chinese characters for digits
</summary>
Private string[] numleverchinesesign = new string[] {"Min", "Jiao", "Yuan", "Pick Up", "Bai", "Qian", "million", "billion", "trillion"};
<summary>
Uppercase characters
</summary>
Private string[] Numchinesecharacter = new string[] {"0", "one", "II", "three", "Restaurant", "WU", "Lu", "Qi", "ba", "Nine"};
<summary>
Whole (when there is no corner)
</summary>
Private Const string Endofint = "whole";
2: Digital legitimacy verification, the use of regular expression verification
<summary>
Regular expression verifies that the number is legitimate
</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: Get digits for example 1000 digits for Numlevel.thousand
<summary>
Gets the number of digits using log
</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: To determine whether there is a jump between numbers, that is, whether the Chinese middle to add 0, such as 1020 should add 0.
<summary>
Whether to jump bit
</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 (numexponent)), 2);
if (postfixnun> 0)
Nextlevel = Getnumlevel (Postfixnun);
if (currentlevel!= null && nextlevel!= null)
{
if (CurrentLevel > nextlevel + 1)
{
return true;
}
}
}
return false;
}
5 Divide the long number into two smaller arrays of numbers, such as 999.9 billion megabytes, and 999.9 billion and 0 megabytes,
Because the computer does not support too long numbers.
///<summary>
///is greater than the trillion, if greater than the string is divided into two parts,
///part is the number of megabytes
///another part is a trillion later number
///</summary
///<param name= "Num" ></PARAM>
///<returns></returns>
private bool Isbigthantillion (String Num)
{
bool isbig = false;
if (Num.indexof ('. ')!=-1)
{
//if greater than Mega
if (Num.indexof ('. ') > numlevelexponent[(int) numlevel.trillion])
{
Isbig = true;
}
}
Else
{
//if greater than Mega
if (Num.length > numlevelexponent[(int) numlevel.trillion])
{
Isbig = True ;
}
}
return Isbig
}
<summary>
Separate the numeric string by ' Mega '
</summary>
<returns></returns>
Private double[] Splitnum (string Num)
{
The beginning bit of the trillion
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];
Trillion above the number
Tillionlevelnums[0] = convert.todouble (num.substring (0, trillionlevellength));
Number of megabytes below
TILLIONLEVELNUMS[1] = convert.todouble (num.substring (trillionlevellength));
return tillionlevelnums;
}
6 If you start with a "pick up", you can turn it into "pick up"
BOOL Isstartoften = false;
while (Num >=10)
{
if (Num = 10)
{
Isstartoften = true;
Break
}
Digit of NUM
Numlevel currentlevel = Getnumlevel (Num);
int numexponent = this. numlevelexponent[(int) currentlevel];
Num = Convert.ToInt32 (Math.floor (Num/math.pow (numexponent)));
if (CurrentLevel = = Numlevel.ten && Num = 1)
{
Isstartoften = true;
Break
}
}
return isstartoften;
7 merging a currency string that is greater than the number of megabytes
<summary>
Merging separate arrays of Chinese currency characters
</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 separated characters have a hop bit
if (Getnumlevel (tillionnums[1] *) = = numlevel.trillion)
{
Chinesecharactor = uptillionstr + numleverchinesesign[(int) numlevel.trillion] + downtrillionstr;
}
Else
{
Chinesecharactor = uptillionstr + numleverchinesesign[(int) numlevel.trillion];
if (downtrillionstr!= "0 yuan whole")
{
Chinesecharactor + = numchinesecharacter[0] + downtrillionstr;
}
Else
{
Chinesecharactor + + "Yuan whole";
}
}
return chinesecharactor;
}
8: Recursion calculates the Chinese of the currency number
<summary>
Calculate Chinese strings
</summary>
<param name= "Num" > Digital </param>
<param name= "NL" > digit level such as 10 million of the digital level is million </param>
<param name= "Isexceptten" > whether to start with ' pick ' </param>
<returns> Chinese capital </returns>
public string calculatechinesesign (double Num, numlevel?) NL, bool Isdump,bool isexceptten)
{
num = Math.Round (num, 2);
BOOL Isdump = false;
Digit of NUM
Numlevel? CurrentLevel = Getnumlevel (Num);
int numexponent = this. numlevelexponent[(int) currentlevel];
string result = String. Empty;
//divisible result
int prefixnum;
When the remainder is decimal, the numerator denominator is multiplied by the
double Postfixnun;
if (Num >= 1)
{
Prefixnum = Convert.ToInt32 (Math.floor (Num/math.pow, numexponent));
Postfixnun = Math.Round (Num% (Math.pow (numexponent)), 2);
}
Else
{
Prefixnum = Convert.ToInt32 (Math.floor (Num*100/math.pow (numexponent+2)));
Postfixnun = Math.Round (Num *% (Math.pow, numexponent + 2)), 2);
Postfixnun *= 0.01;
}
if (Prefixnum < 10)
{
Avoid a ' pick ' start
if (!) ( numchinesecharacter[(int) prefixnum] = = Numchinesecharacter[1]
&& CurrentLevel = = Numlevel.ten && isexceptten))
{
result = = numchinesecharacter[(int) prefixnum];
}
Else
{
Isexceptten = false;
}
Plus Unit
if (CurrentLevel = = Numlevel.yuan)
{
Add "meta" when the "meta" bit is not zero.
if (NL = null)
{
result = = numleverchinesesign[(int) currentlevel];
Add "integer" to zero after the decimal point
if (Postfixnun = 0)
{
result = Endofint;
}
}
}
Else
{
result = = numleverchinesesign[(int) currentlevel];
}
When the real single-digit is zero plus "yuan"
if (NL = null && Postfixnun < 1 && currentlevel > Numlevel.yuan && postfixnun > 0)
{
result = = numleverchinesesign[(int) Numlevel.yuan];
}
}
Else
{
When the current prefix number is not removed, recursion goes down
Numlevel? NEXTNL = null;
if ((int) currentlevel >= (int) (Numlevel.tenthousand))
NEXTNL = CurrentLevel;
Result + = Calculatechinesesign (double) prefixnum, NEXTNL, Isdump, Isexceptten);
if ((int) currentlevel >= (int) (Numlevel.tenthousand))
{
result = = numleverchinesesign[(int) currentlevel];
}
}
Whether to jump bit
To determine whether to add 0, such as 302 to 300 after 0, into 302.
if (Isdumplevel (Num))
{
result = Numchinesecharacter[0];
Isdump = true;
}
Whether the remainder requires recursion
if (Postfixnun > 0)
{
result = = Calculatechinesesign (Postfixnun, NL, Isdump, false);
}
else if (Postfixnun = 0 && currentlevel > Numlevel.yuan)
{
When the number is at the end of 0 yuan plus a dollar, such as 10,000,001,000,000 yuan whole
if (NL = null)
{
result = = numleverchinesesign[(int) Numlevel.yuan];
result = Endofint;
}
}
return result;
}
9: The external invocation of the conversion method.
<summary>
Conversion methods for external calls
</summary>
<param name= "Num" ></param>
<returns></returns>
public string Converttochinese (string Num)
{
if (! Isvalidated<string> (Num))
{
throw new OverflowException ("The numeric format is not correct, please enter a number less than 999.9 billion trillion and the maximum amount of accurate points!") ");
}
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:
Personally think that the soul of the program is the algorithm, large to a system of business logic, small to a currency of the number of Chinese algorithm, everywhere embodies a logical thought.
Whether the requirement can be abstracted into a good mathematical model is directly related to the complexity and stability of the program's implementation. In some common functions to think of a different algorithm, for us to develop ideas is very helpful.