Char array printing random characters - java

I'm really struggling to print an array with random letters. If anybody could help me that would be great :)
public class CharFilter
{
public static void main(String args[])
{
int rows = 10;
int cols = 10;
char grid[][] = new char [rows][cols];
for(int i=0; i<grid.length;i++)
{
for(int j=0; j<grid[i].length;j++)
{
grid[i][j] = (char) (Math.random()*'a')+'b';
String gprint = "";
gprint = gprint + String.format("%2c", grid[i][j]);
System.out.println(gprint);
}
}
}

Your code won't compile for me because your parentheses around Math.random should include 'b', e.g.
grid[i][j] = (char) (Math.random()*'a'+'b');
I would also skip storing the individual characters in a string, and just print each character, unless for some reason you needed to do it like that.
System.out.println(grid[i][j]);
instead of
String gprint = "";
gprint = gprint + String.format("%2c", grid[i][j]);
System.out.println(gprint);
Finally, if you're specifically trying to have the grid only contain lowercase letters, your formula is a little off. Use Math.random() * ('z' - 'a') + 'a'because random will give you a value between 0 and 1, but your desired range is 26 ('z' - 'a'), not 1, and you want the initial value to be 'a', not 0.

Related

Is there a way to initialize a 2d array with other arrays?

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

how to create a random generated alphabet in Java

Looking to create a randomly generated alphabet for a substitution cipher. My idea was something like this.
char randomChar = (char) (97 + r.nextInt(25));
However this will cause repetition of letters. Going through the char array and seeing if the letter is already present seems inefficient also.
edit: I was too vague in my request and see this now. Here is the full question I am trying to solve. The alphabet must also contain the space button character e.g ' '.
Write a Java program which converts (user entered) plain text to cipher text using a substitution cipher (in which plain text letters are randomly assigned to cipher text letters). Note that a Substitution Cipher replaces plaintext with cipher-text. The most common substitution ciphers replace single characters of plaintext with predefined single characters of cipher-text (e.g. the plain-text character `a' might be replaced by cipher text character 'q', 'b' might be replaced by 'x', 'c' by 'k' and so on). Each plain-text character should be replaced by a different cipher-text character.
As part of your solution you must write and use at least the following functions/methods:
(i) createCipher() which determines and returns the mapping from plain text to cipher text. Each plain text character ('a' .. 'z', ' ') must be randomly assigned a cipher-text character;
I have thought of a solution, said solution works but is it efficient?
public static char[] createCipher(char[] cipher) {
char[] cipher = new char[27];
int characterNumber = 97;
cipher[0] = ' ';
for(int counter = 1; counter < cipher.length;counter++)
{
char character = (char) characterNumber;
cipher[counter] = character;
characterNumber++;
}
for(int counter = 0; counter < cipher.length;counter++)
{
int randomLocation = (int) (Math.random()*26);
char temporaryCharacter = cipher[randomLocation];
cipher[randomLocation] = cipher[counter];
cipher[counter] = temporaryCharacter;
}
return cipher;
}
To do a reshuffling of the alphabet (26 characters but in different order) you do
boolean[] b=new boolean[26];
for(i=0; i<b.length; i++) b[i]=false;
for(int counter = 0; counter < 26;counter++)
{
int randomLocation = (int) (Math.random()*26);
while(b[randomLocation]) randomLocation = (int) (Math.random()*26);
b[randomLocation]=true;
cipher[counter]=alphabet[randomLocation];
}
forget about "efficient" and stuff first you solve the problem
If you want to shuffle an alphabet you can use the Collections.shuffle(..) metode. Somethink like this:
public static void main(String[] args) {
char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
char[] randomAlphabet = new char[alphabet.length];
// Copy to a List
List<Character> list = new ArrayList<Character>();
for (char c : alphabet) {
list.add(c);
}
// shuffle it
Collections.shuffle(list);
// Copy it back to an array
for (int i = 0; i < list.size(); i++) {
randomAlphabet[i] = list.get(i);
}
System.out.print("Random alphabet: ");
for (int i = 0; i < randomAlphabet.length; i++) {
System.out.print(" " + randomAlphabet[i]);
}
}
That gives this when I run it:
Random alphabet: j b w q o c r f z k g n p a u s i d m y h v e l x t

Populate java array with all allowable ASCII chars for WPA password

I am trying to create a random WPA password generator using java to give me as secure of a Wifi password as possible, which can be changed when I desire.
Is there a way to quickly populate an array with all of the characters which would be allowed to be used in a WPA(2) password as opposed to manually entering the chars one by one?
Shortest way I can think of would be:
String s = new String(IntStream.rangeClosed(32, 126).toArray(), 0, 95);
char[] ascii = s.toCharArray();
If you're just generating a sequence of characters, you don't need to make an array of all ASCII characters:
String s = new String(random.ints(length, 32, 127).toArray(), 0, length);
int pwLength = 8;
Random numberGenerator = new Random();
char[] pw = new char[pwLength];
for(int i = 0; i<pwLength; i++){
pw[i] = numberGenerator.nextInt(95) + 32;
}
Well the range of valid ascii values are 32-126 (see https://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters). So you could simply generate a random number between those values for each character and then turn the ascii value to a string.
You do
Character.toString ((char) i); or String.valueOf(Character.toChars(int)) to turn an ascii value to a string.
Put together 8-63 of these characters and you have yourself a random wpa2 passphrase.
private void buildPassword() {
for (int i = 33; i < 127; i++) {
l.add(i);
}
l.remove(new Integer(34));
l.remove(new Integer(47));
l.remove(new Integer(92));
for (int i = 0; i < 10; i++) {
randInt = l.get(new SecureRandom().nextInt(91));
sb.append((char) randInt);
}
str = sb.toString();
}

Counting lower case letters in a string and printing out their occurrence in the form of a histogram?

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

Java ASCII control codes to literal values

I might be somewhat stupid here, but I can't seem to think of a straightforward solution to this problem.
I've currently got an int[] that contains ASCII character codes, however, with the ASCII table, any value < 32 is a control code. So what I need to do is for any value > 32, put the ASCII character into a char[], however if it's < 32, just put the literal integer value in as a character.
For example:
public static void main(String[] args) {
int[] input = {57, 4, 31}; //57 is the only valid ASCII character '9'
char[] output = new char[3];
for (int i = 0; i < input.length; i++) {
if (input[i] < 32) { //If it's a control code
System.out.println("pos " + i + " Not an ascii symbol, it's a control code");
output[i] = (char) input[i];
} else { //If it's an actual ASCII character
System.out.println("pos " + i + " Ascii character, add to array");
output[i] = (char) input[i];
}
}
System.out.println("\nOutput buffer contains:");
for (int i = 0; i < output.length; i++) {
System.out.println(output[i]);
}
}
Output is:
pos 0 Ascii character, add to array
pos 1 Not an ascii symbol, it's a control code
pos 2 Not an ascii symbol, it's a control code
Output buffer contains:
9 // int value 57, this is OK
As you can see the last two entries in the array are blank, as there isn't actually an ASCII character for either 4, or 31. I know there are methods for converting Strings to char[], however what's the general idea when you've already got a char[] in which you want the value.
There is probably a really easy solution for this, I think I'm just having a dumb moment!
Any advice would be appreciate, thanks!
For classifying characters you should use the Character.getType(char) method.
To store either a character or an integer you could try using a wrapper object to do that.
Alternatively you could wrap your char like this:
static class NiceCharacter {
// The actual character.
final char ch;
public NiceCharacter ( char ch ) {
this.ch = ch;
}
#Override
public String toString () {
return stringValue(ch);
}
public static String stringValue ( char ch ) {
switch ( Character.getType(ch)) {
// See http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters for what the Cc group is.
// See http://en.wikipedia.org/wiki/Control_character for a definition of what are CONTROL characters.
case Character.CONTROL:
return Integer.toString(ch);
default:
return Character.toString(ch);
}
}
}
Change how you print the output buffer
for (int i = 0; i < output.length; i++) {
if (output[i] < 32){
System.out.println("'" + (int)output[i] + "'"); //Control code is casted to int.
//I added the ' ' arround the value to know its a control character
}else {
System.out.println(output[i]); //Print the character
}
}

Categories

Resources