数字转中文金额无限位数终极算法(验证程序,数组连接,固定数组变长)

来源:互联网 发布:java论坛网站建设 编辑:程序博客网 时间:2024/04/19 13:08
从第一种思路的实现推导出第二种思路实现,从第二种思路推导出终极算法,再从终极算法归纳总结优化第一种思路,从下面发布的代码可以看到演化轨迹.MSDN查询
string 标准人民币金额制式模板 = "零仟·零佰·零拾·零☆不可说☆·零仟·零佰·零拾·零☆无量·零仟·零佰·零拾·零不可思议·零仟·零佰·零拾·零那由他·零仟·零佰·零拾·零阿僧祇·零仟·零佰·零拾·零恒河沙·零仟·零佰·零拾·零极·零仟·零佰·零拾·零载·零仟·零佰·零拾·零正·零仟·零佰·零拾·零涧·零仟·零佰·零拾·零沟·零仟·零佰·零拾·零穰·零仟·零佰·零拾·零秭·零仟·零佰·零拾·零垓·零仟·零佰·零拾·零京·零仟·零佰·零拾·零兆·零仟·零佰·零拾·零亿·零仟·零佰·零拾·零万·零仟·零佰·零拾·零元"                 , 中文值 = "零壹贰叁肆伍陆柒捌玖", 转换输出标准 = "", 缩读处理 = "零仟零佰零拾";            string[] 反转单位集合 = 标准人民币金额制式模板.Split('·').Reverse().ToArray();            long 要转换的数字 = new Random().Next(int.MaxValue);            int 位数 = 0, 读单位 = 0;            Console.WriteLine("要转换的数字:" + 要转换的数字.ToString() + "转换:");            do            {                转换输出标准 = 转换输出标准.Insert(0, 反转单位集合[位数].Replace("零", 中文值[(int)(要转换的数字 % 10)].ToString()));                ++位数;            } while ((要转换的数字 /= 10) > 0);            Console.WriteLine(转换输出标准);            /*会计标准的输出就是上面这样了,来看看如何生成读的文字,首先说明,代码修改和优化在写完后期进行,这是个人习惯了.             其实规则还是很单纯的,首先处理最多4项,再处理左右321项,从最多处理开始,左补零,右单位,最后处理单项进阶单位*/            do            {                string 零单位 = 反转单位集合[读单位]; string[] 四位数 = { "" };                if (位数 > 读单位 + 4)                {                    string 进位 = 反转单位集合[读单位 + 4].Replace("零", "");                    四位数 = 转换输出标准.Split(进位.ToCharArray());                    四位数[0] += 进位;                    转换输出标准 = 四位数[四位数.Length - 1];                }                转换输出标准 = 转换输出标准.Replace(缩读处理 + 零单位, "");/*4*/                转换输出标准 = 转换输出标准.Replace(缩读处理.Substring(2) + 零单位, 零单位).Replace(缩读处理, "零");/*3*/                转换输出标准 = 转换输出标准.Replace(缩读处理.Substring(4) + 零单位, 零单位).Replace(缩读处理.Remove(4), "零").Replace(缩读处理.Substring(2), "零");/*2*/                转换输出标准 = 转换输出标准.Replace(缩读处理.Substring(4), "零").Replace(缩读处理.Remove(2), "零").Replace(缩读处理.Substring(2, 2), "零").Replace(零单位, 零单位.Replace("零", ""));/*1*/                if (四位数[0] != "") 转换输出标准 = 四位数[0] + 转换输出标准;                读单位 += 4;            } while (位数 > 读单位);/*完美实现第一种思路 1000004000300102;//*/            Console.WriteLine(转换输出标准 + (转换输出标准.Contains("元") ? "" : "元"));            要转换的数字 = new Random().Next(int.MaxValue);            转换输出标准 = ""; 位数 = 0;/*用到上面用过的变量时的初始化*/            bool 零补 = false, 是否加 = false;            Console.WriteLine("要转换的数字:" + 要转换的数字.ToString() + "转换:");            Func<long, bool> 四位判断 = delegate(long 信息)            {                long 代数 = 信息, 计位 = 0;                bool 逻辑 = false;                do                {                    if (代数 % 10 > 0)                        逻辑 = true ;                    代数 /= 10;                } while (++计位 < 4);                return 逻辑;            };            do            {                读单位 = (int)(要转换的数字 % 10);                if (位数 % 4 == 0)                    是否加 = 四位判断(要转换的数字);                if (读单位 > 0)                {                     转换输出标准 = 转换输出标准.Insert(0, 反转单位集合[位数].Replace("零", 中文值[读单位].ToString()));                    零补 = true ;                 }                else                    if (是否加)                    {                        if (位数 % 4 == 0)                            转换输出标准 = 转换输出标准.Insert(0, 反转单位集合[位数].Replace("零", ""));                        else                            if (零补)                                转换输出标准 = 转换输出标准.Insert(0, "零");                        零补 = false;                                            }                ++位数;            } while ((要转换的数字 /= 10) > 0);/*完美实现第二种思路*/            Console.WriteLine(转换输出标准 + (转换输出标准.Contains("元") ? "" : "元"));            /*最后,为什么要写字符串模板?因为,处理代码可以写为一个函数,传递字符串模板给函数去处理即可,无位数限制,可扩展。*/            要转换的数字 = new Random().Next(int.MaxValue);            Console.WriteLine(要转换的数字.ToString() + " 终极算法:");            转换输出标准 = ""; 位数 = 0;/*用到上面用过的变量时的初始化*/            bool 选加 = true, 是否 = false; string 选单位 = "";            Action 插入 = delegate()            {                if (是否)                {                    转换输出标准 = (选加 ? 选单位 : "零") + 转换输出标准;                    是否 = false;                }            };            do/*数字转中文金额终极算法,可申请算法专利了,哈哈......*/            {                读单位 = (int)(要转换的数字 % 10);                if (位数 % 4 == 0)                {                    if (是否 && !选加) 插入();/*第三位0的处理,单位未加前不加零.*/                    选单位 = 反转单位集合[位数].Replace("零", "");                    选加 = true; 是否 = false;/*逻辑还原初始化.*/                }                if (读单位 > 0)                {                    插入();                    转换输出标准 = 反转单位集合[位数].Replace("零", 中文值[读单位].ToString()) + 转换输出标准;                    选加 = false;                }                else                    是否 = true;                ++位数;            } while ((要转换的数字 /= 10) > 0);/*完美实现第三种思路*/            Console.WriteLine(转换输出标准 + (转换输出标准.Contains("元") ? "" : "元"));            string[] 小数中文集 = { "角", "分", "厘", "毫", "丝", "忽", "微", "纤", "沙", "尘", "埃", "渺", "莫", "模糊", "逡巡", "须臾", "瞬息", "弹指", "刹那", "六德", "空虚", "☆清静" };            double 要转换的小数 = new Random().Next(int.MaxValue) *.0000000001; //.1020030004;            string 小数字符串 = 要转换的小数.ToString(), 小数输出标准 = "";            int 取位 = 0, 总位 = 小数字符串.Length, 读数值 = 0;            bool 加入 = false;            do            {                读数值 = int.Parse(小数字符串[取位 + 2].ToString());/*变为0.1020030004为此+2*/                if (读数值 > 0)                {                    if (加入) 小数输出标准 += "零";                    小数输出标准 += 中文值[读数值].ToString() + 小数中文集[取位];                    加入 = false;                }                else                     加入 = true;            } while (++取位 + 2 < 总位);            Console.WriteLine(小数字符串 + " 小数转换输出标准:\n" + 小数输出标准);            后期代码维护与优化:            Action<string> 整理 = delegate(string 单位)            {                转换输出标准 = 转换输出标准                    .Replace(缩读处理 + 单位, "")                    .Replace(缩读处理.Substring(2) + 单位, 单位)                    .Replace(缩读处理, "零")                    .Replace(缩读处理.Substring(4) + 单位, 单位)                    .Replace(缩读处理.Remove(4), "零")                    .Replace(缩读处理.Substring(2), "零")                    .Replace(缩读处理.Substring(4), "零")                    .Replace(缩读处理.Remove(2), "零")                    .Replace(缩读处理.Substring(2, 2), "零")                    .Replace(单位, 单位.Replace("零", ""));            };            do            {                转换输出标准 = 反转单位集合[位数].Replace("零", 中文值[(int)(要转换的数字 % 10)].ToString()) + 转换输出标准;                if (位数 > 0 && 位数 % 4 == 0) 整理(反转单位集合[位数 - 4]);                ++位数;            } while ((要转换的数字 /= 10) > 0);/*完美实现第一种思路,后期代码维护与优化*/            整理(反转单位集合[位数 - (位数 % 4 > 0 ? 位数 % 4 : 4)]);                        int 自增检验数 = 0;            var 零单位 = 反转单位集合.Distinct().Reverse();            var 相邻单位 = 零单位.Take(零单位.Count() - 2).Select((单位, 序) => 单位.Replace("零", "") + 零单位.Skip(1).Select(相邻 => 相邻.Replace("零", "")).ToArray()[序]);            var 验证集合 = 零单位.Concat(相邻单位).Concat(new string[] { "零零" });/*答复来自论坛提问:固定数组变长,用连接两个数组函数Concat和创建数组函数ToArray完成*/零单位 = 零单位.Concat(相邻单位).Concat(new string[] { "零零" }).ToArray();            do            {                要转换的数字 = ++自增检验数;                do                {                    转换输出标准 = 反转单位集合[位数].Replace("零", 中文值[(int)(要转换的数字 % 10)].ToString()) + 转换输出标准;                    if (位数 > 0 && 位数 % 4 == 0) 整理(反转单位集合[位数 - 4]);                    ++位数;                } while ((要转换的数字 /= 10) > 0);/*完美实现第一种思路,后期代码维护与优化*/                整理(反转单位集合[位数 - (位数 % 4 > 0 ? 位数 % 4 : 4)]);                Console.WriteLine(转换输出标准 + (转换输出标准.Contains("元") ? "" : "元"));                /*校验正确性:1.零单位 2.相邻单位 3.连零*/                foreach (string 元素 in 验证集合)                    if (转换输出标准.Contains(元素))                    {                        Console.Beep();                        Console.WriteLine(元素);                        return;                    }                转换输出标准 = ""; 位数 = 0;            } while (自增检验数 < int.MaxValue);                        /*之上代码逻辑经得起推敲.*/                        //    if (要转换的数字 % 10 == 0) 零补 = true;            //    要转换的数字 /= 10;            //    if (零补 && 要转换的数字 % 10 > 0)/*完成任意个0的处理*/            //        零补 = false;


答复论坛提问

1 0
原创粉丝点击