2011年2月28日 星期一

括號配對

從"in.txt"中輸入一個包含小括號()及中括號﹝﹞的字串。當字串符合下列條件時我們稱他為正確的運算式:
1.該字串為空字串。
2.如果A為正確的運算式,則(A)及﹝A﹞都為正確的運算式。
3.如果A和B都為正確的運算式,則AB也為正確的運算式。
4.字串最大長度為128個字元
5.輸入檔案的第一列為正整數n,代表接下來有n列的待測資料。
6.檢查每列待測資料,如果正確輸出Yes,否則輸出No。

輸入範例:

(﹝﹞)
((﹝()﹞)))
(﹝()﹝﹞()﹞)()
輸出範例:
Yes
No
Yes


>> http://chscvb.blogspot.com/2010/02/20100217.html

11 則留言:

  1. Private Sub Form_Load()
    Me.Hide

    Dim ins As String

    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2

    Input #1, times

    If times <= 0 Then Exit Sub
    For i = 1 To times
    Input #1, ins
    R = 0: L = 0
    If Len(ins) > 128 Then Print #2, "No": Exit For

    For k = 1 To Len(ins)
    gotit = Mid(ins, k, 1)
    If gotit = "(" Or gotit = "﹝" Then R = R + 1
    If gotit = ")" Or gotit = "﹞" Then L = L + 1
    Next
    If R = L Then Print #2, "Yes" Else Print #2, "No"

    Next

    Close
    Close

    End


    End Sub


    //----------

    有點看不懂題意

    這樣不知道算對還錯 ((<)>)

    回覆刪除
  2. arro好,
    錯。
    小括弧和中括弧都要成對出現。不只是個數相同,而是,出現的組合。
    這是「堆疊stack」的觀念。
    (([))]
    這是錯的。
    ([)]
    也是錯的。
    ([])[]()
    是對的。

    回覆刪除
  3. 什麼是堆疊!!?

    我想過從外面開始猜
    可是會遇到
    ([])[]()
    又假設先用()~隔1個不就是([])
    K = 1 不是")"
    迴圈
    K = K+ 2 裡面會成對

    但又怕
    遇到
    (﹝()﹝﹞()﹞)()

    回覆刪除
  4. Private Sub Form_Load()
    Me.Hide


    Dim strs As String, ans As Boolean
    Dim ins As String


    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2

    Input #1, times

    If times <= 0 Then Exit Sub


    For i = 1 To times

    Input #1, ins
    R = 0: L = 0
    ans = True
    strs = ""

    If Len(ins) > 128 Then Print #2, "No": Exit For

    For k = 1 To Len(ins)
    gotit = Mid(ins, k, 1)
    If gotit = "(" Then R = R + 1: strs = strs + "1"
    If gotit = ")" Then L = L + 1: If Right(strs, 1) = "1" Then strs = strs \ 10 Else ans = False
    If gotit = "﹝" Then R = R + 1: strs = strs + "2"
    If gotit = "﹞" Then L = L + 1: If Right(strs, 1) = "2" Then strs = strs \ 10 Else ans = False
    Print #2, strs, gotit
    Next

    If strs <> "0" Then ans = False
    If R <> L Then ans = False
    If ans = True Then Print #2, "Yes" Else Print #2, "No"
    Next


    Close
    Close

    End


    End Sub


    //-----------

    仔細想過後,發現其實蠻簡單的
    只是要想出 怎麼讓他記錄上個及上上個...是什麼
    還真的一時找不到方法


    我是用字串去把左方括弧接起來,發後出現右方括弧時再消掉

    回覆刪除
  5. arro好,
    程式應該是可以,但是,字串和數字的用法,要分一下。
    數字的少掉個位數,才是用\10的方式,字串的話,請用mid,right,left這三個函數吧。
    strs = strs \ 10
    strs = left(strs,len(strs)-1)
    後面的方式比較好,
    但是,你如果改了之後,最後的檢查,就記得用if strs<>"" then

    還有,你特別用了1,2來記住([, 是可以的,但是,直接用([放進字串中,一樣可以檢查。


    佑好,
    stack就是先進的後出,後進的先出。 像疊盤子一樣,疊的時候,從最上面放,拿的時候,也是從最上面拿。

    回覆刪除
  6. 終於寫出來了,
    我是由內往外拆。


    Dim Times As Byte
    Dim N As String
    Dim T As Boolean



    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, Times

    For i = 1 To Times
    Input #1, N

    If Len(N) <= 128 Then

    T = True

    Do
    N = Replace(N, "()", "")
    N = Replace(N, "[]", "")
    Loop Until (InStr(N, "()") = 0) And (InStr(N, "[]") = 0)

    If Len(N) <> 0 Then T = False

    Else
    T = False
    End If

    If T = True Then Print #2, "Yes" Else Print #2, "No"

    Next i

    Close #2
    Close #1

    End
    End Sub

    回覆刪除
  7. 佑好,
    程式正確,而且,是另闢蹊徑,很好。
    利用replace反復的將已經成對的東西給取消掉。
    再去判斷是不是有剩下的。
    還有兩點,
    一,那些外頭dim的變數,也是個取巧的方式,你的這個程式只有一個sub,並不需要用那些外部的變數。如果有兩個以上的副程式,而且需要在副程式之間保持住變數的內容時,才需要用這樣的外部變數的。
    二,除了用這樣奇怪的方式來解這題之外,也請用正常的判斷的方式來解一下這一題。因為,你用的特別方法,並不適用於正常的題目的,正常的題目中,是還有數字與其它的變數,例如
    (35+(22*4-(22-30)+55*2)*12+9)*22
    用你的方法,並不能理解什麼是堆疊的。

    回覆刪除
  8. 熊掌好,

    今天遇到阿揚學長
    急忙的問他這一題
    才發現不難

    阿不過那種怪怪的方法
    可以只取()[]再進行判斷這樣可以嘛!!?

    Dim Times As Byte
    Dim N As String
    Dim N2(128) As String
    Dim K(64) As String
    Dim T As Byte
    Dim P As Boolean


    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, Times

    For i = 1 To Times
    Input #1, N
    P = True
    T = 1

    For j = 1 To Len(N)
    N2(j) = Mid(N, j, 1)
    Next j

    For j = 1 To Len(N)
    If N2(j) = "(" Then K(T) = "(": T = T + 1: N2(j) = ""
    If N2(j) = "[" Then K(T) = "[": T = T + 1: N2(j) = ""
    If N2(j) = ")" And K(T - 1) = "(" Then T = T - 1: N2(j) = ""
    If N2(j) = "]" And K(T - 1) = "[" Then T = T - 1: N2(j) = ""
    Next j

    For j = 1 To Len(N)
    If N2(j) <> "" Then P = False
    Next j


    If P = True Then Print #2, "Yes" Else Print #2, "No"

    Next i

    Close #2
    Close #1

    End
    End Sub

    回覆刪除
  9. 佑好,
    你這題應該還不正確。
    當If N2(j) = ")" And K(T - 1) = "(" Then T = T - 1: N2(j) = ""
    如果n2(j)=")" 但是,K(T-1)="["的話,你什麼也沒做,就放過它了吧。
    接近了,這樣的方式,的確是像堆疊了。
    再試試。

    回覆刪除
  10. 熊掌好,

    For j = 1 To Len(N)
    If N2(j) <> "" Then P = False
    Next j

    這邊就是判斷是否有沒被取代掉

    在體育組碰一下電腦...

    回覆刪除
  11. Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, t
    For i = 1 To t
    Line Input #1, n
    Call A1(n)
    Next
    Close
    Close
    End
    End Sub

    Sub A1(a)
    Dim check
    For i = 1 To Len(a)
    m = Mid(a, i, 1)
    Select Case m
    Case "(": check = check & "("
    Case "[": check = check & "["
    Case ")": If Right(check, 1) = "(" Then check = Left(check, Len(check) - 1) Else Print #2, "No": Exit Sub
    Case "]": If Right(check, 1) = "[" Then check = Left(check, Len(check) - 1) Else Print #2, "No": Exit Sub
    End Select
    Next
    If Len(check) = 0 Then Print #2, "Yes" Else Print #2, "No"
    End Sub


    4:36
    用堆疊去做的

    回覆刪除