面试中遇到的一道算法题,请各位对我的算法指点一下
前几天面试,遇到一题上机题,由于写了大半年的安卓控件,对于一些基础函数都有点生疏,面试结束后,面试官说我的算法一般般,不过现在也没有想到哪里可以优化。请各位指点一下。
面试题目是这样的:将输入的账户余额以读取的形式转化出来。例如:
输入:123.12
输出:One hundred twenty three dollars and twelve cents
注意:dollar和cent的复数形式,有没有and连接等。
我的思路就是把整数和小数部分分开,然后分别读取各个部分。
读取每个部分的时候,先将该部分字符串补全至3的倍数个(前面加0),然后以三个字符为一组进行读取,先读百位,再读剩下两位。
最后根据两个部分的值,看情况把两个部分连接起来。
我写了五个函数,分别是:
1、读取函数。功能是将输入的字符串划分为两个部分,然后使用别的函数读出这两个部分,最后视情况添加and。
/// /// 如果输入的字符串是数字,则读出来/// /// /// 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参数判断是整数部分还是小数部分。现在想想判断哪个部分可以放在上面第一步的函数里面。
/// /// 读取整数或小数部分/// /// 待读取的字符串/// 是否是整数部分/// private static string readOnePart(string part, bool isIntPart){try{//将这个部分按照每三位一个划分List lisParts = spiltThreeChars(part);//依次读取每个部分,然后在每个部分后加上单位,比如dollars,centsstring 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;}//如果没有整数部分,就直接返回emptystringif (strPartRead.Trim().Equals("")){return strPartRead;}//根据数值,看dollar后面是否加sif (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后面要不要加sif (strFloat.Trim().Equals("one")){return strFloat + " cent";}else{return strFloat + " cents";}#endregion}}catch (Exception e) { throw e; }}
3、读取三个一组的数字,这里写了两个函数,还有一个函数是读取[0,99]的数字
/// /// 读取[0-100]范围的数字,其中包含了readUnitNumber方法/// /// /// 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;}}/// /// 读取[0-99]范围的数字/// /// /// 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容器中。
/// /// 将字符串按照三个字符一组划分/// /// 待划分字符串/// private static List spiltThreeChars(string part){try{//将字符串长度补全为3的倍数,如果不是三的倍数就在开头补0int intLess = part.Length % 3;if (intLess != 0){for (int i = 0; i < 3 - intLess; i++){part = "0" + part;}}//每三个字符一分割List lisThreeCharsArray = new List();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{/// /// 如果输入的字符串是数字,则读出来/// /// /// 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;}}/// /// 读取整数或小数部分/// /// 待读取的字符串/// 是否是整数部分/// private static string readOnePart(string part, bool isIntPart){try{//将这个部分按照每三位一个划分List lisParts = spiltThreeChars(part);//依次读取每个部分,然后在每个部分后加上单位,比如dollars,centsstring 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;}//如果没有整数部分,就直接返回emptystringif (strPartRead.Trim().Equals("")){return strPartRead;}//根据数值,看dollar后面是否加sif (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后面要不要加sif (strFloat.Trim().Equals("one")){return strFloat + " cent";}else{return strFloat + " cents";}#endregion}}catch (Exception e) { throw e; }}/// /// 读取[0-100]范围的数字,其中包含了readUnitNumber方法/// /// /// 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;}}/// /// 读取[0-99]范围的数字/// /// /// 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;}}/// /// 将字符串按照三个字符一组划分/// /// 待划分字符串/// private static List spiltThreeChars(string part){try{//将字符串长度补全为3的倍数,如果不是三的倍数就在开头补0int intLess = part.Length % 3;if (intLess != 0){for (int i = 0; i < 3 - intLess; i++){part = "0" + part;}}//每三个字符一分割List lisThreeCharsArray = new List();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;}}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
