Skip to main content
edited body
Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96
func isBalanced(sequence: [Character]) -> Bool {
    var stack = [Bracket]()
    for elemchar in sequence {
        if let bracket = Bracket(rawValue: elemchar) {
            if let open = bracket.matchingOpen {
                // `bracket` is a closing bracket and `open` the corresponding opening bracket:
                guard let last = stack.last where last == open  else {
                    return false
                }
                stack.removeLast()
            } else {
                // `bracket` is an opening bracket:
                stack.append(bracket)
            }
        } else {
            fatalError("unknown bracket found")
        }
    }
    return stack.isEmpty
}
func isBalanced(sequence: [Character]) -> Bool {
    var stack = [Bracket]()
    for elem in sequence {
        if let bracket = Bracket(rawValue: elem) {
            if let open = bracket.matchingOpen {
                // `bracket` is a closing bracket and `open` the corresponding opening bracket:
                guard let last = stack.last where last == open  else {
                    return false
                }
                stack.removeLast()
            } else {
                // `bracket` is an opening bracket:
                stack.append(bracket)
            }
        } else {
            fatalError("unknown bracket found")
        }
    }
    return stack.isEmpty
}
func isBalanced(sequence: [Character]) -> Bool {
    var stack = [Bracket]()
    for char in sequence {
        if let bracket = Bracket(rawValue: char) {
            if let open = bracket.matchingOpen {
                // `bracket` is a closing bracket and `open` the corresponding opening bracket:
                guard let last = stack.last where last == open  else {
                    return false
                }
                stack.removeLast()
            } else {
                // `bracket` is an opening bracket:
                stack.append(bracket)
            }
        } else {
            fatalError("unknown bracket found")
        }
    }
    return stack.isEmpty
}
edited body
Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96

readStrings() is better named readCharacters() because that is what isit does. I prefer Array(...) instead of .map { $0 } to convert a sequence into an array, but that is a matter of taste:

readStrings() is better named readCharacters() because that is what is does. I prefer Array(...) instead of .map { $0 } to convert a sequence into an array, but that is a matter of taste:

readStrings() is better named readCharacters() because that is what it does. I prefer Array(...) instead of .map { $0 } to convert a sequence into an array, but that is a matter of taste:

added 364 characters in body
Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96
enum Bracket: Character {
    case Left = "("
    case Right = ")"
    case LeftCurly = "{"
    case RightCurly = "}"
    case LeftSquare = "["
    case RightSquare = "]"
    
    /// For a closing bracket, the corresponding opening bracket is returned.
    /// For an opening bracket, `nil` is returned.
    var matchingOpen: Bracket? {
        switch self {
        case .Right:        return .Left
        case .RightCurly:   return .LeftCurly
        case .RightSquare:  return .LeftSquare
        default:            return nil
        }
    }
}

And nowNow the isBalanced() function becomes even more readabledoes not use any explicit bracket values anymore:

func isBalanced(sequence: [Character]) -> Bool {
    var stack = [Bracket]()
    for elem in sequence {
        if let bracket = Bracket(rawValue: elem) {
            switchif let open = bracket.matchingOpen {
            case .Left, .LeftCurly, .LeftSquare // `bracket` is a closing bracket and `open` the corresponding opening bracket:
                guard let last = stack.append(bracket)
last where last == open  else {
     case .Right, .RightCurly, .RightSquare:
            return false
   if let last = stack.last where last == bracket.matchingOpen {
    }
                stack.removeLast()
                } else {
                // `bracket` is an returnopening falsebracket:
                }stack.append(bracket)
            }
        } else {
            fatalError("unknown bracket found")
        }
    }
    return stack.isEmpty
}

If you decide to add another type of brackets later (e.g. «») then only the enumeration needs to be extended, but not the isBalanced() function.

enum Bracket: Character {
    case Left = "("
    case Right = ")"
    case LeftCurly = "{"
    case RightCurly = "}"
    case LeftSquare = "["
    case RightSquare = "]"
    
    var matchingOpen: Bracket? {
        switch self {
        case .Right:        return .Left
        case .RightCurly:   return .LeftCurly
        case .RightSquare:  return .LeftSquare
        default:            return nil
        }
    }
}

And now the isBalanced() function becomes even more readable:

func isBalanced(sequence: [Character]) -> Bool {
    var stack = [Bracket]()
    for elem in sequence {
        if let bracket = Bracket(rawValue: elem) {
            switch bracket {
            case .Left, .LeftCurly, .LeftSquare:
                stack.append(bracket)
            case .Right, .RightCurly, .RightSquare:
                if let last = stack.last where last == bracket.matchingOpen {
                    stack.removeLast()
                } else {
                    return false
                }
            }
        } else {
            fatalError("unknown bracket found")
        }
    }
    return stack.isEmpty
}
enum Bracket: Character {
    case Left = "("
    case Right = ")"
    case LeftCurly = "{"
    case RightCurly = "}"
    case LeftSquare = "["
    case RightSquare = "]"
    
    /// For a closing bracket, the corresponding opening bracket is returned.
    /// For an opening bracket, `nil` is returned.
    var matchingOpen: Bracket? {
        switch self {
        case .Right:        return .Left
        case .RightCurly:   return .LeftCurly
        case .RightSquare:  return .LeftSquare
        default:            return nil
        }
    }
}

Now the isBalanced() function does not use any explicit bracket values anymore:

func isBalanced(sequence: [Character]) -> Bool {
    var stack = [Bracket]()
    for elem in sequence {
        if let bracket = Bracket(rawValue: elem) {
            if let open = bracket.matchingOpen {
                // `bracket` is a closing bracket and `open` the corresponding opening bracket:
                guard let last = stack.last where last == open  else {
                    return false
                }
                stack.removeLast()
            } else {
                // `bracket` is an opening bracket:
                stack.append(bracket)
            }
        } else {
            fatalError("unknown bracket found")
        }
    }
    return stack.isEmpty
}

If you decide to add another type of brackets later (e.g. «») then only the enumeration needs to be extended, but not the isBalanced() function.

Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96
Loading