Skip to main content
Fixed issue with trailing brackets
Source Link
Xiaoy312
  • 3.1k
  • 16
  • 18
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.

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;
}

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.

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 !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.

code fix
Source Link
Xiaoy312
  • 3.1k
  • 16
  • 18
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]);

    // validationnon-bracket characters doesn't affect the result,
    var// invalidCharactersso =we expression.ToCharArray()
can filter them out to make the flow .Distinct()simpler
    Func<char, bool> isBracket = .Where(c => !pairedBrackets.ContainsKey(c) &&|| !pairedBrackets.ContainsValue(c));
    if (invalidCharacters.Any())
        throw new ArgumentException("`expression` contains invalid characters: " + string.Join(", ", invalidCharacters));

    // 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;
}

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.

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)
{
    // definition
    var brackets = new[] { "()", "{}", "[]" };
    var pairedBrackets = brackets.ToDictionary(x => x[0], x => x[1]);

    // validation
    var invalidCharacters = expression.ToCharArray()
        .Distinct()
        .Where(c => !pairedBrackets.ContainsKey(c) && !pairedBrackets.ContainsValue(c));
    if (invalidCharacters.Any())
        throw new ArgumentException("`expression` contains invalid characters: " + string.Join(", ", invalidCharacters));

    // implementation
    var stack = new Stack<char>();
    foreach (var c in expression)
    {
        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;
}

EDIT: I skipped the requirements...

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;
}

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.

formatting corrections
Source Link
t3chb0t
  • 44.3k
  • 9
  • 84
  • 190
  • Poor choice of variable name. You picked expression just a little below, that is a good one. Why not use the plural form of it: expressions?

    foreach (var barcketsList in list)

    Poor choice of variable name. You picked expression just a little below, that is a good one. Why not use the plural form of it: expressions?
foreach (var barcketsList in list)
  • barcketsList contains a typo, not a big deal usually. However, you should pay some more attention for an interview.

    barcketsList contains a typo, not a big deal usually. However, you should pay some more attention for an interview.
  • bracket-s + List you really don't want hinting this is an array/collection/list twice.

    foreach (var barcketsList in list) // <- unnecessary white line {

    bracket-s + List you really don't want hinting this is an array/collection/list twice.
foreach (var barcketsList in list)
// <- unnecessary white line
{
  • Don't leave white line just anywhere within a method in your code. They should be used to divide the logical blocks, eg: declaration/initialization vs logic vs return, logic#1 vs logic#2

    string expression = barcketsList; Stack stack = new Stack(); char[] symbols = expression.ToCharArray();

    Don't leave white line just anywhere within a method in your code. They should be used to divide the logical blocks, eg: declaration/initialization vs logic vs return, logic#1 vs logic#2
string expression = barcketsList;
Stack<char> stack = new Stack<char>();
char[] symbols = expression.ToCharArray();
  • A temporary variable expression is not necessary here. In fact, both this and barcketsList is only used once. You can substitute one by the other.

    A temporary variable expression is not necessary here. In fact, both this and barcketsList is only used once. You can substitute one by the other.
  • Use var when you can, it makes the variable names aligned thus making scanning easier. The variable name itself or its right-hand side assignment should give enough clue usually, plus you can always mouse-over with intellisense.

    Use var when you can, it makes the variable names aligned thus making scanning easier. The variable name itself or its right-hand side assignment should give enough clue usually, plus you can always mouse-over with intellisense.
  • Poor choice of variable name. You picked expression just a little below, that is a good one. Why not use the plural form of it: expressions?

    foreach (var barcketsList in list)

  • barcketsList contains a typo, not a big deal usually. However, you should pay some more attention for an interview.

  • bracket-s + List you really don't want hinting this is an array/collection/list twice.

    foreach (var barcketsList in list) // <- unnecessary white line {

  • Don't leave white line just anywhere within a method in your code. They should be used to divide the logical blocks, eg: declaration/initialization vs logic vs return, logic#1 vs logic#2

    string expression = barcketsList; Stack stack = new Stack(); char[] symbols = expression.ToCharArray();

  • A temporary variable expression is not necessary here. In fact, both this and barcketsList is only used once. You can substitute one by the other.

  • Use var when you can, it makes the variable names aligned thus making scanning easier. The variable name itself or its right-hand side assignment should give enough clue usually, plus you can always mouse-over with intellisense.

  • Poor choice of variable name. You picked expression just a little below, that is a good one. Why not use the plural form of it: expressions?
foreach (var barcketsList in list)
  • barcketsList contains a typo, not a big deal usually. However, you should pay some more attention for an interview.
  • bracket-s + List you really don't want hinting this is an array/collection/list twice.
foreach (var barcketsList in list)
// <- unnecessary white line
{
  • Don't leave white line just anywhere within a method in your code. They should be used to divide the logical blocks, eg: declaration/initialization vs logic vs return, logic#1 vs logic#2
string expression = barcketsList;
Stack<char> stack = new Stack<char>();
char[] symbols = expression.ToCharArray();
  • A temporary variable expression is not necessary here. In fact, both this and barcketsList is only used once. You can substitute one by the other.
  • Use var when you can, it makes the variable names aligned thus making scanning easier. The variable name itself or its right-hand side assignment should give enough clue usually, plus you can always mouse-over with intellisense.
Source Link
Xiaoy312
  • 3.1k
  • 16
  • 18
Loading