簡體   English   中英

比較兩個不同的數據類型對?

[英]Comparing Two different data type pairs?

我正在研究一個問題,以檢查Java中的括號是否平衡。

每個括號都具有一個類型,並且類型是隨機整數。

(0(1)1(2(0)0)2)0

^這將被視為平衡。

即時通訊使用堆棧來實現這一點,但是我對如何比較和/或配對值以補償它們感到困惑?

這就是我現在所擁有的。

public class Parenthesis
{
private static final char OPEN = '(';
private static final char CLOSE = ')';

public static boolean isPair(char char1, char char2, int num1, int num2)
{
    if(char1 == OPEN && char2 == CLOSE && num1 == num2)
    {
        return true;
    }
    return false;
}

public static boolean checkBalanced(int[] p, boolean[] b)
{
    Stack storage = new Stack(b.length);

    for(int i=0; i<p.length; i++)
    {
        if(b[i]==false)
        {
           char o=OPEN;
           int numO=p[i];
           storage.push(o, numO);
        }
        else if(b[i]==true)
        {
            char c=CLOSE;
            int numC=p[i];
            if (storage.isEmpty() || 
!isPair(storage.popSymb(),c,storage.popNum(),numC))
            {
                return false;
            }
        }
    }
    if(storage.isEmpty())
    {
        return true;
    }
    else
        {
            return false;
        }
}
}

如果要手動實現此算法,則應實現以下幾個步驟:

  1. 如果符號是開括號,請將其推入堆棧。
  2. 如果符號是封閉的括號:
    • 如果stack不為空並且堆棧中的最后一個符號是開括號,則只需彈出開括號。
    • 否則將堆棧中的閉合支架推入。
  3. 如果堆棧因此為空,則表達式是平衡的。

例如

public class Parenthesis {
private static final char OPEN = '(';
private static final char CLOSE = ')';

private static boolean checkBalanced(String str) {

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

    char[] chars = str.toCharArray();
    for (char ch : chars) {
        if (ch == OPEN) {
            storage.push(ch);
        }

        if (ch == CLOSE) {
            if (storage.size() != 0 && storage.peek() == OPEN) {
                storage.pop();
            } else {
                storage.push(ch);
            }
        }
    }

    return storage.size() == 0;
}

public static void main(String[] args) {
    System.out.println(checkBalanced("(0(1)1(2(3)2)2)0"));
}

但我建議你使用反向波蘭表示法來實現這個算法。 https://en.wikipedia.org/wiki/Reverse_Polish_notation http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm

也許這段代碼可以幫助你:

import java.util.Stack;

import java.util.Stack;

public class Parenthesis {

    private static class Pair {

        private final char parenthesis;
        private final char number;

        Pair(String value) {
            this.parenthesis = value.charAt(0);
            this.number = value.charAt(1);
        }

        boolean canFormAPairWith(Pair pair) {
            if (parenthesis == ')') {
                return false;
            }
            return this.number == pair.number && pair.parenthesis == ')';
        }

    }

    public static void main(String[] args) {

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

        String example = "(0(1)1(2(0)0)2)0";
        for (String s : example.split("(?<=\\G.{2})")) {

            Pair currentPair = new Pair(s);
            if (!stack.isEmpty() && stack.peek().canFormAPairWith(currentPair)) {
                stack.pop();
            } else {
                stack.push(currentPair);
            }
        }

        System.out.println(stack.isEmpty());

    }
}

我並未針對所有案例進行測試,但針對您的案例進行了測試。

TL;博士

有工具!

無需編寫任何Java代碼。 只需使用ANTLR和下面給出的語法。

是的,您的輸入(0(1)1(2(0)0)2)0通過平衡。

ANTLR 4

ANTLR是一種語言識別工具。

  • 階段1
    您向ANTLR提供一個“語法”文件,該文件定義了編程語言(Java,C,COBOL,等等)或數據結構(XML,JSON,CSV,等等),然后ANTLR為詞法分析器生成Java源代碼。
  • 階段2
    您編譯這些源。 然后運行這些類,提供要分析的源代碼或數據文件。
    • 樂星
      處理字符流以識別以前稱為標記的單詞。
    • 解析
      處理令牌流以識別句子(編程語言中的語句或數據文件中的行)。 結果是一個抽象語法樹

使用ANTLR 4附帶的TestRig類通過控制台或文件輸入值。 如果您輸入的數字字符串和括號沒有正確平衡,則詞法分析將發出錯誤信號。

我只是ANTLR的新手,但是我根據Terence Parr《 ANTLR項目》的創建者)在《權威ANTLR 4參考》中 的示例改編的語法似乎正在為您完成這項工作。

grammar ParenBalance;

prog:   stat+ ;

stat:   expr NEWLINE
    |   NEWLINE
    ;

expr:  expr expr
    |   INT
    |   '(' expr ')'
    ;

INT :   [0-9]+ ;         // match integers
NEWLINE:'\r'? '\n' ;     // return newlines to parser (is end-statement signal)
WS  :   [ \t]+  ;

嘗試一些輸入(全部帶有換行符 ,未顯示):

  • 42次傳球
  • (42)通過
  • (42失敗,缺少')'
  • 42)失敗,無關的輸入')'
  • (((1)2)3)通過
  • ((1 2)3)失敗,輸入''不匹配,無關的輸入')'

我們來試試吧。

  • (0(1)1(2(0)0)2)0通過。

這是通過IntelliJ IDE的ANTLR4插件運行的ANTLR 4的屏幕截圖。 點擊放大。 ANTLR實際上是由控制台或Java代碼驅動的。 這里顯示的插件代表我們處理這種交互,因此我們可以在IDE中方便地工作。

通過ANTLR4插件在IntelliJ IDE中運行的ANTLR 4屏幕截圖

暫無
暫無

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

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