How to create a loop for - java

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.

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.

How to populate an array (like hangman) based on a guess

What I am trying to do is take a hidden String and then display it letter by letter in a random sequence every time the user presses the hint button. Currently, every time the hint button is pressed the entire solution displays once per character of the solution.
I am trying to make it so that when the hint button is pressed a random character from the string solution appears in the correct location. I am unsure about how to compare the location of the generated character to the string location.
public String letterGenerator(int count, String word) {
//String word is taken from another function and it is based on the current displayed card and associated answer
StringBuilder string = new StringBuilder();
Random rng = new Random();
char[] letters = word.toCharArray();
char[] answers = new char[letters.length];
int selected = rng.nextInt(letters.length);
for (int i = 0; i < word.length(); i++) {
if (i == selected) {
letters[i] = answers[i];
}
string.append(letters);
}
return string.toString();
}
For example if the answer is "a wallet" this code outputs the solution as "a walleta walleta walleta walleta walleta walleta walleta walleta" (It displays the output 8 times because it prints the solution once per character including blank spaces)
What it should be doing for each press of the hint button would be to display each character in a random order like so:
Press 1: "_ _ _ l_ _ _"
Press 2: "a _ _ l_ _ _"
Press 3: "a _ _ l _e _", and so on until the entire word appears on screen
Any help is appreciated!
Well, you append(letters) to your output for each iteration of your loop, and letters is an array of all your letters, not just one of them. So of course you end up with that output that you got.
But I think you can design this in a more elegant, and more object-oriented way. Instead of two character arrays for the answer and what is displayed, maybe make just one array of 'Letters'. This means you create a custom class Letter, which could hold the information whether it is 'solved' or not. Like so:
public class Letter{
char character;
boolean solved;
// ... Constructor, Getters, Setters
}
Then, you can just pass your array of letters to a method that selects a random letter that is not solved yet, and simply switch its solved property to true. Your code for displaying the thing to your user would then be something like this:
for(Letter letter : letterArray){
System.out.print(letter.isSolved() ? letter.getCharacter() : "_");
}
If I've understood correctly, then here's a few things to change;
1) You want to remember the last revealed hint, but you've stored it in a local variable.
You'll want a way to store the revealed letters. How you do that depend on how the rest of your class is setup, but either passing it back as part of the method return or setting a global variable should do
2) Since you are remembering the previous hints, you'll want to make sure that 'selected' has not been revealed before. Perhaps store what letter positions have been revealed before and compare against them.
3) I would put the internal of the loop more as
for (int i = 0; i < word.length(); i++) {
if(i == selected){
string.append(letters[i]);
}else{
string.append("_");
}
}
I hope this helps
Edit:
I've changed the for loop, now it should work as you wanted. Sorry I should have been more careful to start with.
As for storing the previously revealed letters, if you are using a Singleton class then it would be acceptable to store this values in another list. My suggestion would be to keep an ArrayList of revealed values, then do something like;
List<Integer> revealed = new ArrayList<>();
Random rng = new Random();
public int getNextSelected(int length){
int selected = rng.nextInt(length);
if(revealed.contains(selected)){
return getNextSelected(length);
}
return selected;
}
public String letterGenerator(int count, String word) {
...
int selected = getNextSelected(letters.length);
for (int i = 0; i < word.length(); i++) {
if (i == selected){
string.append(letters[i]);
} else if (revealed.contains(i)) {
string.append(letters[i]);
} else{
string.append("_");
}
}
revealed.add(selected);
return string.toString();
}
This should do what you need. There's plenty of ways to clean up the code, the suggestion by user3237736 is quite nice as it follows the 'tell don't ask' principle, but the design decisions of the class is up to you
public class SOEN_student {
public static void letterGenerator(String word) {
//String word is taken from another function and
//it is based on the current displayed card and associated answer
StringBuilder string;
Random rng = new Random();
char[] letters = word.toCharArray();
char[] answers = new char[letters.length];
boolean[] visited=new boolean[letters.length];
int selected;
for (int i = 0; i < word.length(); i++) {
do{
selected=rng.nextInt(letters.length);
}while(visited[selected]);
string=new StringBuilder();
for(int j=0;j<word.length();j++){
if(visited[j] | j==selected){
visited[selected]=true;
string.append(letters[j]);
}else{
string.append("_");
}
}
System.out.print(string.toString()+" ");
}
}
public static void main(String... args){
letterGenerator("a wallet");
}
}

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

Removing duplicate chars from a string passed as a parameter

