public void CheckAllExpressionsAreBalanced()
{
var expressions = new List<string> { "({[]})", "][(]}})(" };
foreach (var expression in expressions)
{
//Console.WriteLine("Expression `{0}` {1} balanced.",
// expression,
// IsBalanced(expression) ? "is" : "is not");
Console.WriteLine(IsBalanced(expression) ? "YES" : "NO");
}
}
// Define other methods and classes here
public bool IsBalanced(string expression)
{
// argument validation
if (expression == null)
throw new ArgumentNullException(nameof(expression));
// definition
var brackets = new[] { "()", "{}", "[]" };
var pairedBrackets = brackets.ToDictionary(x => x[0], x => x[1]);
// non-bracket characters doesn't affect the result,
// so we can filter them out to make the flow simpler
Func<char, bool> isBracket = c => pairedBrackets.ContainsKey(c) || pairedBrackets.ContainsValue(c);
// implementation
var stack = new Stack<char>();
foreach (var c in expression.Where(isBracket))
{
var isOpening = pairedBrackets.ContainsKey(c);
var pair = isOpening
? pairedBrackets[c]
: pairedBrackets.First(x => x.Value == c).Key;
if (isOpening)
{
stack.Push(c);
}
else
{
// closing bracket with empty stack
if (!stack.Any())
return false;
// closing bracket doesnt match last opening bracket
if (stack.Peek() != pair)
return false;
// matched
stack.Pop();
}
}
return true;!stack.Any();
}
EDIT: I skipped the requirements...
EDIT2: Updated IsBalanced
to accept non-bracket characters input. As @HenrikHansen points out, it doesn't make sense to throw an exception.
EDIT3: Fixed issue with trailing brackets.