Arrays - square-free word - java

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

Related

Sudoku Code Program - Checking Rows,Columns, and Boxes

I need help checking rows, columns, and boxes for a Sudoku program. I am a high school student that needs help completing this project. If any one could provide help that would be awesome! I am currently working on checking boxes where I have a comment saying "Start Here". Thanks!
import java.util.*;
public class Run
{
Scanner scanner = new Scanner(System.in);
public static void main(String[] args)
{
char [][] board = new char [9][9];
Scanner scanner = new Scanner(System.in);
System.out.println("Welcome to Sudoku!\n");
fill(board);
printBoard(board);
inputLengthandDigits(board);
System.out.println();
printBoard(board);
}
public static void fill(char[][] arr){
for(int row = 0; row < arr.length; row++){
for(int col= 0; col< arr[row].length; col++){
arr[row][col] = '-';
}
}
}
public static void printBoard(char [][] array)
{
for(char[] row: array)
{
for(char play: row)
{
System.out.print(play+ " ");
}
System.out.println();
}
}
public static void inputLengthandDigits(char[][] array){
Scanner in = new Scanner(System.in);
for (int i = 0; i < 9; i++)
{
System.out.println("\nEnter the numbers in row " + (i+1) + ":");
String input = in.nextLine();
String numbers = "123456789-";
boolean numberscheck = false;
boolean endCheck = true;
boolean onlyOnce = true;
//Input Validation Starts Here!
//Checks if Input is only digits 0-9
do{
if(endCheck==false){
System.out.println("\nPlease input numbers only (1-9)!");
input = in.nextLine();
}
if(onlyOnce==false){
System.out.println("\nPlease input numbers only once!");
input = in.nextLine();
}
//Checks Length of User Input
while(input.length() < 9 || input.length() > 9){
System.out.println("\nPlease input 9 numbers!");
input = in.nextLine();
}
//Start Here
for(int a = 0; a<input.length()-1; a++){
for(int b= a + 1; b<input.length(); b++){
if(input.charAt(a)==input.charAt(b)){
onlyOnce = false;
}
}
}
for(int x = 0; x < input.length(); x++){
char thing = input.charAt(x);
numberscheck = false;
for(int y = 0; y < numbers.length(); y++){
char numbersn = numbers.charAt(y);
if(thing == numbersn){
numberscheck = true;
endCheck = true;
break;
}
}
if(numberscheck == false){
endCheck = false;
break;
}
}
}while(endCheck==false || onlyOnce==false);
for(int j=0; j<9; j++){
array[i][j] = input.charAt(j);
}
}
}
}
My initial response is too long for a comment. I'm not sure I have a solution to your problem, largely because you haven't actually pointed out which bit is a problem yet, but these pointers should help improve things anyway:
Please reformat your code. It is actually quite painful to look at. Spaces should be used consistently around variables, key words, brackets and operands. Opening curly braces should be on the same line as the method signature, for() loop or whatever else comes first. You have random blank lines within methods which don't separate logical sections so are just confusing. The compiler won't care about any of this, but if you can make your code look neater people will instinctively presume you care and are more likely to credit you with the ability to write decent code.
You have declared a new scanner variable three times. This is redundant and wasteful clutter. Either have a single, class-wide scanner, or (preferably), only create a scanner in a method which actually uses it and then remember to call scanner.close() once the scanner is no longer required.
inputLengthandDigits is a weird name. Is 'Lengthand' a single word, or should it be 'inputLengtHandDigits' or 'inputLengthAndDigits'? In camel case, capitalise every word except the first to make the whole easier to read. Whatever it should be, I don't understand from the name what this method does. It isn't inputting anything, it's getting inputs from someone else. Perhaps getData or populateGrid might be more explanatory.
9 appears quite a few times, with no explanation. I know where it came from, because I spend far too much time playing Sudoku, but it is a magic number and these are to be avoided at all costs. I met a magic number in the workplace once, wasted half a day trying to do what could have been a ten minute job if colleagues had recorded what the number was and where it came from. Here, just have a private static final int maxNumber = 9; statement.
A good thing: your main() method has almost no fiddly details in it. You have effectively used method calls to tell a story and describe what is happening elsewhere. This is a really, really good thing to do :)
Some of your logic tests can be tidied up a bit, e.g. !onlyOnce is the same as onlyOnce == false, and input.length() < maxNumber || input.length() > maxNumber can be simplified to input.length() != maxNumber. It's exactly the same logic, but faster to type and easier to read :)
It looks like your code under the //Start here comment is checking that you don't have any duplicate numbers. If you do get duplicate numbers, the program is still going to try and run the next bit of code before asking the user for alternative input. Is that something you want to happen, or a waste of time?
I actually burst out laughing when I saw a variable called 'thing'. Please, find a name which actually describes the purpose of this variable.
I have now run the code, and it rightly pointed out an error when I tried to key in duplicate numbers for row 4. However, it's now stuck there and keeps asking me to try again even when I put in a valid set of digits. This needs to be fixed. Look closely at which flags are triggering the request to retry. Run your code in debugging mode (you are using an IDE like IntelliJ or Eclipse, aren't you?) and deliberately enter a bad row to see the behaviour for yourself and where the logic is going wrong.
This whole method to get the row input, validate it, and then populate the array, is very big and confusing. You need to refactor it into a lot of smaller methods. Here is a suggestion to play with:
private static char[][] populateGrid(char[][] array) {
Scanner scanner = new Scanner(System.in);
for (int i = 0; i <maxNumber; i++) {
String rowData = getRowInput(scanner);
populateRow(array, rowNumber, rowData);
}
scanner.close;
return array;
}
private static String getRowInput(Scanner scanner) {
System.out.println("\nEnter the numbers in row " + (i + 1) + ":");
String input = scanner.nextLine();
while (!isValidInput(input) {
System.out.println("Please enter only the digits 1-9 in any order, with no duplicates or omissions");
input = scanner.nextLine();
}
return input;
}
private static boolean isValidInput(String input) {
if (!rightLengthOfInput(input)) {
return false;
}
if (!allUniqueDigits(input)) {
return false;
}
if (!usesCorrectCharacters(input)) {
return false;
}
return true;
}
I'll leave you to make the different input validation methods. It will largely be a case of moving your existing code, but the method names will help humans understand what each section is doing. This structure also allows you to cleanly add more validation checks, should such a thing be desired in the future.
Things to consider after all that:
Are you going to check that you have a viable Sudoku solution, or will you trust the user to put in correct data such that the columns also have each of the nine digits in them? How will you handle an invalid grid, e.g. each row is identical?
How far does this assignment want you to go? Do you need to systematically remove numbers to get a solvable puzzle rather than a completed grid? Will the assignment stop at a puzzle which can be seen in the console, or do you need a printable format, or will the user be able to play through the program? If the latter option, will this be in the console or using a graphical interface?
I appreciate that there is a lot to think about and work on here. Take it steadily, one step at a time, and keep asking questions if you need too.

Hangman : Exit the program when the word is found

This is an implementation of the Hangman game. Once the user has uncovered the word, the program should exit, but it continues to prompt the user for input although all letters of the word have been correctly guessed.
How can I make the program exit properly once the word has been guessed?
The word to seach is for example no : Here is an illustration:
Enter your lettre:
n
The letter is OK !
n_
Enter your lettre:
o
The letter is OK !
no
Enter your lettre:
I don't understand why the loop continues ? Because I found the word...
Here is my code:
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
Random r = new Random();
String[] arr = {"one", "no"};
String word = arr[r.nextInt(arr.length)];
char[] dash = word.toCharArray();
char[] charArr = word.toCharArray();
for(int i=0;i<dash.length;i++){
dash[i] = '-';
System.out.print(dash[i] + " ");
}
System.out.println("");
for(int i=0;i<3;i++){
System.out.print("Enter your letter : ");
char letter = input.next().charAt(0);
for(int j=0;j<charArr.length;j++){
if(letter == charArr[j]){
dash[j] = letter;
System.out.println("Ok ! ");
System.out.println(dash);
i--;
}
}
}
}
}
I share you the code here => https://repl.it/repls/BonyRevolvingOs
Thank you for your help.
Look at the block of code defining your inner loop:
for(int j=0;j<charArr.length;j++){
if(letter == charArr[j]){
dash[j] = letter;
System.out.println("Ok ! ");
System.out.println(dash);
i--; // What is this doing here?
}
}
At the bottom of that block is the line that's blowing up your program. Get rid of it. Your program never exits the loop because you keep resetting the value of the counter for your outer loop i to 0. Every time the loop increments itself normally to 1, you decrement it, so it's always going from 0 to 1 and back to 0.
Because 0 is less than 3, the loop keeps running. If a break statement depended on the value of that counter, it would not have changed the way your program operated at all. If you called break on some other basis, you could have exited, but you would still have had a fundamentally broken program.
This said, you still have a long way to go to get a working implementation of Hangman because as it stands, your user only has as many guesses as the word has letters If you guess wrong, even a single time, you can never complete the word.
You need to find a way to account for incorrect guesses (drawing the parts of the hanged man) and a way to detect and announce victory or failure (right now, your program just exits after two or three guesses whether or not the puzzle is solved). Work on those things, and if you need more help, post separate questions for each problem.

