• 转 .Net/C#/VB/TSQL/Java/Script 实现: 将天文数字转换成中文大写 (2000 年前的思路,打劫的,一点儿技术含量都没有)


    下面的是转贴

    Microshaoft (大舌头)

    的帖子,正好项目用上,想法还可以,但是不能区别小数点和最后不能添加上金额单位!


    C# Code:

    /*
    .Net/C#/T-SQL/VB/Java 实现: 将天文数字转换成中文大写
    最近这里流行这个大写金额转换
    我看了几个,感觉思路都不如这个 2000 年左右用 VB6 写的:
    《VB6 之数据格式化对象使用技巧》
    http://search.csdn.net/Expert/topic/38/38970.xml?temp=.5078089
    <<精华: 将金额小写转大写的代码可转到亿位>>
    http://www.dev-club.com/club/bbs/showEssence.asp?id=20684&page=1
    思路非常简单,且没有任何位数限制!
    例如: 401,0103,1013
    读作: 肆佰零壹[亿]零壹佰零叁[万]壹仟零壹拾叁
    咱们先按每四位一组 从左到右,高位到低位分别"大声朗读"一下:
    "肆佰零壹" 单位是: "[亿]"
    "壹佰零叁" 单位是: "[万]"
    "壹仟零壹拾叁" 单位是 "" (相当于没有单位)
    很容易发现,每四位: 只有 千位,百位,十位,个位 这四种情况!
    我们把 [万],[亿] 当作单位就可以了!
    这就是规律了!简单吧!
    依据该思路,只用区区不到 50 行代码就可以搞定:
    只要你能够提供足够多的"单位"
    任何天文数字都可以正确转换!
    */


    namespace Microshaoft
    {
        
    using System;

        
    public class Util
        
    {
            
    public static string ConvertNumberToChinese(string x, string[] Nums, string[] Digits, string[] Units)
            
    {
                
    string S = ""//返回值
                int p = 0//字符位置指针
                int m = x.Length % 4//取模

                
    // 四位一组得到组数
                int k = (m > 0 ? x.Length / 4 + 1 : x.Length / 4);

                
    // 外层循环在所有组中循环
                
    // 从左到右 高位到低位 四位一组 逐组处理
                
    // 每组最后加上一个单位: "[万亿]","[亿]","[万]"
                for (int i = k; i > 0; i--)
                
    {
                    
    int L = 4;
                    
    if (i == k && m != 0)
                    
    {
                        L 
    = m;
                    }

                    
    // 得到一组四位数 最高位组有可能不足四位
                    string s = x.Substring(p, L);
                    
    int l = s.Length;

                    
    // 内层循环在该组中的每一位数上循环 从左到右 高位到低位
                    for (int j = 0; j < l; j++)
                    
    {
                        
    //处理改组中的每一位数加上所在位: "仟","佰","拾",""(个)
                        int n = Convert.ToInt32(s.Substring(j, 1));
                        
    if (n == 0)
                        
    {
                            
    if (j < l - 1
                                
    && Convert.ToInt32(s.Substring(j + 11)) > 0 //后一位(右低)
                                && !S.EndsWith(Nums[n]))
                            
    {
                                S 
    += Nums[n];
                            }

                        }

                        
    else
                        
    {
                            
    //处理 1013 一千零"十三", 1113 一千一百"一十三"
                            if (!(n == 1 && (S.EndsWith(Nums[0]) | S.Length == 0&& j == l - 2))
                            
    {
                                S 
    += Nums[n];
                            }

                            S 
    += Digits[l - j - 1];
                        }

                    }

                    p 
    += L;
                    
    // 每组最后加上一个单位: [万],[亿] 等
                    if (i < k) //不是最高位的一组
                    {
                        
    if (Convert.ToInt32(s) != 0)
                        
    {
                            
    //如果所有 4 位不全是 0 则加上单位 [万],[亿] 等
                            S += Units[i - 1];
                        }

                    }

                    
    else
                    
    {
                        
    //处理最高位的一组,最后必须加上单位
                        S += Units[i - 1];
                    }

                }

                
    return S;
            }


            
    // 测试程序
            private static void Main()
            
    {
                
    //数字 数组
                string[] Nums = new string[] {""""""""""""""""""""};
                
    //位 数组
                string[] Digits = new string[] {""""""""};
                
    //单位 数组
                string[] Units = new string[] {"""[万]""[亿]""[万亿]"};

                Console.WriteLine(ConvertNumberToChinese(
    "1100000013", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "2100000000", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "1000000000", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "40000000013", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "40000000001", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "400000010000", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "40101031013", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "40101031113", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "101140101031013", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "100000001000013", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "100000001000113", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "100011003", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "10010103", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "10110013", Nums, Digits, Units));
                Console.WriteLine(ConvertNumberToChinese(
    "130000", Nums, Digits, Units));
                Console.ReadLine();
            }

        }

    }


    2005-04-26 参阅
    aierong
    自定义格式字符串随笔
    顺便贴一个转大写的 Formatter

    namespace Microshaoft
    {
        
    using System;

        
    public class ChineseFormat : System.ICustomFormatter, System.IFormatProvider
        
    {
            
    //如果format Type与当前实例类型相同,则为当前实例,否则为空引用 
            public object GetFormat(Type format)
            
    {
                
    if (format == typeof (ICustomFormatter))
                
    {
                    
    return this;
                }

                
    return null;
            }


            
    //实现Format方法说明: 
            
    //如果您的格式方法不支持格式,则确定正在设置格式的对象是否实现 IFormattable 接口。 
            
    //如果实现,请调用该接口的IFormattable.ToString 方法。 
            
    //否则,调用基础对象的默认 Object.ToString 方法。 
            public string Format(string format, object arg, IFormatProvider provider)
            
    {
                
    if (format == null)
                
    {
                    
    if (arg is IFormattable)
                    
    {
                        
    return ((IFormattable) arg).ToString(format, provider);
                    }

                    
    return arg.ToString();
                }

                
    else
                
    {
                    
    if (format == "ChineseFormat")
                    
    {
                        
    string[] Nums = new string[] {""""""""""""""""""""};
                        
    //位 数组 
                        string[] Digits = new string[] {""""""""};
                        
    //单位 数组 
                        string[] Units = new string[] {"""[万]""[亿]""[万亿]"};
                        
    return ConvertNumberToChinese(arg.ToString(), Nums, Digits, Units);
                        
    //return "***"+arg.ToString(); 
                    }

                    
    else
                    
    {
                        
    if (arg is IFormattable)
                        
    {
                            
    return ((IFormattable) arg).ToString(format, provider);
                        }

                        
    return arg.ToString();
                    }

                }

            }


            
    public static string ConvertNumberToChinese(string x, string[] Nums, string[] Digits, string[] Units)
            
    {
                
    string S = ""//返回值 
                int p = 0//字符位置指针 
                int m = x.Length % 4//取模 

                
    // 四位一组得到组数 
                int k = (m > 0 ? x.Length / 4 + 1 : x.Length / 4);

                
    // 外层循环在所有组中循环 
                
    // 从左到右 高位到低位 四位一组 逐组处理 
                
    // 每组最后加上一个单位: "[万亿]","[亿]","[万]" 
                for (int i = k; i > 0; i--)
                
    {
                    
    int L = 4;
                    
    if (i == k && m != 0)
                    
    {
                        L 
    = m;
                    }

                    
    // 得到一组四位数 最高位组有可能不足四位 
                    string s = x.Substring(p, L);
                    
    int l = s.Length;

                    
    // 内层循环在该组中的每一位数上循环 从左到右 高位到低位 
                    for (int j = 0; j < l; j++)
                    
    {
                        
    //处理改组中的每一位数加上所在位: "仟","佰","拾",""(个) 
                        int n = Convert.ToInt32(s.Substring(j, 1));
                        
    if (n == 0)
                        
    {
                            
    if (j < l - 1
                                
    && Convert.ToInt32(s.Substring(j + 11)) > 0 //后一位(右低) 
                                && !S.EndsWith(Nums[n]))
                            
    {
                                S 
    += Nums[n];
                            }

                        }

                        
    else
                        
    {
                            
    //处理 1013 一千零"十三", 1113 一千一百"一十三" 
                            if (!(n == 1 && (S.EndsWith(Nums[0]) | S.Length == 0&& j == l - 2))
                            
    {
                                S 
    += Nums[n];
                            }

                            S 
    += Digits[l - j - 1];
                        }

                    }

                    p 
    += L;
                    
    // 每组最后加上一个单位: [万],[亿] 等 
                    if (i < k) //不是最高位的一组 
                    {
                        
    if (Convert.ToInt32(s) != 0)
                        
    {
                            
    //如果所有 4 位不全是 0 则加上单位 [万],[亿] 等 
                            S += Units[i - 1];
                        }

                    }

                    
    else
                    
    {
                        
    //处理最高位的一组,最后必须加上单位 
                        S += Units[i - 1];
                    }

                }

                
    return S;
            }

        }

    }


    namespace Test
    {
        
    using System;
        
    using Microshaoft;

        
    class AppTest
        
    {
            
    static void Main()
            
    {
                
    string printString = String.Empty;
                
    long i = 1100000013;
                ChineseFormat fmt 
    = new ChineseFormat();

                printString 
    = string.Format(fmt, "显示正常格式: {0}", i);
                Console.WriteLine(printString);
                printString 
    = string.Format(fmt, "显示正常格式: {0:C}", i);
                Console.WriteLine(printString);
                printString 
    = string.Format(fmt, "显示自定义格式: {0:ChineseFormat}", i);
                Console.WriteLine(printString);

                Console.ReadLine();
            }

        }

    }


    T-SQL UDF Code:

    alter function ConvertNumberToChinese(@ varchar(100))
    returns varchar(100)
    as
    begin
    --declare @ varchar(100)
    --
    set @ = '101140101031013'
    declare @s varchar(100)
    set @s = ''

    declare @p integer
    set @p = 0

    declare @m integer
    set @m = len(@) % 4

    declare @k integer
    set @k = len(@)/4

    select @k = @k + 1
     
    where @m > 0

    declare @i integer
    set @i = @k

    while (@i > 0)
    begin --outer
       declare @L integer
       
    set @L = 4

       
    select @L = @m
        
    where @i = @k and @m != 0

       
    declare @ss varchar(4)
       
    set @ss = substring(@,@p+1,@L)

       
    declare @ll integer
       
    set @ll = len(@ss)

       
    --inner
       declare @j integer
       
    set @j = 0

       
    while (@j < @ll) --inner
       begin --inner
          declare @n integer
          
    set @n = cast(substring(@ss,@j+1,1as integer)

          
    declare @num varchar(2)   
          
    select @num = Num
            
    from (
                  
    select 0 as id,'' as Num
                  
    union all select 1,''
                  
    union all select 2,''
                  
    union all select 3,''
                  
    union all select 4,''
                  
    union all select 5,''
                  
    union all select 6,''
                  
    union all select 7,''
                  
    union all select 8,''
                  
    union all select 9,''
                 ) Nums
          
    where id = @n

          
    if @n = 0
          
    begin
             
    select @s = @s + @num
              
    where @j < @ll - 1
                    
    and cast(substring(@ss,(@j+1)+1,1as integer> 0
                    
    and right(@ss,1!= @num
          
    end
          
    else
          
    begin
             
    declare @jj integer
             
    set @jj = 1

             
    select @jj = @j - 1
              
    where @j > 1

             
    select @s = @s + @num
              
    where not (@n = 1
                         
    and @j = @ll - 2
                         
    and (len(@s) = 0
                              
    or right(@s,1= ''
    /*
                                               (   select Num
                                                    from
                                                   (
                                                    select 0 as id,'零' as Num
                                                    union all select 1,'壹'
                                                    union all select 2,'贰'
                                                    union all select 3,'叁'
                                                    union all select 4,'肆'
                                                    union all select 5,'伍'
                                                    union all select 6,'陆'
                                                    union all select 7,'柒'
                                                    union all select 8,'捌'
                                                    union all select 9,'玖'
                                                   ) Nums
                                                   where id = 0
                                               )
    */

                                               )
                             )

             
    select @s = @s + digit
               
    from (
                     
    select 0 as id,'' as digit
                     
    union all select 1,''
                     
    union all select 2,''
                     
    union all select 3,''
                    ) digits
              
    where id = @ll - @j - 1

          
    end
          
    set @j = @j + 1 --inner
       end --inner
       set @p = @p + @L

       
    declare @unit varchar(10)
       
    select @unit = Unit
         
    from (
               
    select 0 as id,'' as Unit
               
    union all select 1,'[万]'
               
    union all select 2,'[亿]'
               
    union all select 3,'[万亿]'
              ) Units
        
    where id = @i - 1

       
    if @i < @k
       
    begin
          
    select @s = @s + @unit
           
    where cast(@ss as integer!= 0
       
    end
       
    else
       
    begin
          
    set @s = @s + @unit
       
    end
       
    set @i = @i - 1 -- outer
    end --out
    return @s
    /*
    --Test:
    select dbo.ConvertNumberToChinese('1011111112101013')
    ,dbo.ConvertNumberToChinese('40000000001')
    ,dbo.ConvertNumberToChinese('400000010000')
    ,dbo.ConvertNumberToChinese('40101031013')
    ,dbo.ConvertNumberToChinese('101140101031013')
    ,dbo.ConvertNumberToChinese('100000001000003')
    ,dbo.ConvertNumberToChinese('10011003')
    ,dbo.ConvertNumberToChinese('10010103')
    ,dbo.ConvertNumberToChinese('10010013')
    */

    end



    VB6 Code:
    《VB6 之数据格式化对象使用技巧》
    http://search.csdn.net/Expert/topic/38/38970.xml?temp=.5078089
    <<精华: 将金额小写转大写的代码可转到亿位>>
    http://www.dev-club.com/club/bbs/showEssence.asp?id=20684&page=1

    VB.Net Code:
    可自行将 C# Code 编译成 EXE 后, Reflector 反编译获取 VB.Net/Delphi.Net/IL 等语言源码

    Java Code:

    public class Class1
    {
        
    public static String ConvertNumberToChinese(String x, String[] Nums, String[] Digits, String[] Units)
        
    {
            String S 
    = ""//返回值
            int p = 0//字符位置指针
            int m = x.length() % 4//取模

            
    // 四位一组得到组数
            int k = (m > 0 ? x.length() / 4 + 1 : x.length() / 4);

            
    // 外层循环在所有组中循环
            
    // 从左到右 高位到低位 四位一组 逐组处理
            
    // 每组最后加上一个单位: "[万亿]","[亿]","[万]"
            for (int i = k; i > 0; i--)
            
    {
                
    int L = 4;
                
    if (i == k && m != 0)
                
    {
                    L 
    = m;
                }

                
    // 得到一组四位数 最高位组有可能不足四位
                String s = x.substring(p, p + L);
                
    int l = s.length();

                
    // 内层循环在该组中的每一位数上循环 从左到右 高位到低位
                for (int j = 0; j < l; j++)
                
    {
                    
    //处理改组中的每一位数加上所在位: "仟","佰","拾",""(个)
                    int n = java.lang.Integer.parseInt(s.substring(j, j+1));
                    
    if (n == 0)
                    
    {
                        
    if ((j < l - 1)
                            
    && (java.lang.Integer.parseInt(s.substring(j + 1, j + 1+ 1)) > 0//后一位(右低)
                            && !S.endsWith(Nums[n]))
                        
    {
                            S 
    += Nums[n];
                        }

                    }

                    
    else
                    
    {
                        
    //处理 1013 一千零"十三", 1113 一千一百"一十三"
                        if (!(n == 1 && (S.endsWith(Nums[0]) | S.length() == 0&& j == l - 2))
                        
    {
                            S 
    += Nums[n];
                        }

                        S 
    +=  Digits[l - j - 1];
                    }

                }

                p 
    += L;
                
    // 每组最后加上一个单位: [万],[亿] 等
                if (i < k) //不是最高位的一组
                {
                    
    if (java.lang.Integer.parseInt(s) != 0)
                    
    {
                        
    //如果所有 4 位不全是 0 则加上单位 [万],[亿] 等
                        S += Units[i - 1];
                    }

                }

                
    else
                
    {
                    
    //处理最高位的一组,最后必须加上单位
                    S += Units[i - 1];
                }

            }

            
    return S;
        }


        
    // 测试程序
        public static void main(String[] args) throws Exception
        
    {
            
    //数字 数组
            String[] Nums = new String[] {""""""""""""""""""""};
            
    //位 数组
            String[] Digits = new String[] {""""""""};
            
    //单位 数组
            String[] Units = new String[] {"""[万]""[亿]""[万亿]"};

            System.
    out.println(ConvertNumberToChinese("111112100113", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("1100000000", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("1000000000", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("40000000013", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("40000000001", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("400000010000", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("40101031013", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("40101031113", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("101140101031013", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("100000001000013", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("100000001000113", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("100011003", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("10010103", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("10110013", Nums, Digits, Units));
            System.
    out.println(ConvertNumberToChinese("130000", Nums, Digits, Units));

            
    //System.in.read();
        }

    }

    JavaScript:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    <HEAD>
    <TITLE> New Document </TITLE>
    <META NAME="Generator" CONTENT="EditPlus">
    <META NAME="Author" CONTENT="playyuer㊣www.Microshaoft.com">
    </HEAD>

    <BODY>
    <SCRIPT LANGUAGE="JavaScript">
    <!--
    function ConvertNumberToChinese(x,Nums,Digits,Units)
    {
        
    //var x = "11112100013";
        //
        //var Nums = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"); 
        //var Digits = new Array("", "拾", "佰", "仟"); 
        //var Units = new Array("", "[万]", "[亿]", "[万亿]"); 

        
    var S = ""//返回值 
        var p = 0//字符位置指针 
        var m = x.length % 4//取模 

        
    // 四位一组得到组数 
        var k = (m > 0 ? Math.floor(x.length / 4+ 1 : Math.floor(x.length / 4)); 
        
    // 外层循环在所有组中循环 
        // 从左到右 高位到低位 四位一组 逐组处理 
        // 每组最后加上一个单位: "[万亿]","[亿]","[万]" 
        for (var i = k; i > 0; i--
        
    {
            
    var L = 4
            
    if (i == k && m != 0)
            
    {
                L 
    = m;
            }

            
    // 得到一组四位数 最高位组有可能不足四位 
            var s = x.substring(p, p + L);
            
    var l = s.length;

            
    // 内层循环在该组中的每一位数上循环 从左到右 高位到低位 
            for (var j = 0;j < l;j++)
            
    {
                
    var n = parseInt(s.substring(j, j+1));
                
    if (n == 0)
                
    {
                    
    if ((j < l - 1&& (parseInt(s.substring(j + 1, j + 1+ 1)) > 0//后一位(右低) 
                        && S.substring(S.length-1,S.length) != Nums[n])
                    
    {
                        S 
    += Nums[n];
                    }

                }

                
    else 
                
    {
                    
    //处理 1013 一千零"十三", 1113 一千一百"一十三" 
                    if (!(n == 1 && (S.substring(S.length-1,S.length) == Nums[0| S.length == 0&& j == l - 2)) 
                    
    {
                        S 
    += Nums[n];
                    }

                    S 
    +=  Digits[l - j - 1];
                }

            }

            p 
    += L;
            
    // 每组最后加上一个单位: [万],[亿] 等 
            if (i < k)//不是最高位的一组 
            {
                
    if (parseInt(s)!= 0)
                
    {
                    
    //如果所有 4 位不全是 0 则加上单位 [万],[亿] 等 
                    S += Units[i - 1];
                }

            }

            
    else
            
    {
                
    //处理最高位的一组,最后必须加上单位 
                S += Units[i - 1];
            }

        }

        
    //alert(S);
        return S
    }

    // call function
    var xx = "11112100013";
    var xNums = new Array(""""""""""""""""""""); 
    var xDigits = new Array(""""""""); 
    var xUnits = new Array("""[万]""[亿]""[万亿]");
    alert(ConvertNumberToChinese(xx,xNums,xDigits,xUnits));

    //-->
    </SCRIPT>
    </BODY>
    </HTML>

    原文:http://www.cnblogs.com/microshaoft/archive/2005/04/02/131008.html
     

  • 相关阅读:
    数据结构小总结(成都磨子桥技工学校数据结构前12题)
    Scrum 冲刺博客第二篇
    Scrum 冲刺博客第一篇
    centos部署keepalived服务
    第四周作业
    Svelte 中怎样做双向数据绑定
    Svelte 中多层组件事件转发
    Svelte 中的事件修饰符
    怎样在 Svelte 中设置自定义事件
    怎样使用 Svelte 中的异步块
  • 原文地址:https://www.cnblogs.com/dagon007/p/190353.html
Copyright © 2020-2023  润新知