-2

对于三位数,我在执行此操作时遇到了一些麻烦。我可以对两位数执行此操作,但是当我将 if 语句添加到字符串 TwoDigit 时,它会告诉我检测到无法访问的代码。这是我尝试过的:-

{
    class Program
    {
        static string[] digitWords =
        { "zero", "one", "two", "three", "four",
            "five", "six", "seven", "eight", "nine",
            "ten", "eleven", "twelve", "thirteen", "fourteen",
            "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };

        static string[] tenWords =
        { "", "", "twenty", "thirty", "forty",
          "fifty", "sixty", "seventy", "eighty", "ninety" };

        static string[] hundredWords = { "One-hundred", "two-hundred",
          "three-hundred", "four-hundred", "five-hundred", "six-hundred",
          "seven-hundred", "eight-hundred", "nine-hundred"}

        static string TwoDigit(int num)
        {
            if (num < 0 || num > 99) return "";
            if (num < 20) return digitWords[num];
            if (num % 10 == 0)
                return tenWords[num / 10];
            else
                return tenWords[num / 10] + "-" + digitWords[num % 10];

            if (num % 100 == 0)
                return digitWords[num / 100] + "-" + hundredWords[num % 100];
            else
                return digitWords[num / 100] + "-" + hundredWords[num % 100] + "-" + digitWords[num % 100];
        }

        static void Main(string[] args)
        {
            for (int i = 0; i <= 19; i++)
                Console.WriteLine("{0}: {1}", i, TwoDigit(i));
            for (int i = 20; i <= 99; i +=7)
                Console.WriteLine("{0}: {1}", i, TwoDigit(i));
            for (int i = 100; i <= 1100; i += 7)
                Console.WriteLine("{0}: {1}", i, TwoDigit(i));
        }
    }
}
4

6 回答 6

0

我前段时间在 SO 上找到了以下代码,并相信它是一个令人钦佩的紧凑型 Linq 来解决这个问题。我现在找不到帖子,所以如果有人认出了它,并且可以链接到原始解决方案,那就太好了。我不是为此获得荣誉的人。

    private static Dictionary<string, long> numberTable =
    new Dictionary<string, long>
    {{"zero",0},{"one",1},{"two",2},{"three",3},{"four",4},
    {"five",5},{"six",6},{"seven",7},{"eight",8},{"nine",9},
    {"ten",10},{"eleven",11},{"twelve",12},{"thirteen",13},
    {"fourteen",14},{"fifteen",15},{"sixteen",16},
    {"seventeen",17},{"eighteen",18},{"nineteen",19},{"twenty",20},
    {"thirty",30},{"forty",40},{"fifty",50},{"sixty",60},
    {"seventy",70},{"eighty",80},{"ninety",90},{"hundred",100},
    {"thousand",1000},{"million",1000000},{"billion",1000000000},
    {"trillion",1000000000000},{"quadrillion",1000000000000000},
    {"quintillion",1000000000000000000}};

    public static long ToLong(string numberString)
    {
        var numbers = Regex.Matches(numberString, @"\w+").Cast<Match>()
             .Select(m => m.Value.ToLowerInvariant())
             .Where(v => numberTable.ContainsKey(v))
             .Select(v => numberTable[v]);
        long acc = 0, total = 0L;
        foreach (var n in numbers)
        {
            if (n >= 1000)
            {
                total += (acc * n);
                acc = 0;
            }
            else if (n >= 100)
            {
                acc *= n;
            }
            else acc += n;
        }
        return (total + acc) * (numberString.StartsWith("minus",
              StringComparison.InvariantCultureIgnoreCase) ? -1 : 1);
    }
于 2012-11-15T01:53:39.987 回答
0

对于您遇到的错误的特定问题:

您的第三个 if 语句将始终返回一个值,因此您永远不会到达第四个 if 语句。(请记住,一旦您返回,您就完成了该功能,其余代码将不会被执行!)

此外,您可能想在这里重新考虑您的逻辑,因为输入任何值 > 99 只会返回 "" 作为最终答案

于 2012-11-15T00:47:30.100 回答
0

我相信您可以通过在 TwoDigit 顶部添加一个字符串来解决此问题,该字符串将不同的值连接到其上,然后在最后返回新字符串:

static string TwoDigit(int num)
{
    string newstring = ""; 

    if (num < 0 || num > 99) return "";
    if (num < 20) return digitWords[num];
    if (num % 10 == 0)
        newstring += tenWords[num / 10];
    else
        newstring += tenWords[num / 10] + "-" + digitWords[num % 10];

    if (num % 100 == 0)
        newstring += digitWords[num / 100] + "-" + hundredWords[num % 100];
    else
        newstring += digitWords[num / 100] + "-" + hundredWords[num % 100] + "-" + 
              digitWords[num % 100];

   return newstring; 
}

如果我理解正确的话,这样的事情应该会起作用。

发生这种情况的原因(正如其他人所提到的)是第一个 if/else 块将始终退出函数,无论传入什么值。您的编译器正在检测到这一点并向您抛出错误,因为它有一种感觉正在做一些你不打算做的事情。(C# 是强类型的,编译器不允许像 C 或 C++ 之类的语言那样做很多类似的事情,C 或 C++ 会允许这样做,但你会得到意想不到的结果和逻辑错误)

编辑:经过进一步思考,您需要更改连接数字的顺序(第一个,十秒,最后一个)以使其有意义。

于 2012-11-15T01:11:05.257 回答
0

刚刚在这里看到了这个有趣的解决方案:

namespace NumToText
{
    static class NumberToText
    {
        private static string[] _ones =
        {
            "zero",
            "one",
            "two",
            "three",
            "four",
            "five",
            "six",
            "seven",
            "eight",
            "nine"
        };

        private static string[] _teens =
        {
            "ten",
            "eleven",
            "twelve",
            "thirteen",
            "fourteen",
            "fifteen",
            "sixteen",
            "seventeen",
            "eighteen",
            "nineteen"
        };

        private static string[] _tens =
        {
            "",
            "ten",
            "twenty",
            "thirty",
            "forty",
            "fifty",
            "sixty",
            "seventy",
            "eighty",
            "ninety"
        };

        // US Nnumbering:
        private static string[] _thousands =
        {
            "",
            "thousand",
            "million",
            "billion",
            "trillion",
            "quadrillion"
        };

        /// <summary>
        /// Converts a numeric value to words suitable for the portion of
        /// a check that writes out the amount.
        /// </summary>
        /// <param name="value">Value to be converted</param>
        /// <returns></returns>
        public static string Convert(decimal value)
        {
            string digits, temp;
            bool showThousands = false;
            bool allZeros = true;

            // Use StringBuilder to build result
            StringBuilder builder = new StringBuilder();
            // Convert integer portion of value to string
            digits = ((long)value).ToString();
            // Traverse characters in reverse order
            for (int i = digits.Length - 1; i >= 0; i--)
            {
                int ndigit = (int)(digits[i] - '0');
                int column = (digits.Length - (i + 1));

                // Determine if ones, tens, or hundreds column
                switch (column % 3)
                {
                    case 0:        // Ones position
                        showThousands = true;
                        if (i == 0)
                        {
                            // First digit in number (last in loop)
                            temp = String.Format("{0} ", _ones[ndigit]);
                        }
                        else if (digits[i - 1] == '1')
                        {
                            // This digit is part of "teen" value
                            temp = String.Format("{0} ", _teens[ndigit]);
                            // Skip tens position
                            i--;
                        }
                        else if (ndigit != 0)
                        {
                            // Any non-zero digit
                            temp = String.Format("{0} ", _ones[ndigit]);
                        }
                        else
                        {
                            // This digit is zero. If digit in tens and hundreds
                            // column are also zero, don't show "thousands"
                            temp = String.Empty;
                            // Test for non-zero digit in this grouping
                            if (digits[i - 1] != '0' || (i > 1 && digits[i - 2] != '0'))
                                showThousands = true;
                            else
                                showThousands = false;
                        }

                        // Show "thousands" if non-zero in grouping
                        if (showThousands)
                        {
                            if (column > 0)
                            {
                                temp = String.Format("{0}{1}{2}",
                                    temp,
                                    _thousands[column / 3],
                                    allZeros ? " " : ", ");
                            }
                            // Indicate non-zero digit encountered
                            allZeros = false;
                        }
                        builder.Insert(0, temp);
                        break;

                    case 1:        // Tens column
                        if (ndigit > 0)
                        {
                            temp = String.Format("{0}{1}",
                                _tens[ndigit],
                                (digits[i + 1] != '0') ? "-" : " ");
                            builder.Insert(0, temp);
                        }
                        break;

                    case 2:        // Hundreds column
                        if (ndigit > 0)
                        {
                            temp = String.Format("{0} hundred ", _ones[ndigit]);
                            builder.Insert(0, temp);
                        }
                        break;
                }
            }

            // Append fractional portion/cents
            builder.AppendFormat("and {0:00}/100", (value - (long)value) * 100);

            // Capitalize first letter
            return String.Format("{0}{1}",
                Char.ToUpper(builder[0]),
                builder.ToString(1, builder.Length - 1));
        }
    }
}
于 2013-08-17T12:14:14.443 回答
0

You have code with return in both branches - as result code after that if condition will never be executed:

   if (condition)
   {
      return 1;
   }
   else 
   { 
     return 2;
   }
   // never will reach here
   var i = 1; // unreachable code.
于 2012-11-15T00:45:26.263 回答
0

您可能会更清楚错误发生的位置,但我可以看到后半部分TwoDigit()无法访问。由于返回之前的语句的两种情况,if都无法执行下面的代码。return 语句退出该方法,并且不再执行该方法中的其他语句。这就是它无法到达的原因。

您可以在我的文章Converting Numbers to Words中的代码中看到我是如何做到这一点的。

于 2012-11-15T00:42:24.883 回答