-2

3桁でこれを行うのに問題があります。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

TwoDigit の先頭に文字列を追加して、異なる値を連結し、最後に newstring を返すことで、これを修正できると思います。

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++ はこれを許可しますが、意図しない結果や論理エラーが発生します)

編集:さらに熟考すると、意味をなすために、数字を連結する順序(最初に数百、数十秒、最後に1)を変更する必要があります。

于 2012-11-15T01:11:05.257 に答える
0

両方のブランチにコードがあります-その条件returnの後の結果コードは決して実行されません:if

   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 に答える
0

あなたが得ているエラーの特定の問題について:

3 番目の if ステートメントは常に値を返すため、4 番目の if ステートメントに到達することはありません。(一度戻ったら、その関数は完了しており、残りのコードは実行されないことを忘れないでください!)

また、99 を超える値を入力すると、最終的な回答として "" が返されるため、ここでロジックを再考することをお勧めします。

于 2012-11-15T00:47:30.100 に答える