Square Free Word in Java - java

I'm stuck on creating a program to solve a question for a class. I have a main method and a secondary testing method that are working in conjunction to solve this problem, however I can't get the solution to work when there's a change.
The problem is making sure a word is square free, here's an excerpt from the problem:
For this part, implement a method called isSquareFree that takes as input (a reference to ) an array of characters. You may assume that the elements of the array are all lower case letters. (In other words, you do not need to worry about a question like: "is Z the same letter as z?") Your method should test if the given input array of characters is square-free. If it is, the method should print a message stating that, otherwise it should print a message stating that the world is not square-free, where the square subword starts and what that subword is. For example, if the given array contained the word zatabracabrac the method should print: The word, zatabracabrac, is not square free, since it has subword, abrac twice starting at position 4 of the word.
Below is the current code I have, it works in the case that there is a repeating character directly next to each other, but I'm unsure of how to continue to check if there is multiple repeating characters (abab for example) nor am I sure how to print out the repeating subword.
public static void main(String[] args) {
// part (a) of the main
Scanner keyboard = new Scanner(System.in);
System.out.println("***************************");
System.out.println(" Part (a)");
System.out.println("***************************");
do{
System.out.println("Enter a word and then press enter:");
String str=keyboard.next();
char[] word = str.toCharArray();
isSquareFree(word);
System.out.println("Do you want to test another word? Press y for yes, or another key for no");
}while(keyboard.next().charAt(0)=='y');
}
public static void isSquareFree(char[] word){
int sqf = 0;
for(int i=0; i<word.length; i++){
for(int j=0; j<word.length-1;j++){
if (word[j] == word[j+1]){
sqf = 1;
j = word.length;
}
else{
sqf = 2;
}
}
}
if (sqf == 1){
System.out.println();
System.out.println("Not Square Free");
}
else{
System.out.println();
System.out.println("Square Free");
}
}}
I'd also like to add that I'm not allowed to use the arrays class for this question, nor am I allowed to use strings and I cannot change the main method, not can I change the input for my other method.

To see if a sequence of characters repeats, for a given sequence length (say, n), you would replace your if with a loop that compares word[j+x] with word[j+n+x] for each value of x between 0 and n; and only consider them the same if all n match. Thus, you'd need to loop over these n values for x; if you need to consider different values of n, then you'd need yet another loop to go through those.
It isn't clear from your code what you are using i for, but if it is the length of the repeating part (what I've called n), then you'd only need to consider values up to half the length of word (or else there isn't room to repeat it).
To print out a sub word, you could print out each individual letter in order (using print instead of println)

Related

I am trying to write a recursive function that checks if one word matches the reverse word but im not sure if its recursion

