Javaを使用して文字列の最初の「要素」のインデックスを見つけるにはどうすればよいですか?
質問
私は、Javaで簡単なPrologインタープリターの作成に取り組んでいます。
" List Syntax"の文字列の最初の要素または最後の要素の最初の要素の最後の文字インデックスを見つけるにはどうすればよいですか?
リスト構文は次のようになります:
(X)
(p a b)
(func(func2 a)(func3 X Y))
(等しいイブ(マザーカイン))
これらの各文字列の順番は次のとおりです。
ヘッド:" X&quot ;、インデックス:1
ヘッド:" p&quot ;、インデックス:1
ヘッド:" func&quot ;、インデックス:4
Head:" equal"、Index:5
基本的に、最初の"("の直後で、スペースまたは終了")"のいずれか早い方で終わる文字列と一致させる必要があります。 head要素の最後の文字の文字インデックスが必要です。
このインデックスをJavaで照合して取得するにはどうすればよいですか
Brabsterのソリューションは非常に近いものです。ただし、次の場合を考慮してください。
((b X)Y)
head要素が(b x)の場合。スキャナーの区切り記号から"("を削除して修正しようとしましたが、" b"と&x ;.
同様に: ((((b W)X)Y)Z)
頭は(((b w)x)Y)です。
解決
Javaのスキャナークラス(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
これは非常にエレガントなソリューションではありませんが、正規表現はカウントできません(つまり、括弧)。そこにさらに複雑さがあれば、パーサージェネレーターの使用を考えています:)
他のヒント
それを総当たり攻撃できない理由はありますか?このようなものですか?
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;
}
}
}
ここで何かが足りないかもしれませんが、うまくいくと思う 。
適切なパーサーを作成することをお勧めします( Prologの場合は演算子の優先順位 )、さらに処理するために用語をJavaオブジェクトのツリーとして表します。