I'm very new to programming and I've spent some time looking for a way to do this that I can understand. I'm making a hangman game in java, it's all text based, and I've got almost the entire thing done. All I need is to replace a character array that holds the value of a random word to be replaced with dashes. So if the word was "java" I need to change that character array to "----". Since the word is chosen at random from a list, I have to find a way to use the length of the word to apply those dashes, but I'm not sure how.
Any help is appreciated!
A simple way to replace all the characters by '_' would be :
char[] charArray = {'W','O','R','D'};
Arrays.fill(charArray, '_');
I will give you an example based on what you have provided so far with java and ----:
public class Program {
public static void main(String[] args) {
String value = "java";
char[] array = value.toCharArray();
// Convert string to a char array.
for(int i = 0; i < value.length(); i++)
{
array[i] = '-';
}
// Loop over chars in the array.
for (char c : array) {
System.out.print(c);
}
}
}
OK, a few things that may be helpful in solving this task:
If you have a String you can easily get the length of that String like this:
String word = "java";
int lengthOfWord = word.length();
You can easily edit the contents of an array by accessing the individual elements:
char[] array = new char[4];
array[0] = '-';
array[1] = '_';
array[2] = '-';
array[3] = '_';
If you want to do something repeatedly and know how often you want to do that, using a for-loop is often a great idea. And you can use the counter within the loop. So for example:
int sum = 0;
for(int i = 0; i < 10; i++) {
sum += i;
}
So, combine those pieces of information and you can replace every element of that array. :-)
Related
I have been given a homework assignment as follows:
Read three sentences from the console application. Each sentence should not exceed 80 characters. Then, copy each character in each input sentence in a [3 x 80] character array.
The first sentence should be loaded into the first row in the reverse order of characters – for example, “mary had a little lamb” should be loaded into the array as “bmal elttil a dah yram”.
The second sentence should be loaded into the second row in the reverse order of words – for example, “mary had a little lamb” should be loaded into the array as “lamb little a had mary”.
The third sentence should be loaded into the third row where if the index of the array is divisible by 5, then the corresponding character is replaced by the letter ‘z’ – for example, “mary had a little lamb” should be loaded into the array as “mary zad azlittze lazb” – that is, characters in index
positions 5, 10, 15, and 20 were replaced by ‘z’. Note that an empty space is also a character, and that the index starts from position 0.
Now print the contents of the character array on the console.
The methods, return types, and parameters in the code below are all specified as required so I cannot change any of that information. I am having trouble initializing the 2d array. The instructions say that the sentences must be loaded into the array already reversed etc. but the parameters of the methods for doing this calls for strings. I assume that means I should read the lines as strings and then call the methods to modify them, then use toCharyArray to convert them before loading them into the 2d array. I don't understand how to initialize the 2D array with the values of the char arrays. Is there some kind of for loop I can use? Another issue is that no processing can be done inside of the main method but in the instructions there is no method that I can call to fill the array.
import java.util.regex.Pattern;
public class ReversedSentence {
public static String change5thPosition(String s){
char[] chars = s.toCharArray();
for (int i = 5; i < s.length(); i = i + 5) {
chars[i] = 'z';
}
String newString = new String(chars);
return newString;
}
public static String printChar2DArray(char[][] arr){
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 80; y++) {
// just a print so it does not make new lines for every char
System.out.print(arr[x][y]);
}
}
return null;
}
public static String reverseByCharacter(String s){
String reverse = new StringBuffer(s).reverse().toString();
return reverse;
}
public static String reverseByWord(String s){
Pattern pattern = Pattern.compile("\\s"); //splitting the string whenever there
String[] temp = pattern.split(s); // is whitespace and store in temp array.
String result = "";
for (int i = 0; i < temp.length; i++) {
if (i == temp.length - 1)
result = temp[i] + result;
else
result = " " + temp[i] + result;
}
return result;
}
public static String truncateSentence(String s){
if (s==null || s.length() <= 80)
return s;
int space = s.lastIndexOf(' ', 80);
if (space < 0)
return s.substring(0, 80);
return s;
}
public static void main(String[] args) {
String sentence1 = ("No one was available, so I went to the movies alone.");
String sentence2 = "Ever since I started working out, I am so tired.";
String sentence3 = "I have two dogs and they are both equally cute.";
char[][] arr = new char[3][80];
arr[0] = reverseByCharacter(sentence1).toCharArray();
arr[1] = reverseByWord(sentence2).toCharArray();
arr[2] = change5thPosition(sentence3).toCharArray();
printChar2DArray(arr);
}
}
The error I am getting is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 52 out of bounds for length 52
at ReversedSentence.printChar2DArray(ReversedSentence.java:20)
at ReversedSentence.main(ReversedSentence.java:71)
.enola seivom eht ot tnew I os ,elbaliava saw eno oN
The problem is that in your printChar2DArray method you assume that every array has the length of 80, but that's actually not the case here. In Java, a 2D array is just an array of arrays. So, when you have this: char[][] arr = new char[3][80], you are creating an array of 3 arrays, and each of these arrays has the length of 80 characters. That may seem ok, but in the next lines you reinitialize the 3 arrays with something different entirely.
arr[0] = reverseByCharacter(sentence1).toCharArray();
arr[1] = reverseByWord(sentence2).toCharArray();
arr[2] = change5thPosition(sentence3).toCharArray();
Now none of these arrays has the length of 80. Each of them has the length of the respective string.
You can solve this in 2 ways (depending on how constrained your task actually is).
First, you can copy the string into arrays, instead of assigning the arrays to the results of the toCharArray method. You can achieve this with a simple loop, but I wouldn't recommend this approach, because you will end up with arrays of 80 characters, even if the strings contain less.
String firstSentence = reverseByCharacter(sentence1);
for (int i = 0; i < firstSentence.length(); i++) {
arr[0][i] = firstSentence.charAt(i);
}
Or:
char[] firstSentence = reverseByCharacter(sentence1).toCharArray();
for (int i = 0; i < firstSentence.length; i++) {
arr[0][i] = firstSentence[i];
}
Second, you can drop the assumption of the arrays' lengths in the printChar2DArray method. I recommend this approach, because it makes you code much more flexible. Your printChar2DArray method will then look like this:
public static String printChar2DArray(char[][] arr){
for (int x = 0; x < arr.length; x++) {
for (int y = 0; y < arr[x].length; y++) {
// just a print so it does not make new lines for every char
System.out.print(arr[x][y]);
}
}
return null;
}
You can see that I've substituted numbers with the length field, which can be accessed for any array.
Also, this way you don't need to initialize the inner arrays, because you reinitialize them in the next lines anyway.
char[][] arr = new char[3][];
arr[0] = reverseByCharacter(sentence1).toCharArray();
arr[1] = reverseByWord(sentence2).toCharArray();
arr[2] = change5thPosition(sentence3).toCharArray();
But this approach may not be suitable for your task, because then the sentences could be of any length, and they wouldn't be constained to 80 characters max.
UPDATE - To answer the question in the comment
To print a newline character you can use System.out.println() without parameters. It's better than putting the newline character into the arrays because it's not a logical part of the sentences.
So your for-loop in the printChar2DArray would look like this:
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 80; y++) {
// just a print so it does not make new lines for every char
System.out.print(arr[x][y]);
}
System.out.println();
}
I am currently trying to write a program where the user will input a string and then the program will output the occurrence of lowercase letters as such:
"Hello world! The quick brown fox jumps over the fence."
a:
b:*
c:**
d:*
e:*****
f:**
g:
h:***
... so on until z.
I just have no idea how to go about writing this. I've looked around but no one uses arrays. I was thinking you have an array for the alphabet and then have a loop that takes each element of the string and corresponds it with a letter of the alphabet, which then adds one to the counter which wil ultimately display the histogram.
Just not sure how to go about it.
Thanks.
EDIT: Here's what I have so far. It's not much and I still don't really understand what to do. But it's something.
import java.util.Scanner;
public class CountingChars {
public static void main(String[] args) {
System.out.println("Enter the text you would like to count the characters of. Please end with a blank line.");
Scanner sc = new Scanner(System.in);
String userInput = sc.nextLine();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
int[] amount = new int[alphabet.length()];
//for (int i = 0; i < userInput.length();i++){
//}
char occurrence;
int count = 0;
while(userInput.length()>0){
occurrence = userInput.charAt(0);
int i = 0;
while(i < userInput.length() && userInput.charAt(i) == occurrence){
count++;
}
}
}
}
Two basic ways of doing this which come to mind.
First is using an array of fixed length with stored ints (lower alph chars), where 'a' is on index 0. And then iterate through the given chararray updating the specific index (you can get the index by something like 'selectedChar' - 'a', which will give you the index position). Then you simply iterate through the list a print number of asterisks accordingly.
Second way is using a HashMap, where you store per each character the value, count the chars, update the value in the map accordingly and then simply go through the map and print those out (now that I am thinking about it, SortedMap will be better).
public static void printAlphabetHistogram(String input) {
int amount[] = new int[25];
for(char c : input.toCharArray()) {
if(Character.isAlphabetic(c)) {
c = Character.toLowerCase(c);
amount[c - 'a'] += 1;
}
}
for(int i = 0; i < amount.length; i++) {
System.out.printf("%s:", (char)('a' + i));
for(int j = 0; j < amount[i]; j++) {
System.out.print("*");
}
System.out.println();
}
}
I am in a beginner Java class and I haven't gotten the chance to learn how to avoid duplicated values when storing values inside arrays.
String[] newAlphabet = new String[26];
for(int I = 0; I < newAlphabet.length; I++){
int random = (65 + (int)(Math.random() * ((90 - 65) + 1));
char ascii = (char)random;
String letters = ascii + "";
if(letters != newAlphabet[0] && letters != newAlphabet[1] ... so on and so on until
newAlphabet[25])
newAlphabet[I] = letters;
}//end
So this is my pseudo code for part of my program and the point of it is to avoid having duplicated letters inside the array.
The problem that I am having is inside the if statement. Instead of typing letters != newAlphabet[] to 25, is there another way of doing it?
I have seen some of the forums in stackedoverflow that I should use HashSet but I have not learned that? I can ask my teacher if I am allowed but is there another way to avoid this problem?
I have been thinking of using for-each loop to search through all the elements in the array but I haven't thought out the plan long enough if it's valid.
As you are talking about a beginner Java class, I am assuming you are fairly new to programming. So, rather than just give you a library function that will do it for you, let's walk through the steps of how to do this with just the basic code so you can get a better idea of what is going on behind the scenes.
Firstly, for any repetitive action, think loops. You want to check, for each letter in your new alphabet, if the one you are about to add matches it. So...
boolean exists = false; //indicates whether we have found a match
for (int j = 0; j < 26; j++) { //for each letter in the new alphabet
//true if this one, or a previous one is a match
exists = exists || letters == newAlphabet[i];
}
//if we don't have a match, add the new letter
if (!exists) newAlphabet[I] = letters;
Now, as you are building up your new alphabet as we go, we don't have a full 26 letters for most cases of running this code, so only check the parts of the new alphabet we have defined:
boolean exists = false;
for (int j = 0; j < I; j++) { //note in this line we stop before the insertion point
exists = exists || letters == newAlphabet[i];
}
if (!exists) newAlphabet[I] = letters;
Finally, we don't need to keep checking if we have already found a match, so we can change the loop to stop when we have found a match:
boolean exists = false;
int j = 0;
while (!exists && j < I) { //we now also stop if we have already found a match
exists = letters == newAlphabet[i];
//as we are stopping at the first match,
//we no longer need to allow for previous matches
}
if (!exists) newAlphabet[I] = letters;
You could use the asList method:
if( Arrays.asList(newAlphabet).contains(letters) ) {
newAlphabet[I] = letters;
}
It's not the most efficient, but since your array is only 26 elements long, I would favor clarity over efficiency.
Some explanation: asList is a static method on the Arrays class. This just means that we don't have to create an Arrays object to call it. We simply say Arrays.asList() and pass it the arguments. The asList method takes an array (newAlhpabet in this case) as a parameter, and builds a java.util.List out of it. This means that we can call List methods on the return value. contains() is a method on List that returns true if the List contains an element that is equal to the parameter (letters in this case).
Based on this line it looks like all you're trying to do is produce the letters A to Z in some other order:
int random = (65 + (int)(Math.random() * ((90 - 65) + 1));
If I'm understanding that right, then really all you're trying to do is shuffle the alphabet:
// Initialize new alphabet array
String originalAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] newAlphabet = originalAlphabet.toCharArray();
// Shuffle the new alphabet by swapping each character to a random position
for (int i=0; i<26; i++) {
int j = (int)(Math.random() * 26);
char temp = newAlphabet[i];
newAlphabet[i] = newAlphabet[j];
newAlphabet[j] = temp;
}
// Print the new alphabet
for (int i=0; i<26; i++) {
System.out.print(newAlphabet[i]);
}
System.out.println();
Here's a sample output: VYMTBIPWHKZNGUCDLRAQFSOEJX
You have a couple options.
Loop through the array and do basically what you're doing now.
Insert the characters in sorted order so you can perform binary search to determine if a letter is already in the list. As a bonus, if you use option 2, you'll already know the insertion point.
Check out Arrays.binarySearch(): http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html
You could use this :
if(Arrays.binarySearch(newAlphabet, letters) < 0){
newAlphabet[I] = letters;
}
You should either include a while loop to make sure each index of the array is filled before moving to the next or you could make use of the return value of Arrays.binarySearch which is (-(insertion index) - 1) to fill the array and exit when the array is filled up.
I got a little problem here with Java and I am fairly new to it.
My program reads a String via InputStreamReader and saves it in the String input.
How do I save the elements of the String in a 2d char array with n x m elements?
Edit:
I think I´ve got a solution:
I used 2 for-loops (is that the right english translation for it? ) and .toCharArray to convert the String.
public static char[][] transform (String text, int arrBreite, int arrLaenge) {
char[][] returnArray = new char[arrBreite][arrLaenge];
char[] buffer = text.toCharArray();
for (int i = 0; i < arrBreite; i++) {
for (int j = 0; j <arrLaenge; j++) {
if (((i * arrBreite) + j) > buffer.length - 1) returnArray[i][j] = " ".charAt(0);
else returnArray[i][j] = buffer[(i*arrBreite)+j];
}
}
return returnArray;
}
Thanks for your help guys.
You can use the toCharArray() method to get a char array from your String.
If you need to split with a given delimiter to determine the array lines, you use first the Split method on the String, then use toCharArray to create your 2 dimensional array.
You should use String.toCharArray().
I wanted to scramble a String, to make it unreadable and so came up with this method:
public String scrambleWord(String start_word){
char[] wordarray = start_word.toCharArray();
char[] dummywordarray = start_word.toCharArray();
Random random = new Random();
int r = random.nextInt(wordarray.length-1);
int i = 0;
int j = r+1;
while(i <= r){
dummywordarray[wordarray.length -i-1] = wordarray[i];
i++;
}
while (j <= wordarray.length -1){
dummywordarray[j-r-1] = wordarray[j];
j++;
}
String newword = String.valueOf(dummywa);
return newword;
SO I first converted the string to a char array, and in my method I had to duplicate the char array "dummywordarray". Passing once through this algorithm every lette rof the word will have changed position. But it wont be scrambled very well, in the sense that you could put it back together at a glance.
SO I passed a given String of less than 9 characters through the method 7 times, and the words are fairly well scrambled, i.e. unreadable.
But I tried it with a 30 character string and it took 500 passes before I could guarantee it was nicely scrambled. 500!
I'm sure there is a better algorithm, I'd like some advice on either
a)improving this method
or
b)a better way.
How about
ArrayList<Character> chars = new ArrayList<Character>(word.length());
for ( char c : word.toCharArray() ) {
chars.add(c);
}
Collections.shuffle(chars);
char[] shuffled = new char[chars.size()];
for ( int i = 0; i < shuffled.length; i++ ) {
shuffled[i] = chars.get(i);
}
String shuffledWord = new String(shuffled);
In other words, you could take advantage of the existing java.util.Collections.shuffle(List) method. Unfortunately you have to jump through a couple of hoops to use it, since you can't use primitives in Generics.
Edit:
The basic way that shuffle works (see the Javadoc for the full explanation), is like this:
for position = last_index to first_index
let swap_pos = random number between first_index and position, inclusive
swap(swap_pos, position)
Edit 2:
This approach is significantly less verbose with Guava's Chars utilities:
List<Character> chars = Chars.asList(word.toCharArray());
Collections.shuffle(chars);
String shuffledWord = new String(Chars.toArray(chars));