All I really need to know is if the function I am using is recursive or if the method simply doesnt get called within itself.
In my code, I have a helper function to reverse the second word and I put a toLowerCase in order to be able to compare words even if there are any random capitals.
Is this recursion or is it just a function that compares the two?
import java.util.Scanner;
public class isReverse {
public static void main(String[] args) {
isReverse rev = new isReverse();
Scanner in = new Scanner(System.in);
System.out.println("Please enter a word: ");
String a = in.nextLine();
System.out.println("Please Enter a second word to compare: ");
String b = in.nextLine();
System.out.println(rev.isReverse(a, b));
}
String rev = "";
public boolean isReverse(String wordA, String wordB){
String fword = wordA.replaceAll("\\s+", "").toLowerCase();
String clean2 = wordB.replaceAll("\\s+", "").toLowerCase();
String reverse = revString(clean2);
if(fword.length() == 0){
return false;
}
if (fword.equals(reverse)){
return true;
}
if (!reverse.equals(fword)){
return false;
}
else
return isReverse(fword,reverse);
}
public String revString(String sequence) {
String input = sequence;
StringBuilder order = new StringBuilder();
order.append(input);
order = order.reverse();
rev = order.toString();
return rev;
}
}
As far as your question is concerned, your code is not behaving like a recursive function because your code is not entering into the last else condition. For recursion to work you need to have:
a base case(if there is no base case the recursion will go on forever)
a recursive case(this is where you kind of reduce the original problem)
But my comment about your code:
If you're doing the actual reverse logic you don't need to use recursion just to check if the original string and the reverse string are the same. These is purely an algorithm problem so here is the way to solve the problem:
If the length of the given input is 1 then the reverse is the same.
else:
check the first and last chars of the string, if they are equal, then you need to remove those two chars and check if the rest of the string is a palindrome. This is the actual recursive step.
else the string is not a palindrome.
Technically? Well, you are calling a method from within itself, so, technically, yeah.
Pragmatically? No. The recursive call part will never be invoked.
Your code does this: I have 2 words. If the words are equal to each other, stop and do something. if they are not equal to each other, stop and do something. Otherwise, recurse.
And that's where it falls apart: It'll never recurse - either the words are equal, or they are not.
The general idea behind a recursive function is three-fold:
The method (java-ese for 'function') calls itself.
Upon each call to itself, the parameters passed are progressing to an end state - they become smaller or trend towards a stop value such as 0.
There are edge cases where the function does not call itself, and returns instead (the answer for the smallest/zero-est inputs does not require recursion and is trivial).
You're missing the #2 part here. Presumably, this is what you'd want for a recursive approach. Forget about revString, delete that entirely. Do this instead:
If both inputs are completely empty, return true (That's the #3 - edge cases part).
If one of the two inputs is empty but the other one is not, false. (Still working on #3)
If the first character of the input string is NOT equal to the last character of the output string, false. (Still #3).
Now lop the first char off of the first input and the last off of the latter (Working on #2 now - by shortening the strings we're inevitably progressing towards an end no matter what)
now call ourself, with these new lopped-down strings (That'll be #1).
That would be a recursive approach to the problem. It's more complicated than for loops, but, then, recursive functions often are.
Actually this is not a recursing. All you need is just:
Check that both string have the same length
Iteratively check letters from 0 to n from the first string and from n to 0 from the second string. If they equal, then go to the next iteration (recutsion) or return fail otherqwise.
// here do not check signature of the public method
public static boolean isReverse(String one, String two) {
return isReverse(one, 0, two, two.length() - 1);
}
// support method has two additional counters to check letters to be equal
private static boolean isReverse(String one, int i, String two, int j) {
if (i == one.length())
return j == -1;
if (j == two.length())
return i == -1;
// if not equal, then strings are not equal
if (one.charAt(i) != two.charAt(j))
return false;
// go to the next recursion to check next letters
return isReverse(one, i + 1, two, j - 1);
}

removing the characters from a arraylist holding the alphabets based on the characters that appear in users input

I'm doing a project were I need to remove letters systematically from an ArrayList as they show up in the words that the user puts in. Then all the remaining characters are displayed and then the elimination process continues until only vowels are left.
I cant seem to get it to eliminate the characters without the program crashing.
Here's the problematic code:
public static void Mapper(){
Scanner make = new Scanner(System.in);
char Aphabets[] ={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
ArrayList<Character> Alpabets = new ArrayList<>();
String word = make.nextLine();
for (int i = 0; i < Aphabets.length; i++) {
Alpabets. add(i,Aphabets[i]);
}
for (int i = 0; i < word.length(); i++) {
Alpabets.remove(word.charAt(i));
}
System.out.println(Alpabets);
}
Change
Alpabets.remove(word.charAt(i));
to
Alpabets.remove((Object) word.charAt(i));
The issue is that List.remove has two implementations (it's an overloaded method):
One implementation that takes an index as argument: List.remove(int index) ("remove the 5th element from the list")
One that removes an actual object from the list List.remove(Object o) ("remove the number 5 from the list).
By calling using Alpabets.remove(word.charAt(i)); you're accidentally invoking the one that takes an index, and if you give it a "large enough" character (characters can be seen as numerical values in Java), you'll hit an index out of bounds in the remove method.
By casting the argument to Object, you force the correct method to be called.
Might you can also use map key and value and remove based on user input.

Two problems, using charAt for undefined input and looping output

So, I posted this nearly identical code yesterday, asking about how to leave the punctuation at the end of a reversed sentence after using .split. I'm still struggling with it, but I'm also having another issue with the same code: And here is my screen shot http://i.stack.imgur.com/peiEA.png
import java.util.Scanner;
import java.util.StringTokenizer; // for splitting
public class MyTokenTester
{
public static void main(String\[\] args)
{
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String\[\] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
for (int count = words.length -1; count>=0; count--) // reverse the order and assign backward each token
{
backward += words\[count\] + " ";
}
System.out.println(backward); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
sentinel = sentinel.toLowerCase(); // regardless of case
} while (!sentinel.equals("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
} // end class MyTokenTester][1]][1]
As you guys can probably see my from screen shot, when the user is prompted to add another sentence in, the previous sentence is read back again.
My questions are:
How do I use charAt to identify a character at an undefined index (user input with varying lengths)
How do I stop my sentence from reading back after the user decides to continue.
Again, as I said, I'd posted this code yesterday, but the thread died and I had additional issues which weren't mentioned in the original post.
To address part 2, if you want to stop the sentence from reading back previous input, then reset backward to an empty string, because as it stands now, you're constantly adding new words to the variable. So to fix this, add this line of code right before the end of your do-while loop,
backward = "";
To address part 1, if you want to check the last character in a string, then first you have to know what is the last index of this string. Well, a string has indexes from 0 to str.length()-1. So if you want to access the very last character in the user input, simply access the last word in your words array (indexed from 0 to words.length - 1) by doing the following,
words[count].charAt(words[count].length() - 1);
Note that count is simply words.length - 1 so this can be changed to your liking.
1) So you have this array of strings words. Before adding each word to the backward string, you can use something like: words[count].chartAt(words[count].length() - 1). It will return you the charater at the last position of this word. Now you are able to do you checking to know wether it is a letter or any special char.
2) The problem is not that it is reading the previous line again, the problem is that the backward string still has the previous result. As you are using a + operator to set the values of the string, it will keep adding it together with the previous result. You should clean it before processing the other input to have the result that you want.
here is your code:
import java.util.*;
public class main{
public static void main(String[] args){
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String[] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
List<String> items = Arrays.asList(words);
Collections.reverse(items);
System.out.println(generateBackWardResult(items)); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
// i use quals ignore case, makes the code more readable
} while (!sentinel.equalsIgnoreCase("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
static String generateBackWardResult(List<String> input){
String result="";
for (String word:input){
result =result +" "+word;
}
return result;
}
} // end class MyTokenTester][1]][1]
there are also some thing to mention:
* never invent the wheel again! (for reverting an array there are lots of approaches in java util packages, use them.)
*write clean code, do each functionality, i a separate method. in your case you are doing the reverting and showing the result in a single method.

print even words from string input?

I am in a beginners course but am having difficulty with the approach for the following question: Write a program that asks the user to enter a line of input. The program should then display a line containing only the even numbered words.
For example, if the user entered
I had a dream that Jake ate a blue frog,
The output should be
had dream Jake a frog
I am not sure what method to use to solve this. I began with the following, but I know that will simply return the entire input:
import java.util.Scanner;
public class HW2Q1
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a sentence");
String sentence = keyboard.next();
System.out.println();
System.out.println(sentence);
}
}
I dont want to give away the answer to the question (for the test, not here), but I suggest you look into
String.Split()
From there you would need to iterate through the results and combine in another string for output. Hope that helps.
While there will be more simpler and easier way to do this, I'll use the basic structure- for loop, if block and a while loop to achieve it. I hope you will be able to crack the code. Try running it and let me know if there is an error.
String newsent;
int i;
//declare these 2 variables
sentence.trim(); //this is important as our program runs on space
for(i=0;i<sentence.length;i++) //to skip the odd words
{
if(sentence.charAt(i)=" " && sentence.charAt(i+1)!=" ") //enters when a space is encountered after every odd word
{
i++;
while(i<sentence.length && sentence.charAt(i)!=" ") //adds the even word to the string newsent letter by letter unless a space is encountered
{
newsent=newsent + sentence.charAt(i);
i++;
}
newsent=newsent+" "; //add space at the end of even word added to the newsent
}
}
System.out.println(newsent.trim());
// removes the extra space at the end and prints newsent
you should use sentence.split(regex) the regular expression is going to describe what separate your worlds , in your case it is white space (' ') so the regex is going to be like this:
regex="[ ]+";
the [ ] means that a space will separate your words the + means that it can be a single or multiple successive white space (ie one space or more)
your code might look like this
Scanner sc= new Scanner(System.in);
String line=sc.nextLine();
String[] chunks=line.split("[ ]+");
String finalresult="";
int l=chunks.length/2;
for(int i=0;i<=l;i++){
finalresult+=chunks[i*2]+" ";//means finalresult= finalresult+chunks[i*2]+" "
}
System.out.println(finalresult);
Since you said you are a beginner, I'm going to try and use simple methods.
You could use the indexOf() method to find the indices of spaces. Then, using a while loop for the length of the sentence, go through the sentence adding every even word. To determine an even word, create an integer and add 1 to it for every iteration of the while loop. Use (integer you made)%2==0 to determine whether you are on an even or odd iteration. Concatenate the word on every even iteration (using an if statement).
If you get something like Index out of range -1, manipulate the input string by adding a space to the end.
Remember to structure the loop such that, regardless of the whether it is an even or odd iteration, the counter increases by 1.
You could alternatively remove the odd words instead of concatenation the even words, but that would be more difficult.
Not sure how you want to handle things like multiple spaces between words or weird non-alphabetically characters in the entry but this should take care of the main use case:
import java.util.Scanner;
public class HW2Q1 {
public static void main(String[] args)
{
System.out.println("Enter a sentence");
// get input and convert it to a list
Scanner keyboard = new Scanner(System.in);
String sentence = keyboard.nextLine();
String[] sentenceList = sentence.split(" ");
// iterate through the list and write elements with odd indices to a String
String returnVal = new String();
for (int i = 1; i < sentenceList.length; i+=2) {
returnVal += sentenceList[i] + " ";
}
// print the string to the console, and remove trailing whitespace.
System.out.println(returnVal.trim());
}
}

Arrays - square-free word

This is what the program should do:
The word, zatabracabrac, is not square free, since it has subword, abrac twice start-
ing at position 4 of the word.
We are not allowed to use strings, breaks or other complex stuff. I get the square and square not part but am unable to find its place. I think I went wrong some place like I can't figure it out.
public static void main(String[] args) {
// part (a) of the main
Scanner keyboard = new Scanner(System.in);
System.out.println("***************************");
System.out.println(" Part (a)");
System.out.println("***************************");
do{
System.out.println("Enter a word and then press enter:");
String str=keyboard.next();
char[] word = str.toCharArray();
isSquareFree(word);
System.out.println("Do you want to test another word? Press y for yes, or another key for no");
}while(keyboard.next().charAt(0)=='y');
public static void isSquareFree(char[] word){
int z = 0;
for(int i=0; i<word.length; i++){
for(int j=0; j<word.length-1;j++){
if (word[j] == word[j+1]){
z = 1;
j = word.length;
}
else{
z = 2;
}
}
}
if (z == 1){
System.out.println();
System.out.println("Not Square Free");
}
else{
System.out.println();
System.out.println("Square Free");
}
}
}
Downvotes on the question: this is not where you solve your homework... we all went through having homeworks and solved them (well, most of us), and that's partly why we're capable of helping you.
You're checking whether the word contains two consecutive characters which are the same.
That's not what you want, try another solution.
Here's why it does what I said above:
The outer for loop doesn't have an effect on the inner one, since i is not used inside
Index j and j+1 in the same iteration as a character and the next one
Other notes:
j = word.length is the same as break here, try using that, it stops your loop like the end condition was satisfied; read more: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
For easier testing, you might want to use another main function containing only calls like isSquareFree("zatabracabrac".toCharArray());, even multiple ones to see multiple test results at once
This will greatly reduce the change-compile-run-check cycle's length.
You can use a debugger in an IDE (Eclipse or IntelliJ) to see what your program does.
Without debugging you can use println/print/printf calls to see how many iterations you have and what your values during those iterations.
Hints on solution:
As I see you're essentially looking for consecutive k-length subword duplicates
You phrased it right in the comment, the arbitrary length is giving it another level
At each position i try to look for a subword with length k which has a corresponding match starting at i + k (this helps the consecutive constraint)
k can be anything between a letter and half of the string (more than that is overkill since it cannot repeat twice)
I didn't code it, but it would be my first try
In your examples:
borborygmus
^=>
i
borborygmus
^=>
i+k
With k = 3 there is a match
zatabracabrac
^===>
i
zatabracabrac
^===>
i+k
With k = 5 there is a match

Categories

Resources