Java app to check anagram using for loop and if statement - java

I'm working on another coding task for university. I am having trouble using a for loop (with another for loop and an if statement) to take a String parameter, and reorder it in alphabetical order. The task then requires us to check two phrases against each other to check if the phrases are anagrams. The loop is the bit I am stuck with. My for loop should output the first phrase in alphabetical order, but my if statement is not functioning as intended. The boolean statement is incorrect but I am unsure what I should be checking the phrase.charAt(i) against to record the letter.
We are not permitted to use an array to complete this task.
import java.util.Scanner;
public class AnagramApp {
/**Method to reformat string in alphabetical order**/
public static String orderString(String phrase){
String output = "";
for (char alphabet = 'a'; alphabet <='z'; alphabet ++ ){
for (int i = 0; i < phrase.length(); i++){
if (phrase.charAt(i) == i){
output += phrase.charAt(i);
}
}
}
return (output);
}
public static void main(String [] args){
/**Setting scanner object to retrieve user input for both phrases **/
Scanner sc = new Scanner(System.in);
System.out.println("Enter first phrase");
String phrase1 = sc.nextLine();
System.out.println("Enter second phrase");
String phrase2 = sc.nextLine();
/**Send phrases to lower case for parsing to new string in char order**/
phrase1 = phrase1.toLowerCase();
phrase2 = phrase2.toLowerCase();
System.out.println(orderString(phrase1));
System.out.println(orderString(phrase2));
}
}

I think the problem is that you are comparing with the index of the inner loop, i, you want to compare with the index of the outer loop, alphabet.
if (phrase.charAt(i) == alphabet)

change condition in if statement to if (phrase.charAt(i) == alphabet)
or you can use below function to check two string anagram
boolean checkAnagram(String st1, String st2)
{ int arr[]=new int[26];
int l1=st1.length();
int l2=st2.length();
if(l1!=l2){
return false;
}
for(int i=0;i<l1;i++){
arr[st1.charAt(i)-97]+=1;
arr[st2.charAt(i)-97]-=1;
}
for(int i=0;i<25;i++){
if(arr[i]!=0) return false;
}
return true;
}

Related

Java - word scrambler [keeping first and last letter]

