文字の配列内の開き括弧の位置を指定すると、カウンターを使用して一致する閉じ括弧を見つける単純なアルゴリズムがあります。
- カウンターを 1 に初期化します。
- テキストを順方向 (右方向) にループします。
- 別の開き括弧が検出された場合は、カウンターをインクリメントします。
- 閉じ括弧が検出された場合は、カウンターをデクリメントします。
- カウンターがゼロになると、対応する閉じ括弧が見つかりました。
コードでは、これは次のようになります。
public int findClosingParen(char[] text, int openPos) {
int closePos = openPos;
int counter = 1;
while (counter > 0) {
char c = text[++closePos];
if (c == '(') {
counter++;
}
else if (c == ')') {
counter--;
}
}
return closePos;
}
閉じ括弧が与えられた場合に対応する開き括弧の位置を見つけるアルゴリズムは逆です。
- カウンターを 1 に初期化します。
- テキストを逆方向 (左方向) にループします。
- 左括弧が検出された場合は、カウンターをデクリメントします。
- 閉じ括弧が検出された場合は、カウンターをインクリメントします。
- カウンターがゼロになると、対応する開き括弧が見つかりました。
コード内:
public int findOpenParen(char[] text, int closePos) {
int openPos = closePos;
int counter = 1;
while (counter > 0) {
char c = text[--openPos];
if (c == '(') {
counter--;
}
else if (c == ')') {
counter++;
}
}
return openPos;
}
注:上記の例はいずれも、括弧のバランスが取れていることを前提としているため、配列の境界チェックは行われません。実際の実装では、配列の末尾からはみ出していないことを確認し、そうであれば、入力テキストでかっこのバランスが取れていないことを示す例外をスロー (またはエラー コードを返します) します。