Check whether the brackets and delimiters contained in a string are balanced - java

Here is simple code to check whether the brackets/delimiters contained in a string are balanced - can anyone help why wont it work! I'm sure there are many things I could to to improve efficiency but for the purpose of my current tutorial I would like to know why it doesn't work in this form and what the current problems are.
Firstly, I cannot add the variable c to the LinkedList, I have to use the literal value - I have identical in another tutorial and it adds the variable just fine.
Secondly, in some instances it simply doesn't add the delimiters to my linkedlist as per the if statements. the string '(i wonder(if) the delimiters in this) [sentence] will evaluate as[ balanced}' evaluates as balanced but from my code it shouldn't do - Please help I am pulling my hair out here.
Finally, I have had the same error but sporadically not for every string - some i type in randomly for example 'csadlkfsd kljf[]{}[ ][ ]{ '
this returned the error
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at set07102.Delimiter.main(Delimiter.java:16)
and line 16 is 'char c = s.charAt(0);' and as far as i see this shouldn't be happening.
System.out.println(strStack); is only there are at the end to inspect the LinkedList - if it makes it that far through the code!
any help will be amaaaaaaaaazing thanks guys.
import java.util.LinkedList;
import java.util.Scanner;
public class Delimiter {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a string containing different types of brackets: ");
String str = scanner.nextLine();
String[] strSplit = str.split(" ");
LinkedList<Character> strStack = new LinkedList<>();
System.out.println(" ");
for(String s : strSplit) {
char c = s.charAt(0);
if(c == '('){
strStack.push('(');
}
if( c == '{'){
strStack.push('{');
}
if(c == '['){
strStack.push('[');
}
if(c == '<'){
strStack.push('<');
}
if(c == ')' && strStack.get(0) != '('){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
if(c == ']' && strStack.get(0) != '['){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
if(c == '}' && strStack.get(0) != '{'){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
if(c == '>' && strStack.get(0) != '<'){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
}
System.out.println("The delimiters in the string " + "'" + str + "'" + " are balanced. ");
System.out.println(" ");
System.out.println(strStack);
}
}

Here is one way of doing it. I'm not sure if it's completely bug free and will handle all cases, but I think it might be close.
As other users have commented, splitting the input string is the wrong approach. You'll need to iterate over each character and use the stack to keep track of what brackets you've seen and what should be closed next.
import java.util.HashMap;
import java.util.Scanner;
import java.util.Stack;
public class BalancedBrackets
{
public static void main(String[] args)
{
HashMap<Character,Character> bracketPairs = new HashMap<Character,Character>();
bracketPairs.put('[', ']');
bracketPairs.put('(', ')');
bracketPairs.put('{', '}');
bracketPairs.put('<', '>');
Stack stack = new Stack();
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a string containing different types of brackets: ");
String str = scanner.nextLine();
for(int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if(bracketPairs.keySet().contains(c))
{
stack.push(c);
}
if(bracketPairs.values().contains(c))
{
if(stack.size() == 0)
{
System.out.println("Unexpected closing bracket.");
return;
}
char lastOpen = (char) stack.peek();
char expectedClose = bracketPairs.get(lastOpen);
if(expectedClose == c)
{
stack.pop();
}
else
{
System.out.println("Unexpected closing bracket.");
return;
}
}
}
if(stack.size()==0)
{
System.out.println("String is balanced.");
}
else
{
System.out.println("String is unbalanced.");
}
}
}

Related

How do I put a remove a leading space when printing something in java?

How do I put a remove a leading space when printing something in java?
import java.util.Scanner;
import java.io.IOException;
public class InitialsProject {
public static void main(String args[]) throws IOException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scan.nextLine();
char firstInitial = name.charAt(0);
int index = name.indexOf(" ");
System.out.println(firstInitial + name.substring(index++,index+1));
}
}
Sample input: John Doe
Output: J D
So your question is a little vague, but I assume your issue is around "why does it print "J D" and not "JD""
The simple answer is index++ is post operation, that is, the value of index is first used (by substring), then it's updated. You could fix it by using a pre operation, ie ++index, but I would suggest that using index + 1 (and index + 2) is more readable and less error prone.
But...there are a number of ways you might perform this operation
For example, you could simply use String#split
String text = "John Doe";
String[] parts = text.split(" ");
if (parts.length == 1 && !parts[0].isEmpty()) {
System.out.println(parts[0].charAt(0));
} else if (parts.length == 2) {
if (!parts[0].isEmpty() && !parts[1].isEmpty()) {
System.out.println(parts[0].charAt(0) + " " + parts[1].charAt(0));
} else if (!parts[0].isEmpty()) {
System.out.println(parts[1].charAt(0));
} else if (!parts[1].isEmpty()) {
System.out.println("..." + parts[1].charAt(0));
} else {
System.out.println(text + " is an invalid input");
}
} else {
System.out.println(text + " is an invalid input");
}
nb: I'm been a little defensive, can't help it
Or you could simply use charAt directly...
int index = text.indexOf(" ");
if (index >= 0) {
if (index + 1 < text.length()) {
System.out.println(text.charAt(0) + " " + text.charAt(index + 1));
} else {
System.out.println(text.charAt(0));
}
} else {
// Handle all the other possible conditions
}
Both the examples will print J D
Simply using charAt would do the trick,
System.out.println(firstInitial + name.charAt(index+1));

Ignoring particular elements in a string array

I am writing a program that that ignores everything between the symbols "/" and "/" in a string, similarly as the IDE would in a real life scenario. I'm splitting the string into lines and storing it in an array, I then have a while loop to build words from the individual characters in the current line ignoring the symbols, however it my output isn't quite right.
Below is an example of what i'm trying to achieve.
Phrase: The quick brown /* fox jumped over the */ lazy dog.
Desired output: The quick brown lazy dog.
Essentially removing everything between the comments.
Here is my current attempt.
public class Testing6 {
public static void main(String[] args) {
String riddle = "The Quick \n" +
" brown /* fox \n" +
" jumped over \n" +
" the */ lazy \n" +
" dog \n";
String[] lines = riddle.split("\\r?\\n");
for (String line : lines) {
int n = line.length();
int index = 0;
String word = "";
while (index < n) {
char ch = line.charAt(index);
word = word + ch;
if (ch == ' ' ) //if ch is empty, word is complete, print word.
{
System.out.println(word);
word = "";
}
if (ch == '/' || ch == '*') { // checking for symbols
index++;
if (ch == '*' || ch == '/')
{
index++;
break; // breaking if symbols match
}
}
index++;
}
}
}
}
Current output:
The
Quick
brown
jumped
over
the `
Thank you in advance for any feedback.
I am modifying your answer to display the line as per your expectation. There is no real enhancement done to your code here.
Following are the issues in your code:
You are using println which prints each string in a new line.
You are also printing empty words thereby seeing gaps in the strings in the output.
I fixed both the above problems and it is displaying properly now
String riddle = "The Quick \n" +
" brown /* fox \n" +
" jumped over \n" +
" the */ lazy \n" +
" dog \n";
String[] lines = riddle.split("\\r?\\n");
String word = "";
for (String line : lines) {
int n = line.length();
for (int index = 0; index < n; index++) {
char ch = line.charAt(index);
if (ch == ' ') { // if ch is empty, word is complete, print word.
if (!word.isEmpty()) { // do not log empty word
word = word + ch;
System.out.print(word);
word = "";
}
continue;
}
if (ch == '/' || ch == '*') { // checking for symbols
index++;
if (ch == '*' || ch == '/') {
index++;
break; // breaking if symbols match
}
}
word = word + ch; // only non-empty chars are added here
}
}
Output is
The Quick brown jumped over the dog
Note that the last word may contain extra space based on your input. But I think you can take it forward from here.

Having dashes change into guessed letters

my program currently takes a random word and turns into dashes based on how many letters are in the word. I then determine if a letter guessed is in the word, but I was unable to figure out how to have the correctly guessed letter replace the dashes accordingly. I looked through possible solutions on the site, but was unable to have one work for my current code.
Code:
public String hiddenWord(){
word = randomWord.getRandomWord();
String dashes = word.replaceAll("[^ ]", " _ ");
return dashes;
}
public String guessNotification(){
if(word.indexOf(hv.keyChar)!=-1 && (hv.keyChar >= 'a' && hv.keyChar <= 'z')) {
letterGuessed = "There is a " + hv.keyChar + " in the word";
}
else if(word.indexOf(hv.keyChar)==-1 && (hv.keyChar >= 'a' && hv.keyChar <= 'z')) {
letterGuessed = "No " + hv.keyChar + " in the word";
guesses++;
System.out.println(guesses);
}
else{
letterGuessed = "Not a valid letter";
}
return letterGuessed;
}
public void newGame() {
hv.createNotification(this, size);
guesses = 0;
System.out.println(word);
}
}
Here is how the logic of how to replace the appropriate dash with the correct user guess might look
public static String guessNotification(String word, char userGuess, StringBuilder dashes) {
int guessedIndex = word.indexOf(userGuess);
if (guessedIndex != -1 && (userGuess >= 'a' && userGuess <= 'z')) {
letterGuessed = "There is a " + userGuess + " in the word";
dashes.setCharAt(guessedIndex*3+1, userGuess);
}
else if (guessedIndex == -1 && (userGuess >= 'a' && userGuess <= 'z')) {
letterGuessed = "No " + userGuess + " in the word";
guesses++;
}
else {
letterGuessed = "Not a valid letter";
}
return letterGuessed;
}
Comments are all correct. But you may want to see example code: Add an array of correct guesses:
char[] correct = new char[26]; // or more, depends on whether u use non ascii chars
Initialize the array with e.g. ' '. Then replace the dashes:
StringBuilder guessedPart = new StringBuilder;
for (int lc = 0; lc < word.lenght(); lc++) {
for (char c : correct)
if (word.indexOf(lc) = c) guessedPart.append(c);
if (guessedPart.length() < lc) guessedPart.append('_');
String guessedWord = guessedPart.toString();
That should do.

easier way to find vowels and print them? JAVA

Hey this is my first time posting! I got my program to print out the vowels from an input from user but I feel like I have repeated myself a lot in the for loop. Is there a quicker way to do this? Also is this code readable and in the correct format?
import java.util.Scanner;
public class Task09 {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String vowels ="";
//input from user
String answer= input.next()
//loop to find vowels
for(int i = 0 ;i<answer.length();i++)
{
char answerPosition = answer.charAt(i);
//checks if there are vowels in code
if (answerPosition =='a'
||answerPosition =='e'
||answerPosition =='i'
||answerPosition =='o'
||answerPosition =='u'
||answerPosition =='A'
||answerPosition =='I'
||answerPosition =='O'
||answerPosition =='U')
{
vowels += answerPosition + " ";
}
}
System.out.println("The vowels are:" + vowels);
input.close();
}
}
Try this:
String newString = answer.replaceAll("[^AaeEiIoOuU]", "");
System.out.println(newString);
You wont need for loop as well and your code would be compact and sweet.
You could do:
if ( "aeiouAEIOU".indexOf(answerPosition) >= 0 ) {
vowels += answerPosition + " ";
}
inside the loop.
Additionally, as a matter of style, you might write the iteration slightly differently:
for (char c: answer.toCharArray()) {
if ( "aeiouAEIOU".indexOf(c) >= 0 ) {
vowels += c + " ";
}
}
You can do this way too.
import java.util.Scanner;
public class Hi {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String vowels = "";
// input from user
String answer = input.next();
// loop to find vowels
for (int i = 0; i < answer.length(); i++) {
char answerPosition = answer.charAt(i);
char tempAnsPos = Character.toUpperCase(answer.charAt(i));
// checks if there are vowels in code
if (tempAnsPos == 'A' || tempAnsPos == 'E' || tempAnsPos == 'I' || tempAnsPos == 'O' || tempAnsPos == 'U') {
vowels += answerPosition + " ";
}
}
System.out.println("The vowels are:" + vowels);
input.close();
}
}

if else statements returning null with boolean operator

this is my first time making a question so I'm not sure if my title is correct at all because I'm pretty new to java... basically my program is returning all null during the changeNameFormat method when there is no space in the name but what I want it to do is to print out "You do not have a space in your name" and then move onto the next method. Currently my code is as follows, and logically to me at least it makes sense, but I'm no expert.
import java.util.*;
public class Lab11 {
static String name, first, last, word;
static boolean space;
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
System.out.println("Input your name: ");
name = input.nextLine();
changeNameFormat();
if (space = true) {
System.out.println("Your name is : " + first + " " + last);
System.out.println("Your first name is : " + first);
System.out.println("Your last name is : " + last);
}
else {
System.out.println("Your name contains no spaces");
}
System.out.println("Input word for palindrome test: ");
word = input.nextLine();
if (palindrome(word)) {
System.out.println(word + " is a palindrome");
}
else {
System.out.println(word + " is NOT a palindrome");
}
}
public static void changeNameFormat() {
if (name.contains(" ")) {
String [] split = name.split(" ", 2);
first = split[0];
String last = split[1];
space = true;
}
else {
space = false;
}
}
public static boolean palindrome(String w) {
System.out.println("Checking if " + word + " is a palindrome.");
System.out.println("... Loading...");
String reverse = "";
for (int i = w.length() - 1 ; i >= 0 ; i--) {
reverse = reverse + w.charAt(i);
}
if (w.equalsIgnoreCase(reverse)) { // case insensitive check
return true;
}
else {
return false;
}
}
}
A very small mistake out of negligence.
You have used a single equals assignment operator (=), which assigns true to space. If you want to check whether space is true, you need the double equals comparison operator (==):
if (space == true)
Note that a better, more idiomatic way of writing this is:
if (space)
Also your ChangeNameFormat() method localizes the last variable, in case you haven't noticed.

Categories