My assignment is to write a program to scramble a word while maintaining the same first and last letter and only swapping two letters, then prompt the user to continue if they wish.
Example: userInput = bacon | Output = bcaon
I've attached an imagine of my program, there may be several issues, but as it stands I can't really run it due to the errors in the image. I'm really confused because I got a TA to help me on this assignment, and they seemed to think this would definitely work, but as you can see it does not.
I would really appreciate if someone could tell me what exactly is wrong and why. And if you have anything to add to make this program work, I'd really, really appreciate that too, but bottom line is I just want to understand what's wrong and why.
import java.util.Scanner;
import java.util.Random;
public class FreeStyle {
public static void main(String[] args) {
Scanner in = new Scanner(System.in); // Importing and initializing keyboard to 'in'
System.out.println("Please enter a word to be scrambled"); // Asking user for a word
String word = in.next(); // Initializing the user's input
System.out.println(swapLetters(word));
System.out.println("Would you like to enter another word? y/n");
String answer = in.next();
boolean userDone = true; //Using a Boolean statement to ask the user if they are done enter words or not
while (userDone) {
if (answer.equals('y')) {
System.out.println("Please enter a new word"); //Ask user for new word to scramble
word = in.nextLine(); //New initialization for 'word'
} else if (answer.equals('n')) { //If user types 'n', loops then breaks because while(userDone) is false
userDone = false;
} else {
System.out.println("Invalid input, please enter more than 3 letter words."); // The logic doesn't flow or apply to words that are less than 4 letters, so this catches that error and notifies the user
}
}
}
private static String swapLetters(String word) { //Private method used for the program only, no need to involve the user
Random r = new Random(); //Using random instead of math floor
//int arraysize = word.length();
int a = r.nextInt(word.length()-2)+1;
int b = r.nextInt(word.length()-2)+1;
//String word2 = word.substring(a, a+1);
String word2 = word.substring(0, a) + word.charAt(b)+word.substring(a+1, b)+word.charAt(a)+word.substring(b+1);
return word2;
}
Several points:
Why not use something already done exactly for what you are trying to do - Collections.shuffle? See comments in the code for understanding how it works.
You can't use equals() between a String and a char (' ' are for chars, " " are for Strings). Simple fix - just put your 'y' into "y", same for 'n'.
I've refactored the code at the beginning that we used to get user input and then scramble into a separate method, so we can reuse it again - getInputAndScramble.
And finally, I've used a do-while loop to keep looping until the user stops the loop with the "n" letter.
Please see my comments in the code, hopefully will clear things up.
public class Scrambler {
public static void main(String[] args) {
boolean userDone = true;
String word;
Scanner in = new Scanner(System.in);
getInputAndScramble(in); //Extracted method to get Scanner input and scramble
do {
System.out.println("Would you like to enter another word? y/n");
word = in.next();
while (userDone) {
if (word.equals("y")) {
getInputAndScramble(in);
break;
} else if (word.equals("n")) {
userDone = false;
} else {
System.out.println("Invalid input, please enter more than 3 letter words.");
}
}
} while (userDone); //continue until "n"
}
private static void getInputAndScramble(Scanner in) {
System.out.println("Please enter a word to be scrambled");
String word = in.next();
System.out.println(swapLetters(word));
}
private static String swapLetters(String word) {
/* Convert word into an ArrayList of characters.
Create ArrayList size of word,
convert String word into a char array and insert every char in
the char array into our ArrayList.
*/
ArrayList<Character> chars = new ArrayList<>(word.length());
for (char c : word.toCharArray()) {
chars.add(c);
}
//Shuffle, omitting first and last letters
Collections.shuffle(chars.subList(1, chars.size()-1));
//Add shuffled letters into an array to output as a word entity
char[] shuffled = new char[chars.size()];
for (int i = 0; i < shuffled.length; i++) {
shuffled[i] = chars.get(i);
}
//Return shuffled String
return new String(shuffled);
}
}
You are assuming that the two random number a and b have the property that a < b. What if a >= b? Then word.substring(a+1, b) will throw an error.
To fix it, just make sure that a < b is maintained (regenerating, swapping, etc.).
But to be sure, there are more than just this bug in your code. For example, using next(), comparing String with char, using wrong newline character, not striping newline character, and so on. You might want to add some print statements in your code you see what is actually happening.
Well, as for the swapping function, something like that should work:
private static String swapLetters(String word) {
char[] temp = word.toCharArray();
char swapHelper;
Random r = new Random();
int a = r.nextInt(word.length()-2)+1;
int b = r.nextInt(word.length()-2)+1;
swapHelper = temp[a];
temp[a] = temp[b];
temp[b] = swapHelper;
word = String.copyValueOf(temp);
return word;
}
Basically, im converting string to char array so i can operate on them with ease. A and B are variables that contain index of letters that should be swapped. After that, array is converted back to string and returned.

How to make arrayList read Strings only but not int?

Write a method called countWords that accepts an ArrayList of String as argument and
prints out the number of words (i.e. Strings) that start with ―A‖ or ―a‖ and prints all words longer than 5 characters on one line.
My solution is like
int count=0;
String[] st=null;
Scanner input=new Scanner(System.in);
ArrayList<String> array = new ArrayList<String>();
System.out.println("please input something");
while(input.hasNext()) {
String st1=input.next();
array.add(st1);
}
for(int i=0; i<array.size();i++) {
if(array.get(i).startsWith("a")||array.get(i).startsWith("A")) {
count++;
}
}
for(int j=0; j<array.size(); j++) {
if(array.get(j).length()>5)
st[j]=array.get(j);
}
System.out.println(count);
System.out.println(st);
}
but there will be no end for typing in Strings
As the last line of your question said
but there will be no end for typing in Strings
Well That is because you did not provided any way to end the while loop.
while(input.hasNext())
Will run forever and ever waiting for next user input. You have to break the while loop once the inputting is done.
AFTERWARDS
As the question said "prints out the number of words that start with A or a and prints all words longer than 5 characters on one line."
For this you can loop through the ArrayList and check for
if(array.get(i).startsWith("A") || array.get(i).startsWith("a")) count++;
if(array.get(i).length()>5) System.out.print(array.get(i)+" ");
and print the number of A or a Occurrence after the loop
System.out.println("\n Number of word with A or a:"+count);
Here is a working implementation of your code
public static void main(String[] args) {
int count=0;
String[] st=null;
Scanner input=new Scanner(System.in);
ArrayList<String> array = new ArrayList<String>();
System.out.println("please input something");
//System.out.println(input.hasNext());
while(input.hasNext()) {
String st1=input.next();
//System.out.println((int) st1.charAt(0));
if(st1.equals("exit")) break;
array.add(st1);
}
for(int i=0; i<array.size();i++) {
if(array.get(i).startsWith("A") || array.get(i).startsWith("a")){
count++;
}
if(array.get(i).length()>5) {
System.out.print(array.get(i)+" ");
}
}
System.out.println("\nNumber of word with A or a:"+count);
}
to end the loop you have to type exit.
Here is a solution to your problem..
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String... args){
// Sample String sentence
String sentence = "This is the sentence with 5 words starting with
all like allwords alltogether also Allnotout allother and allofus.";
// Splitting above sentence to get each word separately and storing them into List
List<String> strings = Arrays.asList(sentence.split("\\s+"));
// calling a method named countWord() as per your assignment question.
Test.countWords(strings);
}
// implementing that method
static void countWords(List<String> input){
long count = input.stream().filter(word -> word.startsWith("all") || word.startsWith("All")).count();
System.out.print("Total words starting with all/All are : "+ count +"\t");
input.stream().filter(word -> word.length() > 5).forEach( word -> System.out.print(word + "\t"));
}
}

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.