How to create a loop for

I need to create a loop that adds "o" after each consonant
I am going to walk you through what I corrected and changed in your code to make it work in order to make it quick and easy for you to comprehend why your code doesn't work and why my answer fixes it.
The mistakes you made are basic ones and frankly you shouldn't have to much of a hard time correcting them yourself if you would use a debugger that walks you step by step in how your code works. You should look on how to use a debugger (for example the debugger used in Eclipse, hopefully you are using an IDE to make your life easier).
Firstly, when you are looking for a consonant in your code, you are only walking through the half of it because of your condition for(int x = 0; x<20; x++) since your string holding the consonants if of a length of 40 characters. This means you are missing consonants like the letter s.
Then you are correctly the consonants you find according to your Swedish language game. But you are never handling characters that are not of these found consonants. You should make a case where you handle these "non consonant" letters, may they be vowels or any kind of character (like punctuation marks and so on). I am fixing this with the use of a simple boolean here.
Keep in mind that my goal here is to change your code as little as I can, thus I went for adding a boolean to handle your cases (checking the presence of a consonant). There are, obviously, many other ways to implement what you are trying to do.
Here come the changes you should add to your code:
/*This comes after your print "På rövarspråk:"*/
boolean isConsonant = false; //Boolean to check wether there is a consonant or not
for(int i = 0; i<length; i++) {
//You didn't go through the whole consonants list you made with your prevision condition
for(int x = 0; x<consonants.length; x++){
if(array[i] == consonants[x])
{
isConsonant = true; //Set the boolean accordingly
String add = array[i]+"o"+array[i];
slang = slang + add;
break;
}
}
if(!isConsonant){ //If we don't have a consonant, add the char to the result string
slang += array[i];
}
isConsonant = false; //Reset the boolean for the next character
}
/*Here you can print the result (slang) if you want, as you did*/
so the idea is to dublicate consonants and put "o" between them, like t becomes tot, s becomes sos. Vocals are just copied. So you need a method that tells you if a given character is a vocal or consonant to base your decision on that.
public static boolean isConsonant(char inputChar){
final String consonantsx = "bBcCdDfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ";
char consonants[] = consonantsx.toCharArray(); // String to charr
for(int i=0; i < consonants.length;i++){
if(inputChar == consonants[i]){ //note that in Strings u use the equals method instead of "=="
return true;
}
}
return false;
}
Given this method you can use it in the "translator method".
public String rovarSpraket(String normalString) {
char[] array = normalString.toCharArray(); // Input to a char array
System.out.println("På rövarspråk:");
String slang = "";
for (int i = 0; i < normalString.length(); i++) {
String add = "" + array[i];
if(Goran.isConsonant(array[i])){
add += "o" + array[i];
}
slang += add;
}
return slang;
}
This translates stubborn to sostotubobboborornon like in the wikipedia article https://en.wikipedia.org/wiki/R%C3%B6varspr%C3%A5ket.

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());
}
}

Square Free Word in 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)

Categories

Resources