Java Binary search tree implementation - java

import java.util.Scanner;
import java.util.Stack;
public class Stack_1 {
public static void main(String[] args) {
String val;
Scanner input = new Scanner(System.in);
System.out.println("Enter Text: ");
val = input.nextLine();
push(val);
}
public static void push(String str) {
Stack<Character> stk = new Stack<Character>();
for (int i = 0; i < str.length(); i++) {
stk.push(str.charAt(i));
}
System.out.println(stk);
String reverseString = "";
String original = "";
int length = original.length();
for (int i = length - 1; i >= 0; i--)
reverseString = reverseString + original.toUpperCase().charAt(i);
if (original.toUpperCase().equals(stk))
System.out.println("The string is a palindrome.");
else if (reverseString.toUpperCase().equals(stk))
System.out.println("The string is not a palindrome.");
}
}
Can anyone help me out. I didn't know where I went wrong. The question was to create a stack (Character), and display the text where it is a palindrome or not. The user had to enter input.
P.S This was one of my lab test.

If I followed the code correctly, the problem appears to be that the OP is comparing a String object (either original or reverseString) to Stack<Character> object.
So, the probable failure is the incorrect attempted comparison of a String object to a Stack object.
I think there is a 2nd failure in the if/else if logic given that an example input of "cool" is not a palindrome, but no output is produced in such a case.
EDIT: while the OP code does attempt to adjust for the case of the entered data (not given in the question as to whether that is a requirement or not), it does not account for spaces or other punctuation. According to the entry on Wikipedia about Palindromes, punctuation is also usually ignored. Again, whether being concerned about spaces, periods, dashes, etc. was part of the exercise is not defined in the question. The question is a bit under specified in terms of full requirements.
I would think a solution using a stack would take a String, push it by character to a Stack (probably correcting for case and stripping out all punctuation at that time), and then do a comparison by popping from the Stack. I think the OP code is missing part of the requirement in using a Stack.
Example code to have only characters on the Stack. There are other approaches, of course:
// push by character onto the stack; use only
// characters, and convert to lower case
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ) {
stk.push(Character.toLowerCase(c));
}
}
Example to remove all non characters from a check String:
// convert out comparison String to lower case and remove
// all non letters
String chk = str.toLowerCase().replaceAll("[^a-z]", "");
Example loop to use the Stack to check against the String:
// assume we have a palindrome
boolean palindrome = true;
// counter across the String
int i = 0;
// loop while there is more on the stack and we haven't
// failed our test
while (! stk.isEmpty() && palindrome) {
Character c = stk.pop();
palindrome = (c == chk.charAt(i++));
}
Sample Test Data:
cool is a palindrome: false
mom is a palindrome: true
Never odd or even is a palindrome: true
A man, a plan, a canal - Panama! is a palindrome: true

Related

charAt(0) Not returning first number but second