Hangman game error

i have written this code that is a hangman game
however the code keeps running when the user enters all the letters unless i write the word so it congrats the user.
i want it to stop when the user inputs all correct letters
import java.util.Scanner;
public class question6 {
public static void main(String[] args) {
String str = "testing";
boolean[] strBoolean = new boolean[str.length()];
Scanner input = new Scanner(System.in);
String test = "";
int counter = 1;
System.out.println("Java word guessing testing");
// main for loop for guessing the letters
while(true){
System.out.println("Key in one word character or your guessed word:");
test = input.nextLine();
if(test.equals(str)){
System.out.println("Congratulation!");
break;
}else{
// for loop for checking the boolean array
for(int b=0; b<strBoolean.length; b++){
if(str.charAt(b) == test.charAt(0)){
strBoolean[b] = true;
}
}
// for loop for printing the correct letters
System.out.print("Trail "+counter+": ");
for(int j=0; j<str.length(); j++){
if(strBoolean[j] == true){
System.out.print(str.charAt(j));
}else{
System.out.print("_");
}
}
System.out.println();
counter++;
}
}
}
}
First off, you are using attempting to compare your String test to the String str, but since you accept new user input for test before the you make that comparison, that conditional will only ever be true if the user types in "testing". So make sure you keep track of the ordering in your instructions in the program for future cases.
You are keeping track of the user's progress by using an array of boolean values. Thus, you could create a method that checks if all the values in said array are true, and return true if so. See example:
import java.util.Scanner;
public class question6 {
public static void main(String[] args) {
String str = "testing";
boolean[] strBoolean = new boolean[str.length()];
Scanner input = new Scanner(System.in);
String test = "";
int counter = 1;
System.out.println("Java word guessing testing");
// main for loop for guessing the letters
while(true){
if(allTrue(strBoolean)){
System.out.println("Congratulation!");
break;
}else{
System.out.println("Key in one word character or your guessed word:");
test = input.nextLine();
// for loop for checking the boolean array
//and the rest of your code
}
}
}
public static boolean allTrue (boolean[] values) {
for (int index = 0; index < values.length; index++) {
if (!values[index]){
return false;
}
}
return true;
}
}

out of bounds error with word count

I'm trying to write my own Java word count program. I know there may already be a method for this, but I'd like to get it work. I'm getting an out of bounds error at line 14. I'm trying to use an input word to count how many times it appears in an input string. So I'm looping up to stringlength - wordlength, but that's where the problem is.
Here is the code:
import java.util.Scanner;
public class wordcount {
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.print( "Enter word : " );
String word = s.nextLine();
Scanner t = new Scanner(System.in);
System.out.print("Enter string: ");
String string = t.nextLine();
int count = 0;
for (int i = 0; i < string.length()-word.length(); i = i+1){
String substring = string.substring(i,i+word.length());
if (match(substring, word)==true){
count += 1;
}
}
System.out.println("There are "+count+ " repetitions of the word "+word);
}
public static boolean match(String string1, String string2){
for (int i=0; i<string1.length(); i+=1){
if (string1.charAt(i)!=string2.charAt(i)){
return false;
}
}
return true;
}
}
First of all, two Scanners are not necessary, you can do many inputs with the same Scanner object.
Also, this if condition
if (match(substring, word) == true)
can be rewritten like
if (math(substring, word))
I would also recommend you to use i++ to increase the loop variable. Is not strictly necessary but is "almost" a convention. You can read more about that here.
Now, about theIndexOutOfBoundsException, I've tested the code and I don't find any input samples to get it.
Besides, there is an issue, you are missing one iteration in the for:
for (int i = 0; i < string.length() - word.length() + 1; i++) { // Add '+ 1'
String substring = string.substring(i, i + word.length());
// System.out.println(substring);
if (match(substring, word)) {
count++;
}
}
You can test it by putting a print statement inside the loop, to print each substring.
I'm not getting an out of bounds error, can you tell me what values you were using for word and string?
I have identified a bug with your program. If word is equal to string, it still returns count 0. I suggest adding one more iteration and using regionMatches instead. RegionMatches makes your match method obsolete and will return false if word.length() + i is equal or greater than string.length(), avoiding out of bounds issues.
As you can see I also moved the calculations to a seperate method, this will make your code more readable and testable.
And as Christian pointed out; you indeed do only need one Scanner object. I've adapted the code below to reflect it.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter word : ");
String word = sc.nextLine();
System.out.print("Enter string: ");
String string = sc.nextLine();
int count = calculateWordCount(word, string);
System.out.println("There are " + count + " repetitions of the word " + word);
}
private static int calculateWordCount(String word, String string) {
int count = 0;
for (int i = 0; i < string.length() - word.length() + 1; i++) {
if (word.regionMatches(0, string, i, word.length())) {
count++;
}
}
return count;
}

Categories

Resources