簡體   English   中英

找到第一個外括號

[英]Find the first outer brackets

我需要找出第一個最外層(不是嵌套)括號索引。

例如

[]                         output: 0, 1
1[2]                       output: 1, 3
3[a2[c]]2[abc]3[cd]        output: 1, 7

我可以通過很多條件找到它,當前代碼:

public static void main(String[] args) {
    String input = "3[a2[c]]2[abc]3[cd]ef";
    int first = 0;
    int second = 0;

    int count = 0;
    boolean found = false;
    for (int index = 0; index < input.length(); index++) {
        if (input.charAt(index) == '[') {
            count++;
            if (found == false) {
                found = true;
                first = index;
            }
        } else if (input.charAt(index) == ']') {
            count--;
            if (found && count == 0) {
               second = index;
               break;
            }
        }
    }

    System.out.println(first);
    System.out.println(second);
}

有更clean方法嗎?

使用Stack可能更優雅:

String input = "3[a2[c]]2[abc]3[cd]ef";
Stack<Integer> stack = new Stack<> ();
int first = -1;
int second = -1;

for (int index = 0; index < input.length(); index++) {
    if (input.charAt(index) == '[') {
        stack.push(index);
    } else if (input.charAt(index) == ']' && !stack.isEmpty ()) {
        first = stack.pop ();
        if (stack.isEmpty ()) {
            second = index;
            break;
        }
    }
}

if (first >= 0 && second >= 0) {
    System.out.println(first);
    System.out.println(second);
} else {
  System.out.println ("not found");
}

我想補充一點,使用stack可能更優雅,但是增加了O(n) space complexity這在所有情況下可能都不可取。

我只是略微縮小了OP的原始計數器策略:

String input = "3[a2[c]]2[abc]3[cd]ef";
int first, second, index, indexOfFirstBracket = input.indexOf('['), count = 1;

for (index = indexOfFirstBracket + 1; index < input.length() && count != 0; index++) {
    if (input.charAt(index) == '[')
        count++;
    else if (input.charAt(index) == ']')
        count--;
}

first = indexOfFirstBracket;
second = index - 1;

System.out.println(first);
System.out.println(second);

這也是我使用stack制作的解決方案(我在代碼中添加了注釋以供解釋):

 String input = "3[a2[c]]2[abc]3[cd]ef";
    int first, second, count;
    boolean found = false;

    Stack<Character> stack = new Stack<>();

    // first index will always be fixed
    int indexOfFirstBracket = input.indexOf('[');
    first = indexOfFirstBracket;

    //intialize the stack
    stack.push('[');
    int i;

    //loop from index after first [ character
    for (i = indexOfFirstBracket + 1; i < input.length() && !stack.isEmpty(); i++) {
        if (input.charAt(i) == '[' || (input.charAt(i) == ']' && stack.peek() == ']'))
            stack.push('[');
        else if (input.charAt(i) == ']' && stack.peek() == '[')
            stack.pop();

    }

    // second index when loop breaks
    second = i - 1;

    System.out.println(first);
    System.out.println(second);

我假設輸入具有平衡括號。 如果我們想要,我們可以處理( if second == input.length )。

這是一個基於堆棧的解決方案(我希望它是不言自明的)

注意:這假定輸入字符串中的括號已正確平衡(代碼中就是這種情況)。

String input = "3[a2[c]]2[abc]3[cd]ef";
Stack<Character> stack = new Stack<>();
int start = input.indexOf("["); //find first '['

System.out.println(start);
for(int i = start + 1   ; i < input.length(); i++) {
    if(input.charAt(i) == '[') {
        stack.push('[');
    } else if (input.charAt(i) == ']') {
        if (stack.isEmpty()) {
            System.out.println(i); //Matching ']' for our first '['
            break;
        }
        stack.pop();
    }
}

我已經消除了其他解決方案所需的一些局部變量。 對於條件分支,只有一個簡單的操作:堆棧計數遞增或遞減。

String input = "3[a2[c]]2[abc]3[cd]ef";
int first = input.indexOf('[');
int second = first;
for(int stack = 1; first >= 0 && stack > 0; second++) {     
    switch(input.charAt(second+1)) {
    case '[':
        stack++;
        break;
    case ']':
        stack--;
        break;
    }
}
System.out.println(first);
System.out.println(second);

注:上面的代碼依賴於一個事實,即]永遠是平衡的,如你所說。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM