面试中遇到的一道算法题,请各位对我的算法指点一下

前几天面试,遇到一题上机题,由于写了大半年的安卓控件,对于一些基础函数都有点生疏,面试结束后,面试官说我的算法一般般,不过现在也没有想到哪里可以优化。请各位指点一下。

面试题目是这样的:将输入的账户余额以读取的形式转化出来。例如:

输入:123.12

输出:One hundred twenty three dollars and twelve cents

注意:dollar和cent的复数形式,有没有and连接等。


我的思路就是把整数和小数部分分开,然后分别读取各个部分。

读取每个部分的时候,先将该部分字符串补全至3的倍数个(前面加0),然后以三个字符为一组进行读取,先读百位,再读剩下两位。

最后根据两个部分的值,看情况把两个部分连接起来。


我写了五个函数,分别是:

1、读取函数。功能是将输入的字符串划分为两个部分,然后使用别的函数读出这两个部分,最后视情况添加and。

	/// <summary>
        /// 如果输入的字符串是数字,则读出来
        /// </summary>
        /// <param name="amount"></param>
        /// <returns></returns>
        public static string read(string amount)
        {
            try
            {
                if (amount == null || amount.Equals(""))
                {
                    throw new Exception("输入的数字为空,请输入一个有效数字。");
                }

                //分割为整数部分和小数部分
                string[] aryAmount = amount.Split('.');
                if (aryAmount.Length > 2)
                {
                    throw new Exception($"输入的数字中包含{aryAmount.Length - 1}个“.”,请查证后再次输入。");
                }

                //如果只有整数部分
                if (aryAmount.Length == 1)
                {
                    string strLower = readOnePart(aryAmount[0], true).Trim();
                    return strLower.Substring(0, 1).ToUpper() + strLower.Substring(1, strLower.Length - 1);
                }
                else
                {
                    //包含小数部分
                    if (aryAmount[0] == null || aryAmount[0].Equals(""))
                    {
                        //如果数字以“.”开头,就当它没有整数只有小数
                        string strLower = readOnePart(aryAmount[1], false).Trim();
                        return strLower.Substring(0, 1).ToUpper() + strLower.Substring(1, strLower.Length - 1);
                    }
                    else
                    {
                        string strLower = readOnePart(aryAmount[0], true).Trim() + " and " + readOnePart(aryAmount[1], false).Trim();
                        return strLower.Substring(0, 1).ToUpper() + strLower.Substring(1, strLower.Length - 1);
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

2、读取各个部分啦,这里要加dollar或cent,那么就添加了一个bool参数判断是整数部分还是小数部分。现在想想判断哪个部分可以放在上面第一步的函数里面。

        /// <summary>
        /// 读取整数或小数部分
        /// </summary>
        /// <param name="part">待读取的字符串</param>
        /// <param name="isIntPart">是否是整数部分</param>
        /// <returns></returns>
        private static string readOnePart(string part, bool isIntPart)
        {
            try
            {
                //将这个部分按照每三位一个划分
                List<string> lisParts = spiltThreeChars(part);

                //依次读取每个部分,然后在每个部分后加上单位,比如dollars,cents
                string strPartRead = "";

                if (isIntPart)
                {
                    #region 读取整数部分
                    string[] strIntegerUnit =
                    {
                        "",          //0
                        " thousand", //1
                        " million",  //2
                        " billion"   //3
                    };

                    //读取整数部分,单位为billion,million,thousand,Dollar(s)
                    for (int i = 0; i < lisParts.Count(); i++)
                    {
                        string strTempThree = readThreeNumbers(lisParts[i]);
                        if (strTempThree != null || !strTempThree.Equals(""))
                        {
                            strTempThree += strIntegerUnit[lisParts.Count() -1 - i];
                        }
                        strPartRead += strTempThree;
                    }
                    //如果没有整数部分,就直接返回emptystring
                    if (strPartRead.Trim().Equals(""))
                    {
                        return strPartRead;
                    }

                    //根据数值,看dollar后面是否加s
                    if (strPartRead.Trim().Equals("one"))
                    {
                        strPartRead += " dollar";
                    }
                    else
                    {
                        strPartRead += " dollars";
                    }
                    return strPartRead;
                    #endregion
                }
                else
                {
                    #region 读取小数部分
                    string strFloat = "";
                    if (lisParts.Count() == 0)
                    {
                        return "";
                    }
                    else if (lisParts.Count() == 1)
                    {
                        strFloat = readThreeNumbers(lisParts[0]);
                    }
                    else
                    {
                        throw new Exception("小数部分最多三位数,当前太多啦。");
                    }

                    //判断cent后面要不要加s
                    if (strFloat.Trim().Equals("one"))
                    {
                        return strFloat + " cent";
                    }
                    else
                    {
                        return strFloat + " cents";
                    }
                    #endregion
                }
            }
            catch (Exception e) { throw e; }
        }

3、读取三个一组的数字,这里写了两个函数,还有一个函数是读取[0,99]的数字

        /// <summary>
        /// 读取[0-100]范围的数字,其中包含了readUnitNumber方法
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        private static string readThreeNumbers(string v)
        {
            try
            {
                //取百位数字以及剩下的数字
                int intHundred = 0;
                int intRest = 0;
                try
                {
                    intHundred = int.Parse(v.Substring(0, 1));
                    intRest = int.Parse(v.Substring(1, 2));
                }
                catch (Exception e)
                {
                    throw new Exception($"您的输入“{v}” 有误,请检查后再次输入。");
                }

                string strHundred = "";
                string strRest = "";
                if (intHundred != 0)
                {
                    return readUnitNumber(intHundred) + " hundred" + readUnitNumber(intRest);
                }
                else
                {
                    return readUnitNumber(intRest);
                }
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        /// <summary>
        /// 读取[0-99]范围的数字
        /// </summary>
        /// <param name="unit"></param>
        /// <returns></returns>
        private static string readUnitNumber(int unit)
        {
            try
            {
                if (unit <= 20)
                {
                    #region 读取[0,20]区间的数字
                    switch (unit)
                    {
                        case 0:
                            return "";
                        case 1:
                            return " one";
                        case 2:
                            return " two";
                        case 3:
                            return " three";
                        case 4:
                            return " four";
                        case 5:
                            return " five";
                        case 6:
                            return " six";
                        case 7:
                            return " seven";
                        case 8:
                            return " eight";
                        case 9:
                            return " nine";
                        case 10:
                            return " ten";
                        case 11:
                            return " eleven";
                        case 12:
                            return " twelve";
                        case 13:
                            return " thirteen";
                        case 14:
                            return " fourteen";
                        case 15:
                            return " fifteen";
                        case 16:
                            return " sixteen";
                        case 17:
                            return " seventeen";
                        case 18:
                            return " eighteen";
                        case 19:
                            return " ninteen";
                        case 20:
                            return " twenty";
                        default:
                            return null;

                    }
                    #endregion
                }
                else
                {
                    #region 读取[21,99]区间的数字
                    //十位
                    int intTen = unit / 10;
                    //个位
                    int intUnitDigit = unit % 10;

                    switch (intTen)
                    {
                        case 2:
                            return " twenty" + readUnitNumber(intUnitDigit);
                        case 3:
                            return " thirty" + readUnitNumber(intUnitDigit);
                        case 4:
                            return " fourty" + readUnitNumber(intUnitDigit);
                        case 5:
                            return " fifty" + readUnitNumber(intUnitDigit);
                        case 6:
                            return " sixty" + readUnitNumber(intUnitDigit);
                        case 7:
                            return " seventy" + readUnitNumber(intUnitDigit);
                        case 8:
                            return " eighty" + readUnitNumber(intUnitDigit);
                        case 9:
                            return " ninty" + readUnitNumber(intUnitDigit);
                        default:
                            return null;
                    }
                    #endregion
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

4、将字符串用“0”补全至长度为三的倍数,然后划分为三个字符为单位的数组,放在list容器中。

        /// <summary>
        /// 将字符串按照三个字符一组划分
        /// </summary>
        /// <param name="part">待划分字符串</param>
        /// <returns></returns>
        private static List<string> spiltThreeChars(string part)
        {
            try
            {
                //将字符串长度补全为3的倍数,如果不是三的倍数就在开头补0
                int intLess = part.Length % 3;
                if (intLess != 0)
                {
                    for (int i = 0; i < 3 - intLess; i++)
                    {
                        part = "0" + part;
                    }
                }

                //每三个字符一分割
                List<string> lisThreeCharsArray = new List<string>();
                char[] aryChars = part.ToArray();
                for (int i = 0; i < aryChars.Length / 3; i++)
                {
                    string strTemp = aryChars[i * 3].ToString() + aryChars[i * 3 + 1].ToString() + aryChars[i * 3 + 2].ToString();
                    lisThreeCharsArray.Add(strTemp);
                }
                return lisThreeCharsArray;
            }
            catch (Exception e)
            {
                throw e;
            }
        }


这基本就是我当时写的代码,然后面试官说一般,请问这题还有别的什么解决思路?请各位讨论一下。




最后附上整个类

    class Dollars
    {
        /// <summary>
        /// 如果输入的字符串是数字,则读出来
        /// </summary>
        /// <param name="amount"></param>
        /// <returns></returns>
        public static string read(string amount)
        {
            try
            {
                if (amount == null || amount.Equals(""))
                {
                    throw new Exception("输入的数字为空,请输入一个有效数字。");
                }

                //分割为整数部分和小数部分
                string[] aryAmount = amount.Split('.');
                if (aryAmount.Length > 2)
                {
                    throw new Exception($"输入的数字中包含{aryAmount.Length - 1}个“.”,请查证后再次输入。");
                }

                //如果只有整数部分
                if (aryAmount.Length == 1)
                {
                    string strLower = readOnePart(aryAmount[0], true).Trim();
                    return strLower.Substring(0, 1).ToUpper() + strLower.Substring(1, strLower.Length - 1);
                }
                else
                {
                    //包含小数部分
                    if (aryAmount[0] == null || aryAmount[0].Equals(""))
                    {
                        //如果数字以“.”开头,就当它没有整数只有小数
                        string strLower = readOnePart(aryAmount[1], false).Trim();
                        return strLower.Substring(0, 1).ToUpper() + strLower.Substring(1, strLower.Length - 1);
                    }
                    else
                    {
                        string strLower = readOnePart(aryAmount[0], true).Trim() + " and " + readOnePart(aryAmount[1], false).Trim();
                        return strLower.Substring(0, 1).ToUpper() + strLower.Substring(1, strLower.Length - 1);
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// 读取整数或小数部分
        /// </summary>
        /// <param name="part">待读取的字符串</param>
        /// <param name="isIntPart">是否是整数部分</param>
        /// <returns></returns>
        private static string readOnePart(string part, bool isIntPart)
        {
            try
            {
                //将这个部分按照每三位一个划分
                List<string> lisParts = spiltThreeChars(part);

                //依次读取每个部分,然后在每个部分后加上单位,比如dollars,cents
                string strPartRead = "";

                if (isIntPart)
                {
                    #region 读取整数部分
                    string[] strIntegerUnit =
                    {
                        "",          //0
                        " thousand", //1
                        " million",  //2
                        " billion"   //3
                    };

                    //读取整数部分,单位为billion,million,thousand,Dollar(s)
                    for (int i = 0; i < lisParts.Count(); i++)
                    {
                        string strTempThree = readThreeNumbers(lisParts[i]);
                        if (strTempThree != null || !strTempThree.Equals(""))
                        {
                            strTempThree += strIntegerUnit[lisParts.Count() -1 - i];
                        }
                        strPartRead += strTempThree;
                    }
                    //如果没有整数部分,就直接返回emptystring
                    if (strPartRead.Trim().Equals(""))
                    {
                        return strPartRead;
                    }

                    //根据数值,看dollar后面是否加s
                    if (strPartRead.Trim().Equals("one"))
                    {
                        strPartRead += " dollar";
                    }
                    else
                    {
                        strPartRead += " dollars";
                    }
                    return strPartRead;
                    #endregion
                }
                else
                {
                    #region 读取小数部分
                    string strFloat = "";
                    if (lisParts.Count() == 0)
                    {
                        return "";
                    }
                    else if (lisParts.Count() == 1)
                    {
                        strFloat = readThreeNumbers(lisParts[0]);
                    }
                    else
                    {
                        throw new Exception("小数部分最多三位数,当前太多啦。");
                    }

                    //判断cent后面要不要加s
                    if (strFloat.Trim().Equals("one"))
                    {
                        return strFloat + " cent";
                    }
                    else
                    {
                        return strFloat + " cents";
                    }
                    #endregion
                }
            }
            catch (Exception e) { throw e; }
        }

        /// <summary>
        /// 读取[0-100]范围的数字,其中包含了readUnitNumber方法
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        private static string readThreeNumbers(string v)
        {
            try
            {
                //取百位数字以及剩下的数字
                int intHundred = 0;
                int intRest = 0;
                try
                {
                    intHundred = int.Parse(v.Substring(0, 1));
                    intRest = int.Parse(v.Substring(1, 2));
                }
                catch (Exception e)
                {
                    throw new Exception($"您的输入“{v}” 有误,请检查后再次输入。");
                }

                string strHundred = "";
                string strRest = "";
                if (intHundred != 0)
                {
                    return readUnitNumber(intHundred) + " hundred" + readUnitNumber(intRest);
                }
                else
                {
                    return readUnitNumber(intRest);
                }
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        /// <summary>
        /// 读取[0-99]范围的数字
        /// </summary>
        /// <param name="unit"></param>
        /// <returns></returns>
        private static string readUnitNumber(int unit)
        {
            try
            {
                if (unit <= 20)
                {
                    #region 读取[0,20]区间的数字
                    switch (unit)
                    {
                        case 0:
                            return "";
                        case 1:
                            return " one";
                        case 2:
                            return " two";
                        case 3:
                            return " three";
                        case 4:
                            return " four";
                        case 5:
                            return " five";
                        case 6:
                            return " six";
                        case 7:
                            return " seven";
                        case 8:
                            return " eight";
                        case 9:
                            return " nine";
                        case 10:
                            return " ten";
                        case 11:
                            return " eleven";
                        case 12:
                            return " twelve";
                        case 13:
                            return " thirteen";
                        case 14:
                            return " fourteen";
                        case 15:
                            return " fifteen";
                        case 16:
                            return " sixteen";
                        case 17:
                            return " seventeen";
                        case 18:
                            return " eighteen";
                        case 19:
                            return " ninteen";
                        case 20:
                            return " twenty";
                        default:
                            return null;

                    }
                    #endregion
                }
                else
                {
                    #region 读取[21,99]区间的数字
                    //十位
                    int intTen = unit / 10;
                    //个位
                    int intUnitDigit = unit % 10;

                    switch (intTen)
                    {
                        case 2:
                            return " twenty" + readUnitNumber(intUnitDigit);
                        case 3:
                            return " thirty" + readUnitNumber(intUnitDigit);
                        case 4:
                            return " fourty" + readUnitNumber(intUnitDigit);
                        case 5:
                            return " fifty" + readUnitNumber(intUnitDigit);
                        case 6:
                            return " sixty" + readUnitNumber(intUnitDigit);
                        case 7:
                            return " seventy" + readUnitNumber(intUnitDigit);
                        case 8:
                            return " eighty" + readUnitNumber(intUnitDigit);
                        case 9:
                            return " ninty" + readUnitNumber(intUnitDigit);
                        default:
                            return null;
                    }
                    #endregion
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// 将字符串按照三个字符一组划分
        /// </summary>
        /// <param name="part">待划分字符串</param>
        /// <returns></returns>
        private static List<string> spiltThreeChars(string part)
        {
            try
            {
                //将字符串长度补全为3的倍数,如果不是三的倍数就在开头补0
                int intLess = part.Length % 3;
                if (intLess != 0)
                {
                    for (int i = 0; i < 3 - intLess; i++)
                    {
                        part = "0" + part;
                    }
                }

                //每三个字符一分割
                List<string> lisThreeCharsArray = new List<string>();
                char[] aryChars = part.ToArray();
                for (int i = 0; i < aryChars.Length / 3; i++)
                {
                    string strTemp = aryChars[i * 3].ToString() + aryChars[i * 3 + 1].ToString() + aryChars[i * 3 + 2].ToString();
                    lisThreeCharsArray.Add(strTemp);
                }
                return lisThreeCharsArray;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值