2

私はJavaで簡単なPrologインタープリターを書くことに取り組んでいます。

「リスト構文」で文字列のhead要素またはtail要素の最初の要素の最後の文字インデックスを見つけるにはどうすればよいですか?

リストの構文は次のようになります。

(X)
(pab)
(func(func2 a)(func3 XY))
(equal eve(mother cain))

これらの各文字列のヘッドは、次のとおりです。
ヘッド: "X"、インデックス:1
ヘッド: "p"、インデックス:1
ヘッド: "func"、インデックス:4
ヘッド: "等しい"、インデックス:5

基本的に、最初の「(」の直後にあり、スペースまたは終了「)」のいずれか早い方で終わる文字列を一致させる必要があります。head要素の最後の文字の文字インデックスが必要です。

Javaでこのインデックスを照合して取得するにはどうすればよいですか?


ブラブスターのソリューションは本当に近いです。ただし、次の場合を考えてみましょう:
((b X)Y)

ヘッド要素は(bx)です。スキャナーの区切り文字から「(」を削除して修正しようとしましたが、「b」と「x」の間にスペースがあるため、問題が発生します。

同様に:((((b W)X)Y)Z)

頭は(((bw)x)Y)です。

4

3 に答える 3

4

Java のScannerクラス (Java 1.5 で導入) は、開始するのに適した場所かもしれません。

これはあなたが望むことをすると思う例です(文字カウント機能を含むように更新されました)

public class Test {

    public static void main(String[] args) {

        String[] data = new String[] {
                "(X)",
                "(p a b)",
                "(func (func2 a) (func3 X Y))",
                "(equal eve (mother cain))",
                "((b X) Y)",
                "((((b W) X) Y) Z)"
        };


        for (String line:data) {
            int headIdx = 0;
            if (line.charAt(1) == '(') {
                headIdx = countBrackets(line);
            } else {
                String head = "";
                Scanner s = new Scanner(line);
                s.useDelimiter("[)|(| ]");
                head = s.next();
                headIdx = line.indexOf(head) + head.length() - 1;
            }
            System.out.println(headIdx);
        }

    }

    private static int countBrackets(String line) {
        int bracketCount = 0;
        int charCount = 0;
        for (int i = 1; i < line.length(); i++) {
            char c = line.charAt(i);
            if (c == '(') {
                bracketCount++;
            } else if (c == ')') {
                bracketCount--;
            }
            if (bracketCount == 0) {
                return charCount + 1;
            }
            charCount++;
        }
        throw new IllegalStateException("Brackets not nested properly");
    }
}

出力:

1
1
4
5
5
13

これはあまり洗練されたソリューションではありませんが、正規表現はカウントできません (つまり、括弧)。そこにさらに複雑さがあれば、パーサージェネレーターを使用することを考えています:)

于 2009-09-17T19:15:26.510 に答える
1

力ずくで打てない理由ってあるの?このようなもの?

public int firstIndex( String exp ) {
    int parenCount = 0;
    for (int i = 1; i < exp.length(); i++) {
        if (exp.charAt(i) == '(') {
            parenCount++;
        }
        else if (exp.charAt(i) == ')') {
            parenCount--;
        }
        if (parenCount == 0 && (exp.charAt(i+1) == ' ' || exp.charAt(i) == ')')) {
            return i;
        }
    }
}

ここで何かが足りないかもしれませんが、うまくいくと思います

于 2009-09-17T22:07:06.420 に答える
0

適切なパーサー ( Prolog の場合は演算子の優先順位) を作成し、さらに処理するために用語を Java オブジェクトのツリーとして表現することをお勧めします。

于 2009-09-17T19:25:21.410 に答える