2

ユーザーが入力した式が用語に適している場合、私のプログラムは画面にメッセージを出力する必要があります(数字と文字のみを使用できます。「(」で始めることはできません。数式のように、各開き括弧には適切な(そして適切な場所にある)閉じ括弧であること。

ここに、プログラムが受け入れて出力する数式をいくつか示します。

真実-

  • a(aa(a)aaa(aa(a)aa)aa)aaaaaa
  • a(((())))

ここに、プログラムが受け入れて出力してはならないいくつかの式があります。

間違い-

  • ()()()
  • )()()(

しかし、プログラムは常に False を出力します コードを助けてくれてありがとう: EDIT

    bool IsNumeric(char character)
    {
        return "0123456789".Contains(character);
        // or return Char.IsNumber(character);
    }

    bool IsLetter(char character)
    {
        return "ABCDEFGHIJKLMNOPQRSTUVWXWZabcdefghigjklmnopqrstuvwxyz".Contains(character);

    }

    bool IsRecognized(char character)
    {
        return IsBracket(character) | IsNumeric(character) | IsLetter(character);
    }
    public bool IsValidInput(string input)
    {
        if (String.IsNullOrEmpty(input) || IsBracket(input[0]))
        {
            return false;
        }
        var bracketsCounter = 0;
        for (var i = 0; i < input.Length; i++)
        {
            var character = input[i];
            if (!IsRecognized(character))
            {
                return false;
            }
            if (IsBracket(character))
            {
                if (character == '(')
                    bracketsCounter++;
                if (character == ')')
                    bracketsCounter--;
            }
        }


        if (bracketsCounter > 0)
        {
            return false;
        }

        return bracketsCounter==0;
    }
}
}
4

2 に答える 2

3

あなたのアルゴリズムは不必要に複雑です - 必要なのはループとカウンターだけです。

  • の最初の文字を確認し(ます(すでに行っています)
  • カウンターをゼロに設定し、各文字を 1 つずつ調べます
  • 文字が文字でも括弧でもない場合は、false を返します
  • 文字がオープニング(の場合、カウンターをインクリメントします
  • 文字が終了の場合)、カウンターを減らします。カウンターがゼロ未満の場合、false を返します
  • trueループ終了後にカウントがゼロの場合は戻ります。それ以外の場合は戻りますfalse
于 2012-04-04T11:59:45.657 に答える
1

これをデバッグするのは本当に難しいですか?この条件:

((!IsNumeric(st[i])) && (st[i] != '(') && (st[i] != ')')&&((st[i]<'a')||(st[i]>'z')||(st[i]<'A')||(st[i]>'Z')))
    return false;

明らかに間違っています。毎回返ってきますfalse。より大きいaことを考慮しません。aZ

編集:

では、読みやすくするにはどうすればよいでしょうか。それが私が考え出した唯一の方法です。この問題の他の解決策はありますか?

その条件ブロックについては、たとえば、より小さなメソッド/関数を使用します。

bool IsBracket(char character)
{
    return (character == '(' | character == ')');
}

bool IsNumeric(char character)
{
    return "0123456789".Contains(character);
    // or return Char.IsNumber(character);
}

bool IsLetter(char character)
{
    // see why this is NOT prone to fail just because 'a' is greater than 'Z' in C#?
    return (character >= 'a' & character <= 'z') |
        (character >= 'A' & character <= 'Z');

    // or return Regex.IsMatch(character.ToString(), "[a-zA-Z]", RegexOptions.None);
    // or return Char.IsLetter(character);
}

// now you can implement:
bool IsRecognized(char character)
{
    return IsBracket(character) | IsNumeric(character) | IsLetter(character);
}

そして、大きなメソッドで安全に使用できます:

if (!IsRecognized(st[i]))
    return false;

このような些細な例ではやり過ぎのように見えるかもしれませんが、原則としてより優れたアプローチであり、確かに読みやすくなっています。

その後、コードを次のようなものに減らすことができます。

    bool IsInputValid(string input)
    {
        if (String.IsNullOrEmpty(input) || IsBracket(input[0]))
        {
            return false;
        }
        var bracketsCounter = 0;
        for (var i = 0; i < input.Length; i++)
        {
            var character = input[i];
            if (!IsRecognized(character))
            {
                return false;
            }
            if (IsBracket(character)) // redundant?
            {
                if (character == '(') // then what?
                if (character == ')') // then what?
            }
            if (bracketsCounter < what?)
            {
                what?
            }
        }
        return bracketsCounter == what?;
    }

(dasblinkenlightのアルゴリズム)

4月10日編集

間違えている。

    bool IsNumeric(char character)
    {
        return "0123456789".Contains(character);
        // or return Char.IsNumber(character);
    }

    bool IsLetter(char character)
    {
        return "ABCDEFGHIJKLMNOPQRSTUVWXWZabcdefghigjklmnopqrstuvwxyz".Contains(character);

    }

    bool IsRecognized(char character)
    {
        return IsBracket(character) | IsNumeric(character) | IsLetter(character);
    }
    public bool IsValidInput(string input)
    {
        if (String.IsNullOrEmpty(input) || IsBracket(input[0]))
        {
            return false;
        }
        var bracketsCounter = 0;
        for (var i = 0; i < input.Length; i++)
        {
            var character = input[i];
            if (!IsRecognized(character))
            {
                return false;
            }
            if (IsBracket(character))
            {
                if (character == '(')
                    bracketsCounter++;
                if (character == ')')
                    bracketsCounter--;
            }
            // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            if (bracketsCounter < 0) // NOT "> 0", and HERE - INSIDE the for loop
            {
                return false;
            }
            // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        }

        return bracketsCounter==0;
    }
}
}

ところで、あなたは IsLetter メソッドにも間違いを犯しました: ...UVWXWZ? UVWXYZである必要があります

于 2012-04-04T11:59:52.960 に答える