Piglatin translator. at the end I am trying to get the location of the first vowel. Index is set to be the location of every vowel, but with pig latin you only need the location of the first vowel. When I run the program I don't always get the location of the first vowel. it seems to give me the second number and not the first.
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Assignment_4_Piglatin {
public static void main(String[] args) {
Scanner userWord = new Scanner(System.in);
System.out.println("K. Caleb Swallow");
System.out.println("Welcome to the Pig Latin Translator!");
boolean run = true;
while (run) {
System.out.println("Please enter a word(or press Q to quit):");
String firstLetter = "something";
String firstVowel = "test";
String word = userWord.next();
String vowels = "aeiou";
if (word.equals("Q")) {
System.exit(0);
}
firstLetter = Character.toString(word.charAt(0));
if (firstLetter.equals("a") || firstLetter.equals("e") || firstLetter.equals("i") || firstLetter.equals("o") || firstLetter.equals("u")) {
System.out.println(word + "way");
} else {
for (int index = 0; index < word.length(); index++) {
if (vowels.contains(String.valueOf(word.charAt(index)))) {
System.out.print(index);
String firstNumber = Integer.toString(index);
firstVowel = Character.toString(firstNumber.charAt(0));
}
}
}
System.out.println(firstVowel);
The example seems to have some redundant code in if..else condition. If you want to print the first vowels then you can do it with a simple for loop, e.g.:
String word = userWord.next().toLowerCase();
String vowels = "aeiou";
for(int i=0 ; i<word.length() ; i++){
if(vowels.contains(String.valueOf(word.charAt(i)))){
System.out.println(word.charAt(i));
break;
}
}
Please note that you need to do toLowerCase on the actual word in order for contains to work.
There are a few problems I can see off the bat, but the one that is likely causing this error is in these lines:
String firstNumber = Integer.toString(index);
firstVowel = Character.toString(firstNumber.charAt(0));
Think about what this is doing. First, you are making a String out of the index value, then you are saying that the first vowel is at the 0th index of that string.
Think of this example: hello
The program will run and assign "4" to firstNumber and firstVowel which isn't what you want.
However, if you only have one vowel, your program will "work".
What happens if you have over ten vowels? I know this isn't a realistic example, but say it happens. Your program will assign the index of the last vowel to firstNumber (say it's 15), then it will assign the first character of that to firstVowel (1). This doesn't make much sense at all, does it, especially if you don't have a vowel in index 1.
The main problem you are encountering for words less than 10 letters in length is that you are not just outputting the second number, you are outputting the last one. One way I like to deal with this is to go through the code and put in print statements where I'm not sure what a certain value is. For example, I'd put another print statement in your loop which tells you what letter you're looking at, like so:
System.out.println("LETTER: "+ String.valueOf(word.charAt(index)));
This will help you avoid confusion. The proper way to do this problem would be to use a break statement, such as in Darshan's answer. Alternatively, you could use the properties of the for loop:
firstVowel = "";
for (int index = 0; index < word.length() && firstVowel == ""; index++) {
CODE
}
Note that the second part of the for loop is a conditional statement. You already know that this can be used to cycle through the word's characters, but you can insert any logical statement there that you want. For this example, I set the default value of firstVowel to "" (setting it to null is a faux-pas, but that's another story). Then, each time the loop runs, it checks to see if the value of firstVowel has been changed, which will of course happen on the first time a vowel is run through the loop.
So in short, you need to modify the two lines at the beginning of my post and you need to find a way to break your loop when you find the first vowel. One solution has been given here, and another in Darshan Mehta's post.
public static void main(String[] args) {
Scanner userWord = new Scanner(System.in);
System.out.println("K. Caleb Swallow");
System.out.println("Welcome to the Pig Latin Translator!");
boolean run = true;
while (run) {
System.out.println("Please enter a word(or press Q to quit):");
String firstLetter = "something";
String firstVowel = "test";
String word = userWord.next();
ArrayList<Character> vowels = new ArrayList<>();
vowels.add('a');
vowels.add('e');
vowels.add('i');
vowels.add('o');
vowels.add('u');
if (word.equals("Q")) {
System.exit(0);
}
firstLetter = Character.toString(word.charAt(0));
if (firstLetter.equals("a") || firstLetter.equals("e") || firstLetter.equals("i") || firstLetter.equals("o") || firstLetter.equals("u")) {
System.out.println(word + "way");
} else {
for (int index = 0; index < word.length(); index++) {
char indchar = word.charAt(index);
if (vowels.contains(word.charAt(index))) {
System.out.println(index);
firstVowel = Character.toString(word.charAt(index));
System.out.println(firstVowel);
index = word.length();
}
}
}
}
}
This is how I would do it. I changed the vowels String to an ArrayList so you can easily check if the char in the String word with the index is a vowel and the code works absolutely fine. It returns you the index where the first vowel is and what vowel it is.

Palindrome Recognizer

I'm learning Java. I'm building this Palindrome recognizer and using two arrays with chars, I think I got a good implementation with other things I've found around but I'm breaking my head to understand why it's not working as intended so far. What is happening:
"A Santa at Nasa", palindrome, checks as a palindrome.
"I don't know, anything", not a palindrome, checks as not a palindrome.
"Not a palindrome", not a palindrome, checks as a palindrome.
I basically need some help to understand where exactly I got it wrong on my code. Thanks!
/*
"A Santa at Nasa" is an example of palindrome.
*/
import java.util.Scanner;
public class Palindrome
{
public static void main (String[] args)
{
boolean isPalindrome = false;
Scanner kb = new Scanner(System.in);
System.out.println("Enter a string:");
String userInput = kb.nextLine();
userInput = userInput.trim().replaceAll(" ", "").toLowerCase();
char[] array = new char[userInput.length()];
char[] reverseArray = new char[userInput.length()];
int i = 0;
int j = userInput.length();
do {
i++;
j--;
array[i] = userInput.charAt(i);
reverseArray[j] = userInput.charAt(j);
if (array[i] != reverseArray[j])
{
isPalindrome = false;
}
else
{
isPalindrome = true;
}
} while (j > i);
if(isPalindrome)
{
System.out.println("It's a palindrome.");
}
else
{
System.out.println("Not a palindrome.");
}
}
}
Once you've established that the input is not a palindrome, you should end the test.
Currently your algorithm is allowed to change its mind!
You are also incrementing i prematurely.
Here's the problem, you must start before the first element of the input array, because you do a i++ at the beginning of your loop:
int i = -1;
Also, the exit condition of your loop can be improved, so it exits earlier:
while (j > i && !isPalindrome);
Are you allowed to use StringBuilder? If so, you can do String reverseText = new StringBuilder(userInput).reverse().toString();
If not, why not try iterating through the array once and then compare at the end? Leave your array and reverseArray initializers as they are, but then do a for or while loop after that just faithfully copies from the userInput variable into the correct locations in both the arrays.
Then you can just use a single comparison at the end to decide what to print.
A couple things.
You should do your index changes at the end of your loop, to fix starting the lower index from 1.
With the previous change, you should start your upper index from userInput.length()-1 as that will then be the first index from the top that you check.
You should stop when you find one mismatch, as otherwise with a string of odd length, your result will always be the check of the middle character against itself (and otherwise your result will end up being the check of the two middle characters of an even string against each other).
If you'd like the full re-worked solution, I can post it, but you can probably fix it yourself from here!
Well, the problem is that you set your isPalindrome every time you check two letters. So when the last 2 letters checkt are the same, it will say it is a palindrome. Instead try this:
import java.util.Scanner;
public class Main
{
public static void main (String[] args)
{
boolean isPalindrome = true;
Scanner kb = new Scanner(System.in);
System.out.println("Enter a string:");
String userInput = kb.nextLine();
userInput = userInput.trim().replaceAll(" ", "").toLowerCase();
char[] array = new char[userInput.length()];
char[] reverseArray = new char[userInput.length()];
int i = 0;
int j = userInput.length() - 1;
while(i < j && isPalindrome) {
array[i] = userInput.charAt(i);
reverseArray[j] = userInput.charAt(j);
if (array[i] != reverseArray[j])
isPalindrome = false;
i++;
j--;
}
if(isPalindrome)
System.out.println("It's a palindrome.");
else
System.out.println("Not a palindrome.");
}
}
So now the isPalindrome boolean is set to true in the beginning, and when we find something that contradicts this (two characters that are not the same) it will set isPalindrome to false.
I have not tested this code, so there could be some other error. But this is the one I saw at first glance.
EDIT: i didn't start from the beginning of the string. And best to use a while instead of do while because the string could be empty.

How to reduce character from given String until it becomes to palindrome in java

Here i have code to check whether given string is palindrome or not but don't know the procedure to reduce characters from last.To make change the character i need to follow the rule as: Eg String input="abcde".Letter 'e' can be converted to 'd' but not 'e' to 'd' if character becomes 'a' we can't change further.Here is my code:
public static void main(String[] args) {
String input = "abcd";
String temp = input;
String output = "";
for (int i = output.length() - 1; i >= 0; i--) {
output = output + output.charAt(i);
}
if(temp.equals(output)){
System.out.println("String is palindrome");
}else{
System.out.println("Not a palindrome");
}
}
output order logic is as follows:
if input is =abcd
abcc('d' converted to 'c')and check for palindrome
abcb('c' converted to 'b')and check for palindrome
abca('b' converted to 'a')and check for palindrome
abba('a' further we can't change so shift to previous letter 'c' and change to 'b')
and check for palindrome
String is palindrome and count is=4
if input=cbdf
cbde('f' converted to 'f')and check for palindrome
cdbd('e' converted to 'd')and check for palindrome
cdbc('d' converted to 'c')and check for palindrome
cdbb('c' converted to 'b')and check for palindrome
cdba('b' converted to 'a')and check for palindrome
cdaa('a' further we can't change so shift to previous letter 'b' and change to 'a')
and check for palindrome
ccaa('a' further we can't change so shift to previous letter 'd' and change to 'c')
and check for palindrome
cbaa('c' converted to 'b')and check for palindrome
caaa('a' further we can't change so shift to previous letter 'c' and change to 'b')
and check for palindrome
baaa('b' converted to 'a')and check for palindrome
aaaa now string is palindrome
String is palindrome and count is=10
finally i need the count to make string palindrome.
Assuming that I understand your problem, you are going about this in an inefficent way. Here is how I would do this:
String toPalindrome(String str){
StringBuilder reverse = new StringBuilder(str).reverse();
for(int idx = 0; idx < str.size()/2; idx++)
if(str.getCharAt(idx) < reverse.getCharAt(idx))
reverse.setCharAt(idx, str.getCharAt(idx));
return reverse.subString(0,str.size()/2) + reverse.reverse().subString(str.size()/2);
}
Aside from the off-by-one errors in this code, this should work to produce the output you need.
Using this approach, we don't have to decrement each character one by one - we rather just immediately replace each character with the target value. We also never have to check if it is a palindrome, since this method is guaranteed to produce one (after all, it is concatenating a string with its mirror image in the return step).
EDIT: seeing that we need only return the number of times characters were decremented, we can do something even simpler:
int abs(int x){
return x>0?x:-x;
}
int palindromeCounts(String str){
int count = 0;
for(int idx = 0; idx < str.length()/2; idx++)
count += abs(str.charAt(idx) - reverse.charAt(str.length()-1-idx));
return count;
}

Password w/ Specific Requirements Program

I'm currently doing an assignment for my Java programming class.
The question in the book asks for the user to create a program that uses the JOptionPane boxes to ask the user for a password. The password has to be between 6 and 10 characters, and have at least one digit, and one letter. Once this requirement is met, ask the user to verify their password. If their second input doesn't match the first, ask the original question again. Once both inputs match, display a message saying "success!".
I've gotten mine to the point where it checks for the number of characters, but I can't for the life of me, figure out how to check for digits and letters also. I've tried nested for loops that search for digits and letters, but I can't figure out a way to make it bypass the length requirement when it doesn't have a number or letter. This is my current code.
import javax.swing.JOptionPane;
class Password{
public static void main(String[] args){
String input1 = "";
String input2 = "";
int inputLength;
do{
do{
input1 = JOptionPane.showInputDialog(null, "Enter your password\nIt must be 6 to 10 characters and\nhave at least one digit and one letter");
inputLength = input1.length();
}while(inputLength < 6 || inputLength > 10);
input2 = JOptionPane.showInputDialog(null, "Verify Password");
}while(!(input1.equals(input2)));
JOptionPane.showMessageDialog(null, "Success!");
}
}
You can deal with regular expression.
(?=.*\d) mean at last one digit in the word
(?=.*[a-zA-Z]) mean at least one letter
{6,10} mean between 6 and 10 characters
So the correct regex is ((?=.\d)(?=.[a-zA-Z]).{6,10})
Now look at the `.matches(String regex) method of String :)
If you can't use regex :
Get the CharArray (input1.toCharArray()) and iterate.
For each char, check if it's a number or a character
Keep 2 boolean (for exemple num and alpha) and set them to true when you see a number of a character
Then, look at you flag, and then test this
num && alpha && inputLenght > 6 && inputLenght < 10
Edit:
You can use Character.isLetter() and Character.isDigit(), i think you have enough informations now !
Figured it out! I ended up adding two while loops to check for digits and letters inside of the inner do loop. I set the while loops to make the boolean expressions false if the correct thing is found (I know, it seems backwards). But it makes it so the do loop will not run again if the correct characters are found. Thank you to everyone that posted, it really helped clear things up!
Here's the completed code:
import javax.swing.JOptionPane;
class Password{
public static void main(String[] args){
String input1 = "";
String input2 = "";
int inputLength;
boolean isDigit = true;
boolean isLetter = true;
char c = ' ';
char d = ' ';
int x = 0;
do{
do{
input1 = JOptionPane.showInputDialog(null, "Enter your password\nIt must be 6 to 10 characters and\nhave at least one digit and one letter");
inputLength = input1.length();
while(x < input1.length()){
c = input1.charAt(x);
if(Character.isDigit(c)){
isDigit = false;
break;
}
x++;
}
x = 0;
while(x < input1.length()){
d = input1.charAt(x);
if(Character.isLetter(d)){
isLetter = false;
break;
}
x++;
}
}while(inputLength < 6 || inputLength > 10 || isDigit || isLetter);
input2 = JOptionPane.showInputDialog(null, "Verify Password");
}while(!(input1.equals(input2)));
JOptionPane.showMessageDialog(null, "Success!");
}
}

How do I count the number of words in a string?

I need to count the number of words and I am assuming the correct way to do it is by calculating the number of times that the previous character in a string is not a letter (ie other characters) because this is to assume that there would be colons,spaces,tabs, and other signs in the string.
So at first my idea was to loop through each character and count how many times that you will not get a letter of an alphabet
for(int i = 0; i < string.length(); i++) {
for(int j = 0; i < alphabets.length(); j++) {
if (string.charAt(i-1) == alphabets.charAt(j)) {
counter++;
}
}
}
However I will always get an array out of bounds because of this. So, I kinda need a little help or another way that can actually be more efficient.
I thought of using Matches to only [a-zA-z] but I'm not sure how do I handle a char to be comparable to a string in counting how many times it occurs.
Thank you
You can use String.split() to convert the string into an array, with one word in each element. The number of words is given by the length of the array:
int words = myString.split("\s+").length;
Your suggestion to use a regex like "[A-Za-z]" would work fine. In a split command, you'd split on the inverse, like:
String[] words = "Example test: one, two, three".split("[^A-Za-z]+");
EDIT: If you're just looking for raw speed, this'll do the job more quickly.
public static int countWords(String str) {
char[] sentence = str.toCharArray();
boolean inWord = false;
int wordCt = 0;
for (char c : sentence) {
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
if (!inWord) {
wordCt++;
inWord = true;
}
} else {
inWord = false;
}
}
return wordCt;
}
This problem is slightly more complicated than your algorithm allows.
What if there are two or more spaces in a row?
What if the string starts or ends with whitespace (or non-word characters)?
This looks like homework, so I don't want to provide any code. I suggest an alternative approach which is simpler to think about.
Walk through the characters in the string, one by one.
Do something to remember if you are currently scanning a word or if you are not currently scanning a word.
Do something to determine when you enter or leave a word, and increment your counter accordingly.
The reason you are getting an IndexOutOfBoundsException is probably because when i is 0 your inner loop will have string.charAt(i-1) which will throw an exception since 0-1 is -1. If you fix that your method might work, although you can use more efficient techniques.
Addressing the code directly, your first loop has i=0 as the first value of i, but then you ask for
string.charAt(i-1) = string.charAt(-1),
which is where your array-out-of-bounds is coming from.
The second loop has another problem:
for(int j = 0; i < alphabets.length(); j++) {
You may also want to consider apostrophes as parts of words as well.
Use just like this
String s = "I am Juyel Rana, from Bangladesh";
int count = s.split(" ").length;
if (string.charAt(i-1) == alphabets.charAt(j)) {
counter++;
}
You are incrementing the counter if the character is some alphabet character. You should increment it if it is no alphabet character.
The following program will count the number of words in a sentence. In this program, we are counting alphabets just after space. The alphabet can be of lower case or upper case. We are inserting a space at the beginning since people don't start a sentence with space. We also need to take care that any special character or number should not be counted as a word.
`import java.util.Scanner;
public class WordSent {
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
System.out.println("Enter the sentence");
String str=in.nextLine();
String space=" ";
String spaceword=space.concat(str);
int count=0;
for(int i=0; i<spaceword.length()-1;i++)
{
for (int k=0; k<=25; k++)
{
if(spaceword.charAt(i)==' '&& (spaceword.charAt(i+1)==((char)(65+k)) || spaceword.charAt(i+1)==((char)(97+k))))
{
count++;
}
}
}
System.out.println("Total number of words in a sentence are" +" : "+ count);
}
}`

Categories

Resources