我正在阅读算法设计手册第二版,这是一个练习题。引用问题
编译器和编译器的常见问题 文本编辑正在决定是否 字符串中的括号是 平衡和适当嵌套。对于 例如,字符串((())())() 包含正确嵌套的对 括号,其中的字符串)()( 也不要。给出一个算法 如果字符串包含,则返回true 适当嵌套和平衡 括号,否则为假。 要获得全额信贷,请确定头寸 如果是第一个违规括号 字符串没有正确嵌套 平衡的。
问题在堆栈,队列和列表类别下。这是我在C#中写的内容。
const char LeftParenthesis = '(';
const char RightParenthesis = ')';
bool AreParenthesesBalanced(string str, out int errorAt)
{
var items = new Stack<int>(str.Length);
errorAt = -1;
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (c == LeftParenthesis)
items.Push(i);
else if (c == RightParenthesis)
{
if (items.Count == 0)
{
errorAt = i + 1;
return false;
}
items.Pop();
}
}
if (items.Count > 0)
{
errorAt = items.Peek() + 1;
return false;
}
return true;
}
这很有效。但我不确定这是解决这个问题的正确方法。欢迎任何更好的想法。
答案 0 :(得分:10)
我认为这是意图,但实际上,如果你只处理括号,你只需要递减和增加一个计数器。如果你正在处理方括号,尖括号,花括号或你想要使用的任何字符配对的配对,你将需要像你一样的堆栈。
你也可以使用一个列表,关闭和打开head元素,但实际上堆栈可能实现为列表 - 至少它是在ocaml中。
答案 1 :(得分:8)
static public bool CheckForBalancedBracketing(string IncomingString)
{
/*******************************************************************
* The easiest way to check for balanced bracketing is to start *
* counting left to right adding one for each opening bracket, '(' *
* and subtracting 1 for every closing bracket, ')'. At the end *
* the sum total should be zero and at no time should the count *
* fall below zero. *
* *
* Implementation: The bracket counting variable is an unsigned *
* integer and we trap an overflow exception. This happens if the *
* unsigned variable ever goes negative. This allows us to abort *
* at the very first imbalance rather than wasting time checking *
* the rest of the characters in the string. *
* *
* At the end all we have to do is check to see if the count *
* is equal to zero for a "balanced" result. *
* *
*******************************************************************/
const char LeftParenthesis = '(';
const char RightParenthesis = ')';
uint BracketCount = 0;
try
{
checked // Turns on overflow checking.
{
for (int Index = 0; Index < IncomingString.Length; Index++)
{
switch (IncomingString[Index])
{
case LeftParenthesis:
BracketCount++;
continue;
case RightParenthesis:
BracketCount--;
continue;
default:
continue;
} // end of switch()
}
}
}
catch (OverflowException)
{
return false;
}
if (BracketCount == 0)
{
return true;
}
return false;
} // end of CheckForBalancedBracketing()
答案 2 :(得分:2)
从输入字符串中删除所有非'('和 - ')'字符。这只会给你一串'('和')'。
如果字符串的长度为奇数,则返回false。
否则,请开始阅读我们的字符串,为每个'('和-1代表')'的“签名”添加+1;如果此签名为负数,则返回false。
返回true。
答案 3 :(得分:2)
这将适用于()
,{}
和[]
的组合。
还检测到以下错误:([)]
,)[]()
和()(
,...
bool isWellFormatted(string line)
{
Stack<char> lastOpen = new Stack<char>();
foreach (var c in line)
{
switch (c)
{
case ')':
if (lastOpen.Count == 0 || lastOpen.Pop() != '(') return false;
break;
case ']':
if (lastOpen.Count == 0 || lastOpen.Pop() != '[' ) return false;
break;
case '}':
if (lastOpen.Count == 0 || lastOpen.Pop() != '{') return false;
break;
case '(': lastOpen.Push(c); break;
case '[': lastOpen.Push(c); break;
case '{': lastOpen.Push(c); break;
}
}
if (lastOpen.Count == 0) return true;
else return false;
}
答案 4 :(得分:1)
using System;
class Solution
{
public int solution(string S)
{
int x1 = 0;
int x2 = 0;
for (int i = 0; i < S.Length; i++)
{
if (S[i] == ')')
if (x1 <= 0) return 0;
else x1--;
else if (S[i] == '(')
x1++;
}
if (x1 == 0)
return 1;
else
return 0;
}
}
答案 5 :(得分:1)
时间顺序O(n)和空间顺序O(1)
public static bool IsBalanced(string input)
{
int count = 0;
for (int i = 0; i < input.Length; i++)
{
if (input[i] == '(') count++;
if (input[i] == ')') count--;
if (count < 0) return false;
}
if (count == 0) return true;
return false;
}
答案 6 :(得分:0)
C#7左右现在也有元组。您不再需要out
参数。
正如许多其他人指出的那样,不需要堆栈,队列或类似内容。
只需一个余额计数器即可。
-- Checks the balance of braces in a string.
-- Error case 1: More closes than open. We can identify the first culprit by index.
-- Error case 2: More opens than closes. We return the length of the String,
-- indicating that there are closed braces missing.
-- Good case: As many opens as closes. We return (True,Nothing)
checkBraces :: String -> (Bool,Maybe Int)
checkBraces [] = (True,Nothing)
checkBraces s =
let (balance,offender) = foldl account (0,-1) $ zip [0..] s in
if balance == 0
then (True,Nothing)
else (False,Just $ if -1 == offender then length s else offender)
where
account :: (Int,Int) -> (Int, Char) -> (Int,Int)
account acc@(_,off) _ | off /= -1 = acc -- Once there was an error we stop looking what happens.
account acc@(b,off) (i,'(') = (b+1,off) -- One more open brace.
account (b,off) (i,')') -- One more closed brace.
| b <= 0 = (b-1,i) -- Ouch. We closed more than we opened!
| otherwise = (b-1,off) -- Okay.
account acc (i,_) = acc -- Some other character (Not in ['(',')'])
testCases =
[ ("",True)
, ("(",False)
, (")",False)
, ("))((",False)
, ("()()",True)
, ("(()))",False)
]
test =
all ((==) True) . fmap testOne $ testCases
where
testOne (tc,expected) =
let (actual,_) = checkBraces tc in
actual == expected
旁注:这里Haskell的语法突出显示需要改进,对吗? :)
答案 7 :(得分:0)
我使它更通用 Java
public static boolean isBalanced(String expression)
{
// pairs at the same index
List<Character> openers = Arrays.asList('{', '(', '[');
List<Character> closers = Arrays.asList('}', ')', ']');
char[] exp = expression.toCharArray();
Stack<Character> stack = new Stack<>();
for(Character character: exp){
if (openers.contains(character))
stack.push(character);
if(closers.contains(character)){
if (stack.empty())
return false;
//matching pair should be at the same index
Character opener = stack.pop();
int openerIndex = openers.indexOf(opener);
int closerIndex = closers.indexOf(character);
if (openerIndex != closerIndex)
return false;
}
}
return stack.empty();
}
答案 8 :(得分:0)
我将使用队列和堆栈来检查开始和结束比赛
var dictionary = new Dictionary<string, string>() {
{ "{", "}" },
{"[", "]" },
{"(",")" }
};
var par = "{()}";
var queue = new Queue();
var stack = new Stack();
bool isBalanced = true;
var size = par.ToCharArray().Length;
if(size % 2 != 0)
{
isBalanced = false;
}
else
{
foreach (var c in par.ToCharArray())
{
stack.Push(c.ToString());
queue.Enqueue(c.ToString());
}
while (stack.Count > size/2 && queue.Count > size/2)
{
var a = (string)queue.Dequeue();
var b = (string)stack.Pop();
if (dictionary.ContainsKey(a) && b != dictionary[a])
{
isBalanced = false;
}
}
}
Console.WriteLine(isBalanced?"balanced!":"Not Balanced");
Console.ReadLine();
例如在第一次迭代中,a ='{'和b ='}',因此您要检查它是否平衡
答案 9 :(得分:0)
这应该有效:
public class Balanced {
public static boolean isbalanced(String input) {
int open = 0;
int close = 0;
for (int i=0; i< input.length();i++) {
switch (input.charAt(i)) {
case '{':
case '(':
case '[':
open++;
break;
case '}':
case ')':
case ']':
close++;
default:
break;
}
}
if (open == close){
return true;
}
else {
return false;
}
}
public static void main(String args[]) {
System.out.println(Balanced.isbalanced("()"));
}
}
答案 10 :(得分:0)
这里是使用System.Linq的C#单行:
expression.Aggregate(0, (state, ch) => state == -1 ? -1 : state + (ch == '(' ? 1 : ch == ')' ? -1 : 0)) == 0
它利用了字符串实际上是IE数量的字符这一事实,因此我们可以在其上运行聚合函数。当我们遇到&#39;(&#39; char并将其减少1&#39;)时,我们将计数器增加1。焦炭。一旦我们达到负值-1,我们就会留在那里表明无效状态。
它没有实现任何早期退出,所以它会比这里介绍的大多数实现慢,但也许有人会发现它很有用:)
答案 11 :(得分:0)
回想@Russell的想法:
public class BalancedBrackets
{
private readonly char[] _leftBrackets = new char[] {'[', '(', '{', '<'};
private readonly char[] _rightBrackets = new char[] {']', ')', '}', '>'};
public bool IsBalanced(string input)
{
int count = 0;
foreach (var character in input.ToCharArray())
{
if (_leftBrackets.Contains(character)) count++;
if (_rightBrackets.Contains(character)) count--;
}
return count == 0;
}
}
答案 12 :(得分:0)
以下是验证括号的简单解决方案:
1.将起始括号和结束括号保持在一个字符串中
2.循环给我们要验证的人,并检查以下逻辑:
a)如果项目在起始括号中,则将其推入堆叠中
b)如果项目在结束括号中,则将其索引(在结束括号中)与堆栈的顶部项目进行比较
index(在起始括号中)。
c)如果索引是相同的POP TOP ITEM OF STACK。否则它的无效字符串。
d)最后一步,检查堆栈是否有项目/ s,表示无效字符串。
string starters = "({[<";
string enders = ")}]>";
Stack stack = new Stack();
foreach(char c in txtValue.Text.Trim())
{
if(starters.Contains(c))
{
stack.Push(c);
}
else if (enders.Contains(c))
{
if (stack.Count > 0)
{
if (enders.IndexOf(c) == starters.IndexOf(Convert.ToChar(stack.Peek())))
{
stack.Pop();
}
else
{
lblResult.Text = "Invaluid string";
}
}
}
}
if(stack.Count == 0)
{
lblResult.Text = "Valid string";
}
else
{
lblResult.Text = "InValid string";
}
答案 13 :(得分:0)
import java.util.Stack;
public class CheckBalancedParenthesis {
public static void main (String args[]){
CheckBalancedParenthesis checker = new CheckBalancedParenthesis();
System.out.println(checker.checkBalancedParenthesis("{}}{}{}{}{}"));
}
public boolean checkBalancedParenthesis(String pattern){
Stack stack = new Stack();
for(int i = 0; i < pattern.length();i++){
char c = pattern.charAt(i);
if(c == '{'){
stack.push(c);
}else if (c == '}'){
if(!stack.isEmpty()){
stack.pop();
} else{
System.out.println("Error at - " + i);
return false;
}
}
}
return stack.isEmpty();
}
}
答案 14 :(得分:0)
Checking balanced parentheses
package parancheck;
import java.util.EmptyStackException;
import java.util.Stack;
public class ParnCheck
{
public static void main(String args[])
{
int pu = 0;
int po = 0;
String str = "()())";
System.out.println(str);
Stack st = new Stack();
for(int i=0; i<str.length();i++)
{
if(str.charAt(i)=='(')
{
doPush(st, str.charAt(i));
pu++;
}
else
{
try
{
doPop(st);
}
catch(EmptyStackException e)
{
System.out.println("");
}
po++;
}
}
if(pu == po)
{
System.out.println("Correct");
}
else
{
System.out.println("Wrong");
}
}
static void doPush(Stack st,char ch)
{
st.push(ch);
}
static void doPop(Stack st)
{
char c = (char)st.pop();
}
}
答案 15 :(得分:0)
int i;
int len;
char popped;
stack<char> st;
string a = "({<<";
len = a.length();
for(i=0;i<len;i++)
{
if(a[i] == '<' || a[i] == '(' || a[i] == '[' || a[i] == '{')
{
st.push(a[i]);
continue;
}
if(a[i] == '>' || a[i] == ')' || a[i] == ']' || a[i] == '}')
{
if(st.empty())
{
cout << "stack is empty, when popped , not balanced" << endl;
return 0;
}
else
{
popped = st.top();
st.pop();
if (!((a[i] == '>' && popped == '<') || (a[i] == ')' && popped == '(') || (a[i] == '}' && popped == '{') || (a[i] == '>' && popped == '<'))) //ok
{
cout << "not balanced on character" + std::string(1,a[i]) << endl;
return 0;
}
}
}
}
if(st.empty())
{
cout << "balanced" << endl;
}
else
{
cout << "not balanced stack not empty" << endl;
}
答案 16 :(得分:0)
为什么有返回值和out参数提供相同的信息?
你可以返回一个int:-1 = balanced,否则就是错误的索引。
答案 17 :(得分:0)
正如TheVillageIdiot所说,没关系。你也可以递归地实现它,这可能更优雅,也可能不是。最后,您可能希望要求匹配的括号中包含有效的内容,以便允许“(a)”但不允许“()”。