QT - Wrong numbering in the case of two or more overlapping numberings - qtextedit

I need to use two nested lists.
The first is a numeric list and the second is an alphabetical one.
When the second is over and I go to the first list, the numbers are counted from the beginning.
I tried to create a new list createList() but it didn't work
else if (object == ui->textEdit_left && event->type() == QEvent::KeyPress)
{
QTextCursor cursor = ui->textEdit_left->textCursor();
QTextListFormat::Style currentStyle = cursor.currentList()->format().style();
QTextBlockFormat format = cursor.blockFormat();
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
QTextListFormat::Style newStyle = createNewStyle(currentStyle, keyEvent->key());
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter)
{
format.setIndent(format.indent() - 1);
cursor.setBlockFormat(format);
cursor.createList(newStyle);
return true;
}
else if (keyEvent->key() == Qt::Key_Tab)
{
format.setIndent(format.indent() + 1);
cursor.setBlockFormat(format);
cursor.createList(newStyle);
return true;
}
else
{
return false;
}
}
return false;

Related

Troubles with for loop and Range

var colRange = getRange("Sheet1!G2:G200")
logger.log(colRange)
logger.log(colRange[0])
for(var i = 0; i < colRange.length; i++) {
if(activeCell.getColumn() == 7 && activeCell.getRow() == colRange[i] && ss.getActiveSheet().getName()=="Sheet1") {
newValue=e.value;
oldValue=e.oldValue;
if(!e.value) {
activeCell.setValue("");
}
else {
if (!e.oldValue) {
activeCell.setValue(newValue);
}
else {
activeCell.setValue(oldValue+', '+newValue);
}
}
}
}
Could anybody help with the for loop. Need it to check every row of column G to allow multiple drop down selections. If I replace colRange[i] with the specific row it does work. I assume I need to loop through each range G2, G3, G4, etc
Please explain what you are trying to
It's hard to figure out what you are trying to accomplish with you code but this is my best guess
function onEdit(e) {
const sh = e.range.getSheet();
if (e.range.columnStart == 7 && e.range.rowStart > 1 && sh.getName() == "Sheet1") {
if (!e.value) {
e.range.setValue("");//doesn't make sense it's already null
} else if (!e.oldValue) {
e.range.setValue(e.value);
} else {
e.range.setValue(oldValue + ', ' + newValue);
}
}
}

Algorith that determinates frequency of string combinations MQL4

