给定一个仅包含 ‘(‘、‘)‘、‘{‘、‘}‘、‘[‘、‘]‘的字符串,确定输入的字符串是否合法。
e.g. "()"、"()[]{}"、"[()]([]({}))" 是合法的,而"(]"、"([)]" 是不合法的。
使用栈stack
C++实现:
1 bool isValid(string s) { 2 stack<char> stack; 3 for (char &c : s) { 4 if (c == ‘(‘) 5 stack.push(‘)‘); 6 else if (c == ‘{‘) 7 stack.push(‘}‘); 8 else if (c == ‘[‘) 9 stack.push(‘]‘); 10 else if (stack.empty() || (stack.top() != c)) 11 return false; 12 else 13 stack.pop(); 14 } 15 return stack.empty(); 16 }
对应的Java实现:
1 public boolean isValid(String s) { 2 Stack<Character> stack = new Stack<Character>(); 3 for (char c : s.toCharArray()) { 4 if (c == ‘(‘) 5 stack.push(‘)‘); 6 else if (c == ‘{‘) 7 stack.push(‘}‘); 8 else if (c == ‘[‘) 9 stack.push(‘]‘); 10 else if (stack.isEmpty() || stack.pop() != c) 11 return false; 12 } 13 return stack.isEmpty(); 14 }
C++中的stack,其中有两个方法:
- pop(),返回void,不返回类型<T>。
- top(),返回栈顶的引用。
pop()不返回栈顶元素的原因是:
- 异常安全原因
如果要实现,代码如下,
template<class T> T stack<T>::pop() { if( vused_ == 0) { throw "pop from empty stack"; } else { return v_[--vused_ - 1]; } }
试图返回 v_[--vused_ - 1] 的时候,会调用 T 的拷贝构造函数,如果调用的时候发生异常,并没有返回正确的值,但是栈顶元素已经弹出了,这时就丢失了栈顶数据。
如果这样写,
template<class T> T stack<T>::pop() { if( vused_ == 0) { throw "pop from empty stack"; } else { T result = v_[vused_ - 1]; --vused_; return result; } }
先建立一个栈顶元素的副本,如果拷贝构造函数出现异常,那么 --vused_ 不会执行,就不会丢失数据。但假如 --vused_ 和 return result 之间发生异常,依然会出问题。也就是说,如果想同时做 pop() 和 top() ,一定要保证 --vused_ 和 return result 是一个执行事务。
- 效率原因
因为栈顶元素在栈中已经不存在,必须在按引用返回之前现将其存储到某个地方。如果选用动态内存,除非动态内存最终被删除,否则将导致内存泄露。
如果调用拷贝构造函数,对象按值传递的方式从函数返回,效率低下。
时间: 2024-12-21 06:19:58