turning an array of strings into a 2d array of chars - java

my code reads input from a file that has a maze written inside, inside the file looks like this.
7 7
GOOOOXO
XXOXOOX
OXOOOXX
XXXOOXO
XXXXOXX
SOOOOOX
XXXXXXX (these are each on a separate line not sure how to show that here)
the numbers are the dimensions and G is goal S is start, that doesn't really matter for now. I read the file into an array of Strings line by line. So my array looks like this {"GOOOOXO",...,"XXXXXXX"} now I want to convert the strings to a 2d array of chars where the characters are stored the same way as the maze is displayed above.
The first nested for loop just reads the files input and saves each line as a string in the array, the second array is meant to convert the strings into characters to save them into the 2d array and still manage to keep the shape of the maze. I get an array index out of bounds exception. But to be honest with you after hours of being stuck on this my brain is fried, I can't figure out my issue.
int dimensionsX = input.nextInt();
int dimensionsY = input.nextInt();
String[] lines = new String[dimensionsY];
char[][] maze2 = new char[dimensionsX][dimensionsY];
for (int j = 0; j < dimensionsY; ++j) {
if (input.hasNextLine()) {
lines[j] = input.nextLine();
System.out.println(lines[j]);
//System.out.println(j);
}
}
for (int i = dimensionsX; i > 0; --i) {
for (int j = dimensionsY; j > 0; --i) {
maze2[i][j] = lines[i].charAt(j);
System.out.print(maze2[i][j]);
if (i == lines.length) {
System.out.println();
}
}
}

For example:
int dimensionsX = input.nextInt();
int dimensionsY = input.nextInt();
String[] lines = new String[dimensionsY];
char[][] maze2 = new char[dimensionsY][];
for (int j = 0; j < dimensionsY; ++j) {
if (input.hasNextLine()) {
lines[j] = input.nextLine();
if(lines[j].length()<dimensionsX){
System.err.println("we are doomed. Input malformed in line j: it has less then" + dimensionsX + "characters");
System.exit(1);
}
maze2[j] = lines[j].toCharArray();
System.out.println(lines[j]);
//System.out.println(j);
}else{
System.err.println("we are doomed. Input has too few lines");
System.exit(1);
}
}
//taken as is, but makes me wonder if it is intended to have dimensionsX as the Y coordinate but well...
for (int i = dimensionsX; i > 0; --i) {
for (int j = dimensionsY; j > 0; --j) {
System.out.print(maze2[j-1][i-1]);
}
System.out.println();
}
Of course you want to do something different than exiting the program if the input is malformed e.g. throw an exception, or do nothing at all if your input is always correct(well is it?).

Related

Reading a string splitting it and assigning values to 2D array in JAVA