I have csv file like this:
1392249600;EUR;CHF;USD;JPY;GBP
1392163200;GBP;JPY;USD;CHF;EUR
1392076800;GBP;CHF;EUR;JPY;USD
1391990400;JPY;USD;EUR;CHF;GBP
1391904000;GBP;EUR;CHF;USD;JPY
1391731200;GBP;EUR;CHF;JPY;USD
1391644800;EUR;CHF;USD;JPY;GBP
1391558400;JPY;USD;EUR;CHF;GBP
There can be over 15 000 rows in that file. I am trying to write code that could do such thing:
1.Takes first row saves it as parent. Then takes next 3 days as that childs.
2.Counts how often and which combination off childs with that parent are inside this file.
3.It creates something like summary for that so I could read todays combination and script shows the only the most frequent child combinations for next 3 days.
I don't have mathematical thinking so I have big problems to find solution myself.
What I think first I need script that generates all posible combinations of these colums made of EUR,CHF,USD,JPY,GBP so there is posible 5*4*3*2*1 = 120 combinations. Because they cant repeat in single row.
It will be like this.
First parent will be combination from first row like this: EUR;CHF;USD;JPY;GBP
Then 3 childs would be
GBP;JPY;USD;CHF;EUR
GBP;CHF;EUR;JPY;USD
JPY;USD;EUR;CHF;GBP
It saves this combination off parent and child elements.
Then again it starts from begining of the file, but moves one row below(like iteration +1).
then next all childs would be
GBP;CHF;EUR;JPY;USD
JPY;USD;EUR;CHF;GBP
GBP;EUR;CHF;USD;JPY
And again it saves these combinations for counting and make some frequency results.
And this cycle repeats for all rows on csv file.
Is there maybe some tips I should consider how to create this type of programm ?
Any tip would be great !
Thank You Very Much!
BB
Can you please clarify whether first value in a row in your file is date/time? 1392249600;EUR;CHF;USD;JPY;GBP
If yes, are you expecting that there will total 4 rows with the same date/time?
Or else you just need to go sequentially and use Line-1 as parent and then Line-2, Line-3, Line-4 as child and goes on... so that Line-5 becomes parent again?
To check whether country code is equivalent or not, you can use below kind of code. I am not 100% sure about your requirement, please correct me if you think this is not what you are looking for and I will try to answer you in other way:
package com.collections;
public class CountryCodeComparison {
public static void main(String[] args) {
//Read every row and sequentially insert value in CountryCode object.
//For ex. your row is: 1392163200;GBP;JPY;USD;CHF;EUR
String s1 = "1392163200;GBP;JPY;USD;CHF;EUR";
String [] array1 = s1.split(";");
CountryCode cc1 = new CountryCode(array1[1], array1[2], array1[1], array1[4], array1[5]);
//For ex. your row is: 1392076800;GBP;CHF;EUR;JPY;USD
String s2 = "1392076800;GBP;CHF;EUR;JPY;USD";
String [] array2 = s2.split(";");
CountryCode cc2 = new CountryCode(array2[1], array2[2], array2[1], array2[4], array2[5]);
if(cc1.equals(cc2)) {
System.out.println("Both CountryCode objects are equal.");
} else {
System.out.println("Both CountryCode objects are NOT equal.");
}
}
}
class CountryCode {
private String countryCode1;
private String countryCode2;
private String countryCode3;
private String countryCode4;
private String countryCode5;
public CountryCode(String countryCode1, String countryCode2,
String countryCode3, String countryCode4, String countryCode5) {
this.countryCode1 = countryCode1;
this.countryCode2 = countryCode2;
this.countryCode3 = countryCode3;
this.countryCode4 = countryCode4;
this.countryCode5 = countryCode5;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((countryCode1 == null) ? 0 : countryCode1.hashCode());
result = prime * result
+ ((countryCode2 == null) ? 0 : countryCode2.hashCode());
result = prime * result
+ ((countryCode3 == null) ? 0 : countryCode3.hashCode());
result = prime * result
+ ((countryCode4 == null) ? 0 : countryCode4.hashCode());
result = prime * result
+ ((countryCode5 == null) ? 0 : countryCode5.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CountryCode other = (CountryCode) obj;
if (countryCode1 == null) {
if (other.countryCode1 != null)
return false;
} else if (!countryCode1.equals(other.countryCode1))
return false;
if (countryCode2 == null) {
if (other.countryCode2 != null)
return false;
} else if (!countryCode2.equals(other.countryCode2))
return false;
if (countryCode3 == null) {
if (other.countryCode3 != null)
return false;
} else if (!countryCode3.equals(other.countryCode3))
return false;
if (countryCode4 == null) {
if (other.countryCode4 != null)
return false;
} else if (!countryCode4.equals(other.countryCode4))
return false;
if (countryCode5 == null) {
if (other.countryCode5 != null)
return false;
} else if (!countryCode5.equals(other.countryCode5))
return false;
return true;
}
}

Column sort reset of ascending/descending on 3rd click

Suppose we've a grid with sortable columns.
If a user clicks on a column, it gets sorted by 'asc', then if a user clicks the column header again, it gets sorted by 'desc', now I want similar functionality when a user clicks the column third time, the sorting is removed, i.e. returned to previous style, the css is changed back to normal/non-italic etc?
Today I was trying to achieve same thing. I've skimmed through SlickGrid code but didn't find any 'Reset' function. So, I've tweaked the slick.grid.js v2.2 a little bit.
Basically you just need to add a new array - 'latestSortColumns' which will store sort columns state (deep copy of internal SlickGrid sortColumns array).
var latestSortColumns = [];
Optionally add new setting to opt-in for sort reset.
var defaults = {
(...),
autoResetColumnSort: false
};
Change setupColumnSort to reset sort after third click on column's header.
function setupColumnSort() {
$headers.click(function (e) {
// temporary workaround for a bug in jQuery 1.7.1 (http://bugs.jquery.com/ticket/11328)
e.metaKey = e.metaKey || e.ctrlKey;
if ($(e.target).hasClass("slick-resizable-handle")) {
return;
}
var $col = $(e.target).closest(".slick-header-column");
if (!$col.length) {
return;
}
var column = $col.data("column");
if (column.sortable) {
if (!getEditorLock().commitCurrentEdit()) {
return;
}
var sortOpts = null;
var i = 0;
for (; i < sortColumns.length; i++) {
if (sortColumns[i].columnId == column.id) {
sortOpts = sortColumns[i];
sortOpts.sortAsc = !sortOpts.sortAsc;
break;
}
}
**if ((e.metaKey || (options.autoResetColumnSort && latestSortColumns[i] != null && latestSortColumns[i].sortAsc === !column.defaultSortAsc)) && options.multiColumnSort) {**
if (sortOpts) {
sortColumns.splice(i, 1);
**latestSortColumns.splice(i, 1);**
}
}
else {
if ((!e.shiftKey && !e.metaKey) || !options.multiColumnSort) {
sortColumns = [];
}
if (!sortOpts) {
sortOpts = { columnId: column.id, sortAsc: column.defaultSortAsc };
sortColumns.push(sortOpts);
} else if (sortColumns.length == 0) {
sortColumns.push(sortOpts);
}
}
setSortColumns(sortColumns);
if (!options.multiColumnSort) {
trigger(self.onSort, {
multiColumnSort: false,
sortCol: column,
sortAsc: sortOpts.sortAsc}, e);
} else {
trigger(self.onSort, {
multiColumnSort: true,
sortCols: $.map(sortColumns, function(col) {
return {sortCol: columns[getColumnIndex(col.columnId)], sortAsc: col.sortAsc };
})}, e);
}
}
});
}
Store new state after every sort change in latestSortColumns:
function setSortColumns(cols) {
sortColumns = cols;
var headerColumnEls = $headers.children();
headerColumnEls
.removeClass("slick-header-column-sorted")
.find(".slick-sort-indicator")
.removeClass("slick-sort-indicator-asc slick-sort-indicator-desc");
$.each(sortColumns, function(i, col) {
if (col.sortAsc == null) {
col.sortAsc = true;
}
var columnIndex = getColumnIndex(col.columnId);
if (columnIndex != null) {
headerColumnEls.eq(columnIndex)
.addClass("slick-header-column-sorted")
.find(".slick-sort-indicator")
.addClass(col.sortAsc ? "slick-sort-indicator-asc" : "slick-sort-indicator-desc");
}
});
**for (var i = 0; i < sortColumns.length; i++)
latestSortColumns[i] = { columnId: sortColumns[i].columnId, sortAsc: sortColumns[i].sortAsc };**
}
That's all, should work now.
This is a function I call to reset all columns back to their original order.
It requires one of columns to be set up as not sortable.
In the example below I use the first column of the table, columns[0], which has the field id "locus".
function removeSorting() {
columns[0].sortable = true;
$('.slick-header-columns').children().eq(0).trigger('click');
columns[0].sortable = false;
// clear other sort columns
grid.setSortColumns( new Array() );
}
Then in the typical dataView.sort() function you make an exception for this column:
grid.onSort.subscribe(function(e,args) {
var cols = args.sortCols;
dataView.sort(function (dataRow1, dataRow2) {
for( var i = 0; i < cols.length; i++ ) {
var field = cols[i].sortCol.field;
// reset sorting to original indexing
if( field === 'locus' ) {
return (dataRow1.id > dataRow2.id) ? 1 : -1;
}
var value1 = dataRow1[field];
var value2 = dataRow2[field];
if( value1 == value2 ) continue;
var sign = cols[i].sortAsc ? 1 : -1;
return (value1 > value2) ? sign : -sign;
}
return 0;
});
});
Will the table always be sorted in some order on some column?
If not then you'll have to store a lot of state the first time a column is clicked just in case you want to restore it after a third click.

Count the number of "holes" in a bitmap

Consider a MxN bitmap where the cells are 0 or 1. '1' means filled and '0' means empty.
Find the number of 'holes' in the bitmap, where a hole is a contiguous region of empty cells.
For example, this has two holes:
11111
10101
10101
11111
... and this has only one:
11111
10001
10101
11111
What is the fastest way, when M and N are both between 1 and 8?
Clarification: diagonals are not considered contiguous, only side-adjacency matters.
Note: I am looking for something that takes advantage of the data format. I know how to transform this into a graph and [BD]FS it but that seems overkill.
You need to do connected component labeling on your image. You can use the Two-pass algorithm described in the Wikipedia article I linked above. Given the small size of your problem, the One-pass algorithm may suffice.
You could also use BFS/DFS but I'd recommend the above algorithms.
This seems like a nice use of the disjoint-set data structure.
Convert the bitmap to a 2d array
loop through each element
if the current element is a 0, merge it with the set of one its 'previous' empty neighbors (already visited)
if it has no empty neighbors, add it to its own set
then just count the number of sets
There may be advantages gained by using table lookups and bitwise operations.
For example whole line of 8 pixels may be looked up in 256 element table, so number of holes in a field 1xN is got by single lookup. Then there may be some lookup table of 256xK elements, where K is number of hole configurations in previous line, contatining number of complete holes and next hole configuration. That's just an idea.
I wrote an article describe the answer on Medium https://medium.com/#ahmed.wael888/bitmap-holes-count-using-typescript-javascript-387b51dd754a
but here is the code, the logic isn't complicated and you can understand it without reading the article.
export class CountBitMapHoles {
bitMapArr: number[][];
holesArr: Hole[] = [];
maxRows: number;
maxCols: number;
constructor(bitMapArr: string[] | number[][]) {
if (typeof bitMapArr[0] == 'string') {
this.bitMapArr = (bitMapArr as string[]).map(
(word: string): number[] => word.split('').map((bit: string): number => +bit))
} else {
this.bitMapArr = bitMapArr as number[][]
}
this.maxRows = this.bitMapArr.length;
this.maxCols = this.bitMapArr[0].length;
}
moveToDirection(direction: Direction, currentPosition: number[]) {
switch (direction) {
case Direction.up:
return [currentPosition[0] - 1, currentPosition[1]]
case Direction.down:
return [currentPosition[0] + 1, currentPosition[1]]
case Direction.right:
return [currentPosition[0], currentPosition[1] + 1]
case Direction.left:
return [currentPosition[0], currentPosition[1] - 1]
}
}
reverseDirection(direction: Direction) {
switch (direction) {
case Direction.up:
return Direction.down;
case Direction.down:
return Direction.up
case Direction.right:
return Direction.left
case Direction.left:
return Direction.right
}
}
findNeighbor(parentDir: Direction, currentPosition: number[]) {
let directions: Direction[] = []
if (parentDir === Direction.root) {
directions = this.returnAvailableDirections(currentPosition);
} else {
this.holesArr[this.holesArr.length - 1].positions.push(currentPosition)
directions = this.returnAvailableDirections(currentPosition).filter((direction) => direction != parentDir);
}
directions.forEach((direction) => {
const childPosition = this.moveToDirection(direction, currentPosition)
if (this.bitMapArr[childPosition[0]][childPosition[1]] === 0 && !this.checkIfCurrentPositionExist(childPosition)) {
this.findNeighbor(this.reverseDirection(direction), childPosition)
}
});
return
}
returnAvailableDirections(currentPosition: number[]): Direction[] {
if (currentPosition[0] == 0 && currentPosition[1] == 0) {
return [Direction.right, Direction.down]
} else if (currentPosition[0] == 0 && currentPosition[1] == this.maxCols - 1) {
return [Direction.down, Direction.left]
} else if (currentPosition[0] == this.maxRows - 1 && currentPosition[1] == this.maxCols - 1) {
return [Direction.left, Direction.up]
} else if (currentPosition[0] == this.maxRows - 1 && currentPosition[1] == 0) {
return [Direction.up, Direction.right]
} else if (currentPosition[1] == this.maxCols - 1) {
return [Direction.down, Direction.left, Direction.up]
} else if (currentPosition[0] == this.maxRows - 1) {
return [Direction.left, Direction.up, Direction.right]
} else if (currentPosition[1] == 0) {
return [Direction.up, Direction.right, Direction.down]
} else if (currentPosition[0] == 0) {
return [Direction.right, Direction.down, Direction.left]
} else {
return [Direction.right, Direction.down, Direction.left, Direction.up]
}
}
checkIfCurrentPositionExist(currentPosition: number[]): boolean {
let found = false;
return this.holesArr.some((hole) => {
const foundPosition = hole.positions.find(
(position) => (position[0] == currentPosition[0] && position[1] == currentPosition[1]));
if (foundPosition) {
found = true;
}
return found;
})
}
exec() {
this.bitMapArr.forEach((row, rowIndex) => {
row.forEach((bit, colIndex) => {
if (bit === 0) {
const currentPosition = [rowIndex, colIndex];
if (!this.checkIfCurrentPositionExist(currentPosition)) {
this.holesArr.push({
holeNumber: this.holesArr.length + 1,
positions: [currentPosition]
});
this.findNeighbor(Direction.root, currentPosition);
}
}
});
});
console.log(this.holesArr.length)
this.holesArr.forEach(hole => {
console.log(hole.positions)
});
return this.holesArr.length
}
}
enum Direction {
up = 'up',
down = 'down',
right = 'right',
left = 'left',
root = 'root'
}
interface Hole {
holeNumber: number;
positions: number[][]
}
main.ts file
import {CountBitMapHoles} from './bitmap-holes'
const line = ['1010111', '1001011', '0001101', '1111001', '0101011']
function main() {
const countBitMapHoles = new CountBitMapHoles(line)
countBitMapHoles.exec()
}
main()
function BitmapHoles(strArr) {
let returnArry = [];
let indexOfZ = [];
let subarr;
for(let i=0 ; i < strArr.length; i++){
subarr = strArr[i].split("");
let index = [];
for(let y=0 ; y < subarr.length; y++){
if(subarr[y] == 0)
index.push(y);
if(y == subarr.length-1)
indexOfZ.push(index);
}
}
for(let i=0 ; i < indexOfZ.length; i++){
for(let j=0; j<indexOfZ[i].length ; j++){
if(indexOfZ[i+1] && (indexOfZ[i][j]==indexOfZ[i+1][j] || indexOfZ[i+1].indexOf(indexOfZ[i][j])))
returnArry.indexOf(strArr[i]) < 0 ? returnArry.push(strArr[i]): false;
if(Math.abs(indexOfZ[i][j]-indexOfZ[i][j+1])==1)
returnArry.indexOf(strArr[i]) < 0 ? returnArry.push(strArr[i]): false;
}
}
return returnArry.length;
}
// keep this function call here
console.log(BitmapHoles(readline()));
function findHoles(map) {
let hole = 0;
const isHole = (i, j) => map[i] && map[i][j] === 0;
for (let i = 0; i < map.length; i++) {
for (let j = 0; j < map[i].length; j++) {
if (isHole(i, j)) {
markHole(i, j);
hole++;
}
}
}
function markHole(i, j) {
if (isHole(i, j)) {
map[i][j] = 2;
markHole(i, j - 1);
markHole(i, j + 1);
markHole(i + 1, j);
markHole(i - 1, j);
}
}
return hole;
}

Basic Recursion, Check Balanced Parenthesis

I've written software in the past that uses a stack to check for balanced equations, but now I'm asked to write a similar algorithm recursively to check for properly nested brackets and parenthesis.
Good examples: () [] ()
([]()[])
Bad examples: ( (] ([)]
Suppose my function is called: isBalanced.
Should each pass evaluate a smaller substring (until reaching a base case of 2 left)? Or, should I always evaluate the full string and move indices inward?
First, to your original question, just be aware that if you're working with very long strings, you don't want to be making exact copies minus a single letter each time you make a function call. So you should favor using indexes or verify that your language of choice isn't making copies behind the scenes.
Second, I have an issue with all the answers here that are using a stack data structure. I think the point of your assignment is for you to understand that with recursion your function calls create a stack. You don't need to use a stack data structure to hold your parentheses because each recursive call is a new entry on an implicit stack.
I'll demonstrate with a C program that matches ( and ). Adding the other types like [ and ] is an exercise for the reader. All I maintain in the function is my position in the string (passed as a pointer) because the recursion is my stack.
/* Search a string for matching parentheses. If the parentheses match, returns a
* pointer that addresses the nul terminator at the end of the string. If they
* don't match, the pointer addresses the first character that doesn't match.
*/
const char *match(const char *str)
{
if( *str == '\0' || *str == ')' ) { return str; }
if( *str == '(' )
{
const char *closer = match(++str);
if( *closer == ')' )
{
return match(++closer);
}
return str - 1;
}
return match(++str);
}
Tested with this code:
const char *test[] = {
"()", "(", ")", "", "(()))", "(((())))", "()()(()())",
"(() ( hi))) (())()(((( ))))", "abcd"
};
for( index = 0; index < sizeof(test) / sizeof(test[0]); ++index ) {
const char *result = match(test[index]);
printf("%s:\t", test[index]);
*result == '\0' ? printf("Good!\n") :
printf("Bad # char %d\n", result - test[index] + 1);
}
Output:
(): Good!
(: Bad # char 1
): Bad # char 1
: Good!
(())): Bad # char 5
(((()))): Good!
()()(()()): Good!
(() ( hi))) (())()(((( )))): Bad # char 11
abcd: Good!
There are many ways to do this, but the simplest algorithm is to simply process forward left to right, passing the stack as a parameter
FUNCTION isBalanced(String input, String stack) : boolean
IF isEmpty(input)
RETURN isEmpty(stack)
ELSE IF isOpen(firstChar(input))
RETURN isBalanced(allButFirst(input), stack + firstChar(input))
ELSE IF isClose(firstChar(input))
RETURN NOT isEmpty(stack) AND isMatching(firstChar(input), lastChar(stack))
AND isBalanced(allButFirst(input), allButLast(stack))
ELSE
ERROR "Invalid character"
Here it is implemented in Java. Note that I've switched it now so that the stack pushes in front instead of at the back of the string, for convenience. I've also modified it so that it just skips non-parenthesis symbols instead of reporting it as an error.
static String open = "([<{";
static String close = ")]>}";
static boolean isOpen(char ch) {
return open.indexOf(ch) != -1;
}
static boolean isClose(char ch) {
return close.indexOf(ch) != -1;
}
static boolean isMatching(char chOpen, char chClose) {
return open.indexOf(chOpen) == close.indexOf(chClose);
}
static boolean isBalanced(String input, String stack) {
return
input.isEmpty() ?
stack.isEmpty()
: isOpen(input.charAt(0)) ?
isBalanced(input.substring(1), input.charAt(0) + stack)
: isClose(input.charAt(0)) ?
!stack.isEmpty() && isMatching(stack.charAt(0), input.charAt(0))
&& isBalanced(input.substring(1), stack.substring(1))
: isBalanced(input.substring(1), stack);
}
Test harness:
String[] tests = {
"()[]<>{}",
"(<",
"]}",
"()<",
"(][)",
"{(X)[XY]}",
};
for (String s : tests) {
System.out.println(s + " = " + isBalanced(s, ""));
}
Output:
()[]<>{} = true
(< = false
]} = false
()< = false
(][) = false
{(X)[XY]} = true
The idea is to keep a list of the opened brackets, and if you find a closing brackt, check if it closes the last opened:
If those brackets match, then remove the last opened from the list of openedBrackets and continue to check recursively on the rest of the string
Else you have found a brackets that close a nerver opened once, so it is not balanced.
When the string is finally empty, if the list of brackes is empty too (so all the brackes has been closed) return true, else false
ALGORITHM (in Java):
public static boolean isBalanced(final String str1, final LinkedList<Character> openedBrackets, final Map<Character, Character> closeToOpen) {
if ((str1 == null) || str1.isEmpty()) {
return openedBrackets.isEmpty();
} else if (closeToOpen.containsValue(str1.charAt(0))) {
openedBrackets.add(str1.charAt(0));
return isBalanced(str1.substring(1), openedBrackets, closeToOpen);
} else if (closeToOpen.containsKey(str1.charAt(0))) {
if (openedBrackets.getLast() == closeToOpen.get(str1.charAt(0))) {
openedBrackets.removeLast();
return isBalanced(str1.substring(1), openedBrackets, closeToOpen);
} else {
return false;
}
} else {
return isBalanced(str1.substring(1), openedBrackets, closeToOpen);
}
}
TEST:
public static void main(final String[] args) {
final Map<Character, Character> closeToOpen = new HashMap<Character, Character>();
closeToOpen.put('}', '{');
closeToOpen.put(']', '[');
closeToOpen.put(')', '(');
closeToOpen.put('>', '<');
final String[] testSet = new String[] { "abcdefksdhgs", "[{aaa<bb>dd}]<232>", "[ff{<gg}]<ttt>", "{<}>" };
for (final String test : testSet) {
System.out.println(test + " -> " + isBalanced(test, new LinkedList<Character>(), closeToOpen));
}
}
OUTPUT:
abcdefksdhgs -> true
[{aaa<bb>dd}]<232> -> true
[ff{<gg}]<ttt> -> false
{<}> -> false
Note that i have imported the following classes:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
public static boolean isBalanced(String str) {
if (str.length() == 0) {
return true;
}
if (str.contains("()")) {
return isBalanced(str.replaceFirst("\\(\\)", ""));
}
if (str.contains("[]")) {
return isBalanced(str.replaceFirst("\\[\\]", ""));
}
if (str.contains("{}")) {
return isBalanced(str.replaceFirst("\\{\\}", ""));
} else {
return false;
}
}
Balanced Parenthesis (JS)
The more intuitive solution is to use stack like so:
function isBalanced(str) {
const parentesis = {
'(': ')',
'[': ']',
'{': '}',
};
const closing = Object.values(parentesis);
const stack = [];
for (let char of str) {
if (parentesis[char]) {
stack.push(parentesis[char]);
} else if (closing.includes(char) && char !== stack.pop()) {
return false;
}
}
return !stack.length;
}
console.log(isBalanced('{[()]}')); // true
console.log(isBalanced('{[(]]}')); // false
console.log(isBalanced('([()]')); // false
And using recursive function (without using stack), might look something like so:
function isBalanced(str) {
const parenthesis = {
'(': ')',
'[': ']',
'{': '}',
};
if (!str.length) {
return true;
}
for (let i = 0; i < str.length; i++) {
const char = str[i];
if (parenthesis[char]) {
for (let j = str.length - 1; j >= i; j--) {
const _char = str[j];
if (parenthesis[_char]) {
return false;
} else if (_char === parenthesis[char]) {
return isBalanced(str.substring(i + 1, j));
}
}
} else if (Object.values(parenthesis).includes(char)) {
return false;
}
}
return true;
}
console.log(isBalanced('{[()]}')); // true
console.log(isBalanced('{[(]]}')); // false
console.log(isBalanced('([()]')); // false
* As #Adrian mention, you can also use stack in the recursive function without the need of looking backwards
It doesn't really matter from a logical point of view -- if you keep a stack of all currently un-balanced parens that you pass to each step of the recursion, you'll never need to look backwards, so it doesn't matter if you cut up the string on each recursive call, or just increment an index and only look at the current first character.
In most programming languages, which have non-mutable strings, it's probably more expensive (performance-wise) to shorten the string than it is to pass a slightly larger string on the stack. On the other hand, in a language like C, you could just increment a pointer within the char array. I guess it's pretty language-dependent which of these two approaches is more 'efficient'. They're both equivalent from a conceptual point of view.
In the Scala programming language, I would do it like this:
def balance(chars: List[Char]): Boolean = {
def process(chars: List[Char], myStack: Stack[Char]): Boolean =
if (chars.isEmpty) myStack.isEmpty
else {
chars.head match {
case '(' => process(chars.tail, myStack.push(chars.head))
case ')' => if (myStack.contains('(')) process(chars.tail, myStack.pop)
else false
case '[' => process(chars.tail, myStack.push(chars.head))
case ']' => {
if (myStack.contains('[')) process(chars.tail, myStack.pop) else false
}
case _ => process(chars.tail, myStack)
}
}
val balancingAuxStack = new Stack[Char]
process(chars, balancingAuxStack)
}
Please edit to make it perfect.
I was only suggesting a conversion in Scala.
I would say this depends on your design. You could either use two counters or stack with two different symbols or you can handle it using recursion, the difference is in design approach.
func evalExpression(inStringArray:[String])-> Bool{
var status = false
var inStringArray = inStringArray
if inStringArray.count == 0 {
return true
}
// determine the complimentary bracket.
var complimentaryChar = ""
if (inStringArray.first == "(" || inStringArray.first == "[" || inStringArray.first == "{"){
switch inStringArray.first! {
case "(":
complimentaryChar = ")"
break
case "[":
complimentaryChar = "]"
break
case "{":
complimentaryChar = "}"
break
default:
break
}
}else{
return false
}
// find the complimentary character index in the input array.
var index = 0
var subArray = [String]()
for i in 0..<inStringArray.count{
if inStringArray[i] == complimentaryChar {
index = i
}
}
// if no complimetary bracket is found,so return false.
if index == 0{
return false
}
// create a new sub array for evaluating the brackets.
for i in 0...index{
subArray.append(inStringArray[i])
}
subArray.removeFirst()
subArray.removeLast()
if evalExpression(inStringArray: subArray){
// if part of the expression evaluates to true continue with the rest.
for _ in 0...index{
inStringArray.removeFirst()
}
status = evalExpression(inStringArray: inStringArray)
}
return status
}
PHP Solution to check balanced parentheses
<?php
/**
* #param string $inputString
*/
function isBalanced($inputString)
{
if (0 == strlen($inputString)) {
echo 'String length should be greater than 0';
exit;
}
$stack = array();
for ($i = 0; $i < strlen($inputString); $i++) {
$char = $inputString[$i];
if ($char === '(' || $char === '{' || $char === '[') {
array_push($stack, $char);
}
if ($char === ')' || $char === '}' || $char === ']') {
$matchablePairBraces = array_pop($stack);
$isMatchingPair = isMatchingPair($char, $matchablePairBraces);
if (!$isMatchingPair) {
echo "$inputString is NOT Balanced." . PHP_EOL;
exit;
}
}
}
echo "$inputString is Balanced." . PHP_EOL;
}
/**
* #param string $char1
* #param string $char2
* #return bool
*/
function isMatchingPair($char1, $char2)
{
if ($char1 === ')' && $char2 === '(') {
return true;
}
if ($char1 === '}' && $char2 === '{') {
return true;
}
if ($char1 === ']' && $char2 === '[') {
return true;
}
return false;
}
$inputString = '{ Swatantra (() {} ()) Kumar }';
isBalanced($inputString);
?>
It should be a simple use of stack ..
private string tokens = "{([<})]>";
Stack<char> stack = new Stack<char>();
public bool IsExpressionVaild(string exp)
{
int mid = (tokens.Length / 2) ;
for (int i = 0; i < exp.Length; i++)
{
int index = tokens.IndexOf(exp[i]);
if (-1 == index) { continue; }
if(index<mid ) stack .Push(exp[i]);
else
{
if (stack.Pop() != tokens[index - mid]) { return false; }
}
}
return true;
}
#indiv's answer is nice and enough to solve the parentheses grammar problems. If you want to use stack or do not want to use recursive method you can look at the python script on github. It is simple and fast.
BRACKET_ROUND_OPEN = '('
BRACKET_ROUND__CLOSE = ')'
BRACKET_CURLY_OPEN = '{'
BRACKET_CURLY_CLOSE = '}'
BRACKET_SQUARE_OPEN = '['
BRACKET_SQUARE_CLOSE = ']'
TUPLE_OPEN_CLOSE = [(BRACKET_ROUND_OPEN,BRACKET_ROUND__CLOSE),
(BRACKET_CURLY_OPEN,BRACKET_CURLY_CLOSE),
(BRACKET_SQUARE_OPEN,BRACKET_SQUARE_CLOSE)]
BRACKET_LIST = [BRACKET_ROUND_OPEN,BRACKET_ROUND__CLOSE,BRACKET_CURLY_OPEN,BRACKET_CURLY_CLOSE,BRACKET_SQUARE_OPEN,BRACKET_SQUARE_CLOSE]
def balanced_parentheses(expression):
stack = list()
left = expression[0]
for exp in expression:
if exp not in BRACKET_LIST:
continue
skip = False
for bracket_couple in TUPLE_OPEN_CLOSE:
if exp != bracket_couple[0] and exp != bracket_couple[1]:
continue
if left == bracket_couple[0] and exp == bracket_couple[1]:
if len(stack) == 0:
return False
stack.pop()
skip = True
left = ''
if len(stack) > 0:
left = stack[len(stack) - 1]
if not skip:
left = exp
stack.append(exp)
return len(stack) == 0
if __name__ == '__main__':
print(balanced_parentheses('(()())({})[]'))#True
print(balanced_parentheses('((balanced)(parentheses))({})[]'))#True
print(balanced_parentheses('(()())())'))#False

Resources