I am a little confused how to approach this problem. The userKeyword is passed as a parameter from a previous section of the code. My task is to remove any duplicate chars from the inputted keyword(whatever it is). We have just finished while loops in class so some hints regarding these would be appreciated.
private String removeDuplicates(String userKeyword){
String first = userKeyword;
int i = 0;
while(i < first.length())
{
if (second.indexOf(first.charAt(i)) > -1){
}
i++;
return "";
Here's an update of what I have tried so far - sorry about that.
This is the perfect place to use java.util.Set, a construct which is designed to hold unique elements. By trying to add each word to a set, you can check if you've seen it before, like so:
static String removeDuplicates(final String str)
{
final Set<String> uniqueWords = new HashSet<>();
final String[] words = str.split(" ");
final StringBuilder newSentence = new StringBuilder();
for(int i = 0; i < words.length; i++)
{
if(uniqueWords.add(words[i]))
{
//Word is unique
newSentence.append(words[i]);
if((i + 1) < words.length)
{
//Add the space back in
newSentence.append(" ");
}
}
}
return newSentence.toString();
}
public static void main(String[] args)
{
final String str = "Words words words I love words words WORDS!";
System.out.println(removeDuplicates(str)); //Words words I love WORDS!
}
Have a look at this answer.
You might not understand this, but it does the job (it cleverly uses a HashSet that doesn't allow duplicate values).
I think your teacher might be looking for a solution using loops however - take a look at William Morisson's answer for this.
Good luck!
For future reference, StackOverflow normally requires you to post what you have, and ask for suggestions for improvement.
As its not an active day, and I am bored I've done this for you. This code is pretty efficient and makes use of no advanced data structures. I did this so you could more easily understand it.
Please do try to understand what I'm doing. Learning is what StackOverflow is for.
I've added comments in the code to assist you in learning.
private String removeDuplicates(String keyword){
//stores whether a character has been encountered before
//a hashset would likely use less memory.
boolean[] usedValues = new boolean[Character.MAX_VALUE];
//Look into using a StringBuilder. Using += operator with strings
//is potentially wasteful.
String output = "";
//looping over every character in the keyword...
for(int i=0; i<keyword.length(); i++){
char charAt = keyword.charAt(i);
//characters are just numbers. if the value in usedValues array
//is true for this char's number, we've seen this char.
boolean shouldRemove = usedValues[charAt];
if(!shouldRemove){
output += charAt;
//now this character has been used in output. Mark that in
//usedValues array
usedValues[charAt] = true;
}
}
return output;
}
Example:
//output will be the alphabet.
System.out.println(removeDuplicates(
"aaaabcdefghijklmnopqrssssssstuvwxyyyyxyyyz"));

Finding Palindromes in a word list

I'm working on a program for Java on how to find a list of palindromes that are embedded in a word list file. I'm in an intro to Java class so any sort of help or guidance will be greatly appreciated!
Here is the code I have so far:
import java.util.Scanner;
import java.io.File;
class Palindromes {
public static void main(String[] args) throws Exception {
String pathname = "/users/abrick/resources/american-english-insane";
File dictionary = new File(pathname);
Scanner reader = new Scanner(dictionary);
while (reader.hasNext()) {
String word = reader.nextLine();
for (int i = 0; i > word.length(); i++) {
if (word.charAt(word.indexOf(i) == word.charAt(word.indexOf(i)) - 1) {
System.out.println(word);
}
}
}
}
}
There are 3 words that are 7 letters or longer in the list that I am importing.
You have a few ways to solve this problem.
A word is considered a palindrome if:
It can be read the same way backwards as forwards.
The first element is the same as the last element, up until we reach the middle.
Half of the word is the same as the other half, reversed.
A word of length 1 is trivially a palindrome.
Ultimately, your method isn't doing much of that. In fact, you're not doing any validation at all - you're only printing the word if the first and last character match.
Here's a proposal: Let's read each end of the String, and see if it's a palindrome. We have to take into account the case that it could potentially be empty, or be of length 1. We also want to get rid of any white space in the string, as that can cause errors on validation - we use replaceAll("\\s", "") to solve that.
public boolean isPalindrome(String theString) {
if(theString.length() == 0) {
throw new IllegalStateException("I wouldn't expect a word to be zero-length");
}
if(theString.length() == 1) {
return true;
} else {
char[] wordArr = theString.replaceAll("\\s", "").toLowerCase().toCharArray();
for(int i = 0, j = wordArr.length - 1; i < wordArr.length / 2; i++, j--) {
if(wordArr[i] != wordArr[j]) {
return false;
}
}
return true;
}
}
I'm assuming that you're reading in strings. Use string.toCharArray() to convert each string to a char[]. Iterate through the character array using a for loop as follows: on iteration 1, if the first character is equal to the last character, then proceed to the next iteration, else return false. On iteration 2, if the second character is equal to the second-to-last character then proceed to the next iteration, else return false. And so on, until you reach the middle of the string, at which point you return true. Be careful of off-by-one errors; some strings will have an even length, some will have an odd length.
If your palindrome checker is case insensitive, then use string.toLowerCase().toCharArray() to preprocess the character array.
You can use string.charAt(i) instead of string.toCharArray() in the for loop; in this case, if the palindrome checker is case insensitive then preprocess the string with string = string.toLowerCase()
Let's break the problem down: In the end, you are checking if the reverse of the word is equal to the word. I'm going to assume you have all of the words stored in an array called wordArray[].
I have some code for getting the reverse of the word (copied from here):
public String reverse(String str) {
if ((null == str) || (str.length() <= 1)) {
return str;
}
return new StringBuffer(str).reverse().toString();
}
So, now we just need to call that on every word. So:
for(int count = 0; count<wordArray.length;count++) {
String currentWord = wordArray[count];
if(currentWord.equals(reverse(currentWord)) {
//it's a palendrome, do something
}
}
Since this is homework, i'll not supply you with code.
When i code, the first thing i do is take a step back and ask myself,
"what am i trying to get the computer to do that i would do myself?"
Ok, so you've got this huuuuge string. Probably something like this: "lkasjdfkajsdf adda aksdjfkasdjf ghhg kajsdfkajsdf oopoo"
etc..
A string's length will either be odd or even. So, first, check that.
The odd/even will be used to figure out how many letters to read in.
If the word is odd, read in ((length-1)/2) characters.
if even (length/2) characters.
Then, compare those characters to the last characters. Notice that you'll need to skip the middle character for an odd-lengthed string.
Instead of what you have above, which checks the 1st and 2nd, then 2nd and 3rd, then 3rd and fourth characters, check from the front and back inwards, like so.
while (reader.hasNext()) {
String word = reader.nextLine();
boolean checker = true;
for (int i = 0; i < word.length(); i++) {
if(word.length()<2){return;}
if (word.charAt(i) != word.charAt(word.length()-i) {
checker = false;
}
}
if(checker == true)
{System.out.println(word);}
}

Categories

Resources