I am trying to split a string with " "(space) and assigning each value on row to each respective array.
The input file contains:
4
2 2
1 3
4 7
3 4
The first line of the file has a single integer value N which is number of jobs.
The next N lines will represent a job, each with 2 values.
How do I start reading from second line from a Input file?
I want to split from Second line and assign it to 2D array. So if (2,2) is there on second line, then 2 should be assigned to array[0][0] and the other 2 to array[0][1]. For next line 1 should be assigned to array[1][0] and 3 should be assigned to array[1][1].
int num = scan.nextInt(); // taking number of jobs from first line
int[][] array = new int[num][num];
while (scan.hasNext()) //It reads till file has next line
{
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
}
Had done till here, couldn't figure out further.
int[][] array = new int[num][num];
Wrong dimensions of the array, for N = 4 you create array of 4 * 4, not 4 * 2.
Since the number of columns is fixed in your case, you should create array as new int[num][2] and update reading of the data accordingly.
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
Reading a line just to skip it may be redundant if you use Scanner to read the integer numbers using nextInt. So actually you do NOT need to read the data line by line, then split each line into String parts, and convert each part into a number because Scanner class takes care of it.
Also, the innermost loop tries to read N numbers per array row, while it's better to refer actual length of the array in the row.
Thus, it should be ok just to read the data according to the task using Scanner only:
int num = scan.nextInt(); // taking number of jobs from the first line
// preparing array of N rows and 2 columns
int[][] array = new int[num][2];
for (int i = 0; i < num; i++) {
for (int j = 0; j < array[i].length; j++) { // reading 2 ints per row
array[i][j] = scan.nextInt();
}
}
You can make it a lot easier by just ignoring the first line and letting Java do the hard work:
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import java.util.Arrays;
public class FileToArray {
public static void main(String[] args) {
try {
try (Stream<String> stream = Files.lines(Path.of("arr.txt"))) {
String[][] nums = stream.skip(1).map(s -> s.split(" ")).toArray(String[][]::new);
System.out.println(Arrays.deepToString(nums));
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}

I'm trying to count the percentage of every letter in a document by using a scanner, but I can't figure out how to correctly compute and display it

First I uploaded the file I'm using, the constitution. Then, I created two arrays, one for the length of the alphabet, the second to compute the frequency. I created a while loop to read every line in the document and count the frequency of every letter, I just can't figure out how to compute each as a percentage of each letter because after I'm going to put it into a bar chart.
int [ ]lettersLabels = new int [26];
int [ ]lettersFrequency = new int [26];
String line;
//initialize arrays
letterLabels = 0;
lettersFrequency = 0;
Scanner sc = new Scanner(constitution);
while(sc.hasNextLine())
{
line = sc.nextLine();
line = sc.toLowerCase();
char[] characters = line.toCharArray();
for (int i = 0; i< characters.length ; i++)
{
if((characters[i] >='a') && (characters[i]<='z'))
{
lettersLabels[characters[i] -'a' ]++;
}
}
}
for (int i = 0; i < 26; i++)
{
lettersFrequency = 'a' + [characters[i] -'a' ]++;
lettersFrequency = lettersFrequency / 100;
System.out.println(lettersFrequency);
}
Percentage is ratio * 100 (1/2 = 0.5 = (0.5 * 100)% = 50%), and the ratio here is lettersLabels[i] / totalLetters. So, in order to find the percentage, you just use lettersFrequency[i] = (double) lettersLabels[i] / (double) totalLetters * 100;. So, you might need a variable totalLetters at the beginning to count the number of letters.
You have a mistake in your code, which is initializing arrays with 0. You have already initialized the arrays with int[] arr = new int[26];, so you don't need those two lines, which will give an error since initializing arrays with an int is the wrong type. Also, when setting some part of lettersFrequency to something, you need to specify the index, like lettersFrequency[i], and instead of using characters when its out of scope to get the characters, so instead you have to use the letterLabels array.
Hope this works!
Here I've fix some of the errors with description see the code comments for explanation :
int [ ]lettersLabels = new int [26];
int [ ]lettersFrequency = new int [26];
String line;
int totalLetter =0; // needed to calculate %
// No need to initialize, it's already initialized with 0 values.
// remove those lines.
//initialize arrays
// letterLabels = 0;
// lettersFrequency = 0;
Scanner sc = new Scanner(constitution);
while(sc.hasNextLine())
{
line = sc.nextLine();
// need to lower case the current line
line = line.toLowerCase();
char[] characters = line.toCharArray();
for (int i = 0; i< characters.length ; i++)
{
if((characters[i] >='a') && (characters[i]<='z'))
{
// lets count the letter frequency.
totalLetter++;
lettersFrequency[characters[i] -'a' ]++;
}
}
}
// get rid of divide by zero exception
if(totalLetter ==0) totalLetter =1;
for (int i = 0; i < 26; i++)
{
char ch = 'a'+i;
// let's count the parentage of each letter.
double parcentage = (lettersFrequency[i]*100.00)/totalLetter;
System.out.println("parcentage of "+ ch+ " is: " +lettersFrequency +"%");
}

How can I create a new instance of array dynamically if my array size is full in java

I am working on a java program. where I have taken an input string and I am putting each char from a string in a 4*4 matrix. If the input string length is small than 16 i.e 4*4 matrix, then I am adding padding '#' char.
But Now, suppose the input string length is more than 16 then I want to create a new array and put remaining chars into it. I can't use a vector, set, map. So How can I code now?
here is some code. key=4.
char[][] giveMeNewArray() {
char[][] matrix = new char[key][key];
return matrix;
}
void putCharIntoMatrix() {
int counter = 0;
char[][] myArray = giveMeNewArray();
System.out.println("myArray: " + myArray);
for (int i = 0; i < key; i++) {
for (int j = 0; j < key; j++) {
if (counter >= inputString.length()) {
myArray[i][j] = '#';
} else {
myArray[i][j] = inputString.charAt(key * i + j);
}
counter++;
}
}
for (int i = 0; i < key; i++) {
for (int j = 0; j < key; j++) {
System.out.print(myArray[i][j] + " ");
}
System.out.println();
}
}
So if I'm understanding this question correctly, you want to create a matrix to hold the characters of an input string, with a minimum size of 4*4?
You're probably better off creating a proper matrix rather than expanding it:
Do you want your matrix to always be square?
Get the next-highest (self-inclusive) perfect square using Math.sqrt
int lowRoot = (int)Math.sqrt(inString.length());
int root;
if(lowRoot * lowRoot < inString.length())
root = lowRoot+1;
else
root = lowRoot;
Create your matrix scaled for your input, minimum four
int size = (root < 4) ? 4 : root;
char[][] matrix = new char[size][size];
But if you really want to expand it, you can just create a new matrix of a greater size:
char[][] newMatrix = new char[oldMatrix.length+1][oldMatrix[0].length+1];
And copy the old matrix into the new matrix
for(int i = 0; i < oldMatrix.length; ++i){
for(int j = 0; j < oldMatrix[i].length; ++j){
newMatrix[i][j] = oldMatrix[i][j];
}
}
If you expand by one each time you'll do tons of expands, if you expand by more you might expand too far.
This is really inefficient versus just doing some math at the beginning. Making a properly sized matrix from the start will save you a bunch of loops over your data and regularly having two matrices in memory.
If understand you request correctly, if the string length is bigger than 16 you just create a new array, well how about making a list of array initilized at one array and if there are more than 16 chars just add an array to the list using your method that returns an array.

How to determine ASCII value of a word

I am creating a program that imports a large list of words. This list has been separated by word but I now need to determine the ASCII value of each word in this list, and eventually which one has the highest total ASCII value. I am receiving a few errors and need to know how to get this corrected so that I can get each value.
public static void main(String[] args) throws IOException {
//import list of words
BufferedReader File = new BufferedReader(new FileReader(LOC));
//Create a temporary ArrayList to store data
ArrayList<String> words = new ArrayList<String>();
//Find number of lines in txt file
String line;
String delimiter = "\t";
while ((line = File.readLine()) != null)
//read the file
{
String[] wordsInLine = line.split(delimiter);
//separate the words
for(int i=0, isize = wordsInLine.length; i < isize; i++){
words.add(wordsInLine[i]);//put them in a list
//assess each character in the word to determine the ascii value
int total = 0;
for (int i=0; i < wordsInLine.length(); i++)
Receiving an error on the above line that states - Cannot invoke length() on the array type
String[]
- Duplicate local variable i
{
char c = word.charAt(i);
Receiving an error on the above line that states word cannot be resolved
int j = (int) c;
total += c;
}
I have done some research trying to determine the best way to calculate the ASCII value of each word and I haven't been able to find much information on how to do this. If someone could please take a look at my code I would appreciate it!! Also, before anyone says it let me just say this is NOT a school project. I am on summer break and beginning programming II in the fall and just trying to keep up on coding so that I am not rusty in the fall. THANK YOU!!! :))
Receiving an error on the above line that states - Cannot invoke length() on the array type String[] - Duplicate local variable i
wordsInLine is an array, and length is property of array. So, you have to use:
wordsInLine.length
If wordsInLine was a String, then wordsInLine.length() would have made sense.
Receiving an error on the above line that states word cannot be resolved
Before the line char c = word.charAt(i);, add below:
String word = wordsInLine[i];
For the wordsInLine.length() issue, length() is not a valid method for arrays. You actually have to access the length field thusly: wordsInLine.length without ().
As for word.charAt(i), you haven't declared a variable called word anywhere which is what's causing the problem. What you really want to do is sum up the values for every word in the array, and for that you need a nested loop.
You also said that you wanted to figure out which one had the highest value. To do that, just keep track of the largest one and update it after each iteration like this:
int indexOfMax = 0;
int[] sums = new int[wordsInLine.length];
//Iterate over every word
for(int i = 0; i < wordsInLine.length; i++)
{
//Reset the total for each word
total = 0;
//Iterate over every character in the word
for(int j = 0; j < wordsInLine[i].length(); j++)
{
char c = wordsInLine[i].charAt(j);
total += c;
}
//Remember the sum for this word
sums[i] = total;
//If the word's sum is greater than our previous max,
//make it the new max
if(sums[i] > sums[indexOfMax])
{
indexOfMax = i;
}
}
And now you can get the word with the greatest ASCII value by calling wordsInLine[indexOfMax]. It will have an ASCII sum of sums[indexOfMax].
wordsInLine is an array and therefore it does not have a method to get its length. Instead, to get an array's length, use array.length as opposed to what you were doing: array.length() (which causes an error).
word is not a defined variable, this is why java is saying that it cannot be resolved (it can't find any declaration). Instead you want to use 2 for loops in order to loop over every character in the word in the array wordsInLine. You also have two instances of the variable i, this is not allowed. To fix these errors write the following code after `int total = 0;':
int total = 0; // Don't rewrite this line
int[] totals = new int[wordsInLine.length]; // If you want to add all your totals to an array
for (int j=0; j < wordsInLine.length; j++) {
total = 0;
for (int k=0; k < wordsInLine[j].length(); k++) { // Here wordsInLine[j] is a string so you use .length() instead of .length
char c = wordsInLine[j].charAt(k);
int w = (int) c; // Get ascii of c
total += w; // Add it to total
}
// Do something with the total of this word before it gets reset to 0
// Maybe add it to an array of totals:
totals[j] = total;
}
I hope this helps!
Well your organization of your code needs a little bit of work.
First I would take this whole block of code outside file read in while loop.
for (int i=0; i < wordsInLine.length(); i++)
{
char c = word.charAt(i);
int j = (int) c;
total += c;
}
Why? Lets split what you are doing into two steps. Read in all the words into the word list. After doing this you will find where your core root of the problem is. You aren't reading the words from your word list at all.
Further code cleanup
for(int i=0, isize = wordsInLine.length; i < isize; i++){
This line is a little bit bloated. You don't need isize at all you are essentially doing denoting it for no reason. (Well actually caching the length does improve efficiency, another talk for another day). Cleaning up.
for(int i=0, ; i < wordsInLine.length; i++){
Then fixing the entire project
//import list of words
BufferedReader File = new BufferedReader(new FileReader(LOC));
//Create a temporary ArrayList to store data
ArrayList<String> words = new ArrayList<String>();
//Find number of lines in txt file
String line;
String delimiter = "\t";
// adds all the words into the list.
while ((line = File.readLine()) != null)
{
String[] wordsInLine = line.split(delimiter);
for(int i=0, ; i < wordsInLine.length; i++){
// compute alg and store the value some how to the word.
words.add(wordsInLine[i])
}
}
// notice outside the while loop.
// .size() is used for lists and .length is used for arrays.
for(int i = 0; i < words.size(); i++){
// compare
}

No Such Element Exception when reading from a file

I understand that this is a commonly asked question, however, I'm not sure why I'm getting the error even after doing research.
import java.io.*;
import java.util.*;
public class readfile {
private Scanner x;
public void openFile(){
try{
x = new Scanner(new File("input.txt"));
}
catch(Exception e){
System.out.println("Oh noes, the file has not been founddd!");
}
}
public void readFile(){
int n = 0;
n = Integer.parseInt(x.next()); //n is the integer on the first line that creates boundaries n x n in an array.
System.out.println("Your array is size ["+ n + "] by [" + n +"]");
//Create n by n array.
int[][] array = new int[n][n];
//While there is an element, assign array[i][j] = the next element.
while(x.hasNext()){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
array[i][j] = Integer.parseInt(x.next());
System.out.printf("%d", array[i][j]);
}
System.out.println();
}
}
}
public void closeFile(){
x.close();
}
}
I'm reading a text file that contains an adjacency matrix, where the first line indicates how large the matrix will be. ie) line 1 reads 5. Therefore I create a 2d array that is 5x5. The problem I'm having is after I read the file and print it, I get a NoSuchElement Exception. Thanks ahead of time!
Note: I am curious, I've seen that I need to user x.hasNext() when in a loop, so I do not assume there is input when there isn't. However, I've done this. Not sure what the problem is.
Output:
Your array is size [7] by [7]
0110011
1000000
1001000
0010001
0000001
1000001
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at readfile.readFile(readfile.java:32)
at verticies.main(verticies.java:8)
It looks like your code is reading a whole line as an int, is each of those numbers:
0110011 1000000 1001000 0010001 0000001 1000001
meant to be the 7 digits forming each row?
If that is the case, you need to split each value into the its component parts for its corresponding sub array.
In which case, use this section of code instead:
while(x.hasNext()){
for(int i = 0; i < n; i++){
String line = x.next();
for(int j = 0; j < n; j++){
array[i][j] = line.charAt(j) - '0';
System.out.printf("%d", array[i][j]);
}
System.out.println();
}
}

Categories

Resources