I am writing a function in Javascript to check if the string argument has balanced brackets.
Balanced brackets:
- A string is considered balanced if it has as many opening brackets of a given type as it has closing brackets of that same type.
- No bracket can be left unmatched. A closing bracket also cannot match a corresponding opening bracket that comes after it.
- Brackets also cannot overlap each other.
The function iterates over the given string and checks each bracket type, (), [], {}, to see if there is a correct pair. The method is to iterate over the string to check for an opening bracket and then if found, iterate over the rest of the string for the corresponding closing bracket, then remove the pair. Each of the code blocks do this with each different bracket type. At the end, if there are any stray closing or opening brackets, it will return false, otherwise it will return true.
After running my code tested on a string of balanced brackets, ({[]}), I've found it works only if I check the brackets in the order they appear in the string. I'm not sure why the order of these blocks affect how it works. Connecting the conditionals with "else if" instead of just "if" does not have any affect.
function hasBalancedBrackets(string) {
var stringArray = string.split('');
for (var i = 0; i < stringArray.length; i ) {
if (stringArray[i] === '(') {
for (var j = i 1; j < stringArray.length; j ) {
if (stringArray[j] === ')') {
stringArray.splice(i, 1);
stringArray.splice(stringArray.indexOf(')'), 1);
break;
}
}
}
if (stringArray[i] === '{') {
for (var l = i 1; l < stringArray.length; l ) {
if (stringArray[l] === '}') {
stringArray.splice(i, 1);
stringArray.splice(stringArray.indexOf('}'), 1);
break;
}
}
}
if (stringArray[i] === '[') {
for (var k = i 1; k < stringArray.length; k ) {
if (stringArray[k] === ']') {
stringArray.splice(i, 1);
stringArray.splice(stringArray.indexOf(']'), 1);
break;
}
}
}
}
console.log('stringArray:', stringArray); // to check that all the bracket pairs have been removed
if (stringArray.indexOf('(') === -1 && stringArray.indexOf('[') === -1 && stringArray.indexOf('{') === -1 && stringArray.indexOf(')') === -1 && stringArray.indexOf(']') === -1 && stringArray.indexOf('}') === -1) {
return true;
} else {
return false;
}
}
// Assertion functions and test suite
function assertEqual(actual, expected, testName) {
if (actual === expected) {
console.log(`Passed [${testName}]`);
} else {
console.log(`FAILED [${testName}] Expected "${expected}", but got "${actual}"`);
}
}
// tests
// input has balanced brackets, part 2
var actual4 = hasBalancedBrackets('({[]})');
assertEqual(actual4, true, 'Returns true when input string has balanced brackets');
Ordering of the code blocks and affect on the function:
- {}, (), [] - fails, does not find the braces {}
- {}, [], () - fails, does not find the braces {}
- [], {}, () - fails, does not find the braces {}
- [], (), {} - fails, does not find the square brackets []
- (), [], {} - fails, does not find the square brackets []
- (), {}, [] - passes
CodePudding user response:
Your outermost for
block increments index i but the code inside removes elements from the array. So if the inner code removes anything from the array, when the outer loop is run again, it skips the new first element.
{}()[]
first run of outer loop removes {} and []
now stringArray is ()
second run of outer loop now starts at index 1, which is ), so it doesn't find the pair.