I was wondering if this approach is ok or if there is any better structure to find if the brackets are properly nested/aligned.
My concern is the complexity is increase due to isMatrixZero() method.
public static boolean areBracketsCurlyParenthesisAligned(String input){
int numOpen = countOpens(input);
int[][] symbols = new int[numOpen][3];
for (int i=0; i < input.length(); i++){
int j=0; // level 0
switch (input.charAt(i)){
case '[':
symbols[j][0]++;
j++;
break;
case ']':
j--;
symbols[j][0]--;
break;
case '{':
symbols[j][1]++;
j++;
break;
case '}':
j--;
symbols[j][1]--;
break;
case '(':
symbols[j][2]++;
j++;
break;
case ')':
j--;
symbols[j][2]--;
break;
default:
break;
}
if (symbols[0][0] < 0 || symbols[0][1] < 0 || symbols[0][2] < 0) return false;
}
// All symbol variables value should be 0 at the end
if (isMatrixZero(symbols)) return true;
else return false;
}
private static int countOpens(String str){
int opens=0;
for (int i=0; i< str.length(); i++){
if (str.charAt(i) == '[' || str.charAt(i) == '{' || str.charAt(i) == '(') opens++;
}
return opens;
}
private static boolean isMatrixZero(int[][] matrix){
for (int i=0; i < matrix.length;i++){
for (int j=0; j < matrix[0].length;j++){
if (matrix[i][j] != 0) return false;
}
}
return true;
}
}
Any suggestion is welcomed!
Why not use stacks? Instead of strings you can use HashMap, opening brackets would be keys, closing would be value.
private final static String openingBrackets = "([{<";
private final static String closingBrackets = ")]}>";
public static boolean checkBrackets(String input) {
Stack<Character> openedBrackets = new Stack<Character>();
HashMap brackets = new HashMap();
char[] inputs = input.toCharArray();
int x = 0;
for (char c : inputs) {
if (openingBrackets.indexOf(c) != -1) {
openedBrackets.push(c);
} else if (closingBrackets.indexOf(c) != -1) {
if (openedBrackets.isEmpty())
return false;
if (Math.abs(openedBrackets.pop() - c) > 2)
return false;
}
x++;
if (openedBrackets.size() > inputs.length - x)
return false;
}
return openedBrackets.isEmpty();
}
Also, here is the same question Checking string has balanced parentheses
Related
I am trying to develop a method to reverse the vowels in a string. For this, I have developed my own small stack. I am iterating backwards through the string twice, once to populate the stack with each vowel I locate, the second time to replace the vowel with the vowel stored at the top of the stack. I have added a bunch of print statements to determine where this is failing and it seems to be failing at the setCharAt method. For testing purposes, I provide a string aeiou and I am expecting to get back uoiea. The chars are getting replaced during each iteration, but unfortunately, they don't stay that way. As of the next iteration, the chars that were replaced on the previous iteration return to what they were before. As a result, I am getting back ueiou, where only the first character in the string is as expected (and the third which is a noop). Here is my code. Any tips are appreciated.
import java.util.*;
public class Solution {
static String result;
static class StackOfVowels {
static Node top;
public StackOfVowels() {
Node top = null;
}
static class Node {
Node next = null;
char vowel = '\0';
Node(char value) {
this.vowel = value;
}
}
public void push(char item) {
Node node = new Node(item);
if (top == null) {
top = node;
}
else {
node.next = top;
top = node;
}
}
public char top() {
if (top == null) throw new EmptyStackException();
return top.vowel;
}
public void pop() {
int result = -1;
if (top != null) {
result = top.vowel;
top = top.next;
}
}
}
public static String reverseVowels(String s) {
StackOfVowels stackOfVowels = new StackOfVowels();
for(int i = s.length()-1; i >= 0; i--) {
char c = s.charAt(i);
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) {
System.out.println("Initial sequence of iterations identified vowel: " + c);
stackOfVowels.push(c);
System.out.println("Pushed to stack, current top is: " + stackOfVowels.top());
}
}
for(int j = s.length()-1; j >= 0; j--) {
char b = s.charAt(j);
if ((b == 'a') || (b == 'e') || (b == 'i') || (b == 'o') || (b == 'u')) {
System.out.println("Second sequence of iterations identified vowel: " + b);
StringBuilder newstr = new StringBuilder(s);
char d = stackOfVowels.top();
System.out.println("Variable d set to top of: " + stackOfVowels.top());
newstr.setCharAt(j, d);
result = newstr.toString();
System.out.println("Here is the new string: " + result);
stackOfVowels.pop();
System.out.println("Stack was popped");
}
}
return result;
}
public static void main(String[] args) {
String s = "aeiou";
reverseVowels(s);
System.out.println("Final result: " + result);
}
}
A slight improvement (debatable) on #Elliot answer is to create the StringBuilder with the original String and only replace when necessary
String vowels = new StringBuilder(s.replaceAll("[^AEIOUaeiou]", ""))
.reverse().toString();
StringBuilder sb = new StringBuilder(s);
for (int i = 0, p = 0; i < s.length(); i++) {
switch (Character.toLowerCase(s.charAt(i))) {
// Note that these fall-through...
case 'a': case 'e': case 'i': case 'o': case 'u':
sb.setCharAt(i, vowels.charAt(p++));
break;
default:
break;
}
}
return sb.toString();
You generate always a new StringBuilder in your second loop with StringBuilder newstr = new StringBuilder(s);
But you always use ´s´ and not ´result´ to build your new StringBuilder.
It would be better anyways to not create a new Object of StringBuilder in each Iteration.
Also it is confusing that your methode has a return value, which is never used.
Following methode should work:
public static String reverseVowels(String s) {
StackOfVowels stackOfVowels = new StackOfVowels();
for(int i = s.length()-1; i >= 0; i--) {
char c = s.charAt(i);
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) {
System.out.println("Initial sequence of iterations identified vowel: " + c);
stackOfVowels.push(c);
System.out.println("Pushed to stack, current top is: " + stackOfVowels.top());
}
}
StringBuilder result_builder = new StringBuilder(s);
for(int j = s.length()-1; j >= 0; j--) {
char b = s.charAt(j);
if ((b == 'a') || (b == 'e') || (b == 'i') || (b == 'o') || (b == 'u')) {
System.out.println("Second sequence of iterations identified vowel: " + b);
char d = stackOfVowels.top();
System.out.println("Variable d set to top of: " + stackOfVowels.top());
result_builder.setCharAt(j, d);
stackOfVowels.pop();
System.out.println("Stack was popped");
}
}
result = result_builder.toString();
return result_builder.toString();
}
I would approach the problem a little differently, first I would use a regular expression to remove all consonants from the String to create a String of vowels. Then I would iterate through the characters of the String, using StringBuilder to build the output (passing consonants through, but replacing vowels using the vowels String previously created). Like,
public static String reverseVowels(String s) {
// Match all consonants, and remove them. Reverse that String.
String vowels = new StringBuilder(s.replaceAll("[^AEIOUaeiou]", ""))
.reverse().toString();
StringBuilder sb = new StringBuilder();
for (int i = 0, p = 0; i < s.length(); i++) {
switch (Character.toLowerCase(s.charAt(i))) {
// Note that these fall-through...
case 'a': case 'e': case 'i': case 'o': case 'u':
sb.append(vowels.charAt(p++));
break;
default:
sb.append(s.charAt(i));
}
}
return sb.toString();
}
This is one of the places that switch and fall-through behavior can be taken advantage of.
And if you're using Java 8+, you could express the same with an IntStream and map the characters; like
String vowels = new StringBuilder(s.replaceAll("[^AEIOUaeiou]", ""))
.reverse().toString();
int[] counter = new int[1]; // <-- A bit of a kludge really.
return IntStream.range(0, s.length()).mapToObj(i -> {
switch (Character.toLowerCase(s.charAt(i))) {
case 'a': case 'e': case 'i': case 'o': case 'u':
return Character.toString(vowels.charAt(counter[0]++));
default:
return Character.toString(s.charAt(i));
}
}).collect(Collectors.joining());
I have a method getRPNString(), which returns Reverse Polish Notation string. I want to split this string by spacebars to calculate it. Now I can't understand how to add spacebars in my RNP string right, because it's not working with two digits numbers.
public class Calc1 {
public static void main(String[] args) {
String in = "((5+3*(4+2)*12)+3)/(1+3)+5";
String out = getRPNString(in);
System.out.println(out);
}
private static String getRPNString(String in) {
LinkedList<Character> oplist = new LinkedList<>();
StringBuilder out = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
char op = in.charAt(i);
if (op == ')') {
while (oplist.getLast() != '(') {
out.append(oplist.removeLast());
}
oplist.removeLast();
}
if (Character.isDigit(op)) {
out.append(op);
/*int j = i + 1;
for (; j < in.length(); j++) {
if (!Character.isDigit(j)) {
break;
}
i++;
}
out.append(in.substring(i, j));*/
}
if (op == '(') {
oplist.add(op);
}
if (isOperator(op)) {
if (oplist.isEmpty()) {
oplist.add(op);
} else {
int priority = getPriority(op);
if (priority > getPriority(oplist.getLast())) {
oplist.add(op);
} else {
while (!oplist.isEmpty()
&& priority <= getPriority(oplist.getLast())) {
out.append(oplist.removeLast());
}
oplist.add(op);
}
}
}
}
while (!oplist.isEmpty()) {
out.append(oplist.removeLast());
}
return out.toString();
}
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '%';
}
private static int getPriority(char op) {
switch (op) {
case '*':
case '/':
return 3;
case '+':
case '-':
return 2;
case '(':
return 1;
default:
return -1;
}
}
}
I tried to add spacebars by append(' ') in my StringBuilder variable out. But it' s not right with two digits. I think I totally do not understand how to make it.
For example if input is String in = "((5+3*(4+2)*12)+3)/(1+3)+5"; the out will be 5342+12+3+13+/5+, when I add spacebars to all calls out.append(' ')**out is **5 3 4 2 + * 1 2 * + 3 + 1 3 + / 5 +, so numbers like "12" became "1 2".
Can you help?
Just change the code that you have commented out, right after Character.isDigit(op) to:
int j = i + 1;
int oldI = i;//this is so you save the old value
for (; j < in.length(); j++) {
if (!Character.isDigit(in.charAt(j))) {
break;
}
i++;
}
out.append(in.substring(oldI, j));
out.append(' ');
I changed my method, now it works fine. I fonded my mistake when I wroted
!Character.isDigit(j) but need !Character.isDigit(in.charAt(j)).
private static String getRPNString(String in) {
LinkedList<Character> oplist = new LinkedList<>();
StringBuilder out = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
char op = in.charAt(i);
if (op == ')') {
while (oplist.getLast() != '(') {
out.append(oplist.removeLast()).append(' ');
}
oplist.removeLast();
}
if (Character.isDigit(op)) {
int j = i + 1;
int oldI = i;//this is so you save the old value
for (; j < in.length(); j++) {
if (!Character.isDigit(in.charAt(j))) {
break;
}
i++;
}
out.append(in.substring(oldI, j));
out.append(' ');
}
if (op == '(') {
oplist.add(op);
}
if (isOperator(op)) {
if (oplist.isEmpty()) {
oplist.add(op);
} else {
int priority = getPriority(op);
if (priority > getPriority(oplist.getLast())) {
oplist.add(op);
} else {
while (!oplist.isEmpty()
&& priority <= getPriority(oplist.getLast())) {
out.append(oplist.removeLast()).append(' ');
}
oplist.add(op);
}
}
}
}
while (!oplist.isEmpty()) {
out.append(oplist.removeLast()).append(' ');
}
return out.toString();
}
Now it produce right expression.
Test: input: ((5+3*(4+2)*12)+3)/(1+3)+5
output : 5 3 4 2 + * 12 * + 3 + 1 3 + / 5 +
This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
I tried making my infix to postfix code, it works without the braces, but when I try to include the portion to account for braces, it crashes, here is the main part of the code:
for (i=0; i<characters.length; i++)
{
if (characters[i]=='*' || characters[i]=='/' || characters[i]=='+' || characters[i]=='-' || characters[i]=='(' || characters[i]==')'){
if (postfix.empty() && characters[i]!=')')
postfix.push(characters[i]);
else if (!postfix.empty()){
if (characters[i]=='(')
postfix.push(characters[i]);
if (characters[i]=='*' || characters[i]=='/')
priority2=1;
if (characters[i]=='+' || characters[i]=='-')
priority2=0;
if (characters[i]==')'){
while (postfix.peek()!='(') //loop until we see the closing bracket
System.out.print(postfix.pop()); //pop everything till we see the closing bracket
postfix.pop(); //to pop the bracket
}
if (!postfix.empty())
peeked=postfix.peek();
if (peeked=='*' || peeked=='/')
priority=1;
if (peeked=='+' || peeked=='-')
priority=0;
if (priority2>priority)
postfix.push(characters[i]);
else{
while (!postfix.empty())
System.out.print(postfix.pop());
postfix.push(characters[i]);
}
}
}
else
System.out.print(characters[i]);
}
while (!postfix.empty())
System.out.print(postfix.pop());
Any help would be appreciated. It breaks when it comes to a brace.
You can get some insight from my implementation of Infix To Postfix program, which is based on the standard algorithm for doing such conversions. Here it is:
import java.util.Scanner;
import java.util.Stack;
public class InfixPostfix
{
private Stack<Character> stack;
private StringBuilder postfixExpression;
public InfixPostfix()
{
stack = new Stack<>();
postfixExpression = new StringBuilder();
String infix = getInfixExpression();
if (isValidInfix(infix))
{
System.out.println(convertToPostfix(infix));
}
else
{
System.out.println("Invalid Expression");
}
}
private boolean isValidInfix(String infix)
{
int parenthesisCounter = 0;
for (int i = 0; i < infix.length(); i++)
{
char ch = infix.charAt(i);
if (ch == '(')
parenthesisCounter++;
else if (ch == ')')
parenthesisCounter--;
if (parenthesisCounter < 0)
return false;
}
if (parenthesisCounter == 0)
return true;
return false;
}
private String convertToPostfix(String infix)
{
for (int i = 0; i < infix.length(); i++)
{
char ch = infix.charAt(i);
switch (ch)
{
case '+':
case '-':
processOperatorOfPrecedence(ch, 1);
break;
case '*':
case '/':
processOperatorOfPrecedence(ch, 2);
break;
case '(':
stack.push(ch);
break;
case ')':
processParenthesis(ch);
break;
default:
postfixExpression.append(ch);
break;
}
}
while (!stack.isEmpty())
{
postfixExpression.append(stack.pop());
}
return postfixExpression.toString();
}
private void processOperatorOfPrecedence(char operator, int precedence)
{
while (!stack.isEmpty())
{
char topOperator = stack.pop();
if (topOperator == '(')
{
stack.push(topOperator);
break;
}
else
{
int operatorPrecedence;
if (topOperator == '+' || topOperator == '-')
operatorPrecedence = 1;
else
operatorPrecedence = 2;
if (operatorPrecedence < precedence)
{
stack.push(topOperator);
break;
}
else
postfixExpression.append(topOperator);
}
}
stack.push(operator);
}
private void processParenthesis(char ch)
{
while (!stack.isEmpty())
{
char character = stack.pop();
if (character == '(')
break;
else
postfixExpression.append(character);
}
}
private String getInfixExpression()
{
Scanner scanner = new Scanner(System.in);
System.out.println("Enter an infix math expression: ");
String input = scanner.nextLine();
scanner.close();
return input;
}
public static void main(String[] args)
{
new InfixPostfix();
}
}
I have a string array that looks like this:
[67, +, 12, -, 45]
I want to print it out so that it looks like this:
67 12 + 45 -
Here's the code I'm trying to use to do this.
String[] temp = line.split(" ");
String tmp = line.replaceAll("\\s+","");
for(int i = 0; i < temp.length; i++)
{
if(isInt(temp[i]) == false)
{
expression = temp[i];
firstExp = true;
}
else if(isInt(temp[i]) == false && firstExp == true && secondExp == false)
{
System.out.print(expression);
secondExp = true;
}
else if(isInt(temp[i]) == false && firstExp == true && secondExp == true)
{
System.out.print(expression);
firstExp = false;
secondExp = false;
}
else
{
System.out.print(temp[i]);
}
}
firstExp and secondExp are Booleans that check for the expressions that should appear in the array. isInt() is just a method used to determine if the string is a number. Right now, all this code does is output this:
671245
public static void main (String[] args) throws java.lang.Exception
{
String[] expr = new String[]{"67", "+", "45", "-", "12", "*", "5", "/", "78"};
int current = 0;
StringBuilder postfix = new StringBuilder();
// handle first three
postfix.append(expr[current]).append(" ");
postfix.append(expr[current+2]).append(" ");
postfix.append(expr[current+1]).append(" ");
current += 3;
// handle rest
while( current <= expr.length-2 ){
postfix.append(expr[current+1]).append(" ");
postfix.append(expr[current]).append(" ");
current += 2;
}
System.out.println(postfix.toString());
}
Outputs:
67 45 + 12 - 5 * 78 /
You can run/edit this at: http://ideone.com/zcdlEq
I guess what you are trying to do is converting infix expression to post fix. Some time back I had written the following code:
public class InfixToPostfix {
private Stack stack;
private String input;
private String output = "";
public InfixToPostfix(String in) {
input = in;
int stackSize = input.length();
stack = new Stack(stackSize);
}
public String translate() {
for (int j = 0; j < input.length(); j++) {
char ch = input.charAt(j);
switch (ch) {
case '+':
case '-':
hastOperator(ch, 1);
break;
case '*':
case '/':
hastOperator(ch, 2);
break;
case '(':
stack.push(ch);
break;
case ')':
hasSuperior(ch);
break;
default:
output = output + ch;
break;
}
}
while (!stack.isEmpty()) {
output = output + stack.pop();
}
System.out.println(output);
return output;
}
public void hastOperator(char op, int precedence) {
while (!stack.isEmpty()) {
char opTop = stack.pop();
if (opTop == '(') {
stack.push(opTop);
break;
}
else {
int prec2;
if (opTop == '+' || opTop == '-')
prec2 = 1;
else
prec2 = 2;
if (prec2 < precedence) {
stack.push(opTop);
break;
}
else
output = output + opTop;
}
}
stack.push(op);
}
public void hasSuperior(char ch){
while (!stack.isEmpty()) {
char chx = stack.pop();
if (chx == '(')
break;
else
output = output + chx;
}
}
public static void main(String[] args)
throws IOException {
String input = "67 + 12 - 45";
String output;
InfixToPostfix theTrans = new InfixToPostfix(input);
output = theTrans.translate();
System.out.println("Postfix is " + output + '\n');
}
class Stack {
private int maxSize;
private char[] stackArray;
private int top;
public Stack(int max) {
maxSize = max;
stackArray = new char[maxSize];
top = -1;
}
public void push(char j) {
stackArray[++top] = j;
}
public char pop() {
return stackArray[top--];
}
public char peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
}
}
You may need to modify this program to read from an array, but that is very trivial.
Here's how you do it in one line:
System.out.println(Arrays.toString(temp).replaceAll("[^\\d +*/-]", "").replaceAll("[+*/-]) (\\d+)", "$2 $1"));
How can I write the below code without using regex?
public static boolean validateCode(String code){
boolean hasAtLeastOneNumber = Pattern.compile("[0-9].*[0-9]")
.matcher(code).find();
boolean hasAtLeastTwoLetters = Pattern.compile("[a-zA-Z].*[a-zA-Z]")
.matcher(code).find();
boolean hasAtLeastOneHyphen = Pattern.compile("-")
.matcher(code).find();
}
How about
public static boolean validateCode2(String code) {
int numbers = 0, letters = 0, hyphens = 0;
for (char c : code.toCharArray()) {
if (Character.isDigit(c)) numbers++;
if (Character.isAlphabetic(c)) letters++;
if (c=='-') hyphens++;
}
return numbers>=2 && letters>=2 && hyphens>=1;
}
For hasAtLeastOneNumber:
for (char c : code.toCharArray()) {
if (Character.isDigit(c)) {
return true;
}
return false;
For hasAtLeastTwoLetters:
int numFound = 0;
for (char c : code.toCharArray()) {
if (Character.isLetter(c)) {
numFound++;
if (numFound >= 2) {
return true;
}
}
}
return false;
For hasAtLeastOneHyphen:
for (char c : code.toCharArray()) {
if (c == '-') {
return true;
}
}
return false;
If you don't want to use toCharArray, you could use:
for (int i=0; i<code.length(); i++) {
char c = code.charAt(i);
// do the rest of the test here
}
That's basically equivalent to using toCharArray except that it's slightly more confusing: someone who looks at the code would need to take a second or two to figure it out. With toCharArray it's obvious what you're doing.
You can loop through the string and test it for ranges of characters. See an example on IDEONE, or ask me if you need an explanation.
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
System.out.println(validarCodigo("No-numbers"));
System.out.println(validarCodigo("1-A"));
System.out.println(validarCodigo("This 1 Matches -- :-)"));
}
public static boolean validarCodigo(String codigo) {
int i;
char[] chars = codigo.toCharArray();
char current;
boolean tieneAlmenosUnNumero = false;
boolean tieneAlmenosDosLetras = false;
boolean tieneAlmenosUnGuion = false;
// Check for at least one number
for (i=0; i<chars.length; i++) {
current = chars[i];
if (current >= '0' && current <= '9') {
tieneAlmenosUnNumero = true;
break;
}
}
// Check for at least two letters
int found = 0;
for (i=0; i<chars.length; i++) {
current = chars[i];
boolean lower = current >= 'a' && current <= 'z';
boolean upper = current >= 'A' && current <= 'Z';
if (lower || upper) found++;
if (found == 2){
tieneAlmenosDosLetras = true;
break;
}
}
// Check for at least one hyphen
for (i=0; i<chars.length; i++) {
current = chars[i];
if (current == '-') {
tieneAlmenosUnGuion = true;
break;
}
}
return tieneAlmenosUnNumero && tieneAlmenosDosLetras && tieneAlmenosUnGuion;
}
}