Trying to solve a case for a set of multiple types of brackets.
class BracketHelper {
// checks if the string contains properly formatted brackets
public static bool ProperBrackets(string s) {
int p = 0;
return ProperBrackets(s.ToCharArray(), ref p);
}
// main method, uses recursion to check if the brackets are properly formatted
private static bool ProperBrackets(char[] arr, ref int ptr, char oppBracket = ' ') {
for(;ptr<arr.Length;ptr++) {
var ch = arr[ptr];
if ( IsOpen(ch)) { // found an open bracket - let's check the inner content
ptr +=1; // start checking from the next position
if (ProperBrackets(arr, ref ptr, OppositeOf(ch)) == false) // inner content is malformed?
return false;
}
if ( IsClose(ch) ) // found a closing bracket
return ch == oppBracket; // is this what we were looking for? If not - then we found a malformity!
}
// we reached the end. are we still searching for the closing bracket?
return oppBracket == ' ';
}
private static char[] OpenBrackets = new char[] { '{', '[', '(' };
private static char[] CloseBrackets = new char[] { '}', ']', ')' };
// check helpers
private static bool IsOpen(char ch) { return OpenBrackets.Contains(ch); }
private static bool IsClose(char ch) { return CloseBrackets.Contains(ch); }
// returns a closing bracket character
private static char OppositeOf(char ch) {
for(var i=0;i<OpenBrackets.Length;i+=1)
if ( ch == OpenBrackets[i] )
return CloseBrackets[i];
throw new Exception($"'{ch}' is not an open bracket");
}
}
Some test cases for LinqPad:
(BracketHelper.ProperBrackets("{}") == true).Dump();
(BracketHelper.ProperBrackets("{[]()}") == true).Dump();
(BracketHelper.ProperBrackets("{[()][{}]{}}") == true).Dump();
(BracketHelper.ProperBrackets("{[}]}") == false).Dump();
(BracketHelper.ProperBrackets("{[{(}])}") == false).Dump();
(BracketHelper.ProperBrackets("{[][][][{(})}]}") == false).Dump();
(BracketHelper.ProperBrackets("{[]}}") == false).Dump();
(BracketHelper.ProperBrackets("{") == false).Dump();
This can be done with the ref argument, so the pointer is a member of a class but in this case the method won't be static and I just wanted to make its usage as convenient as possible.