Im trying to scan a file and create a 1D array for each line, then immediately following the creation of that array copy into the first row of a 2D array. I've gotten my code to work for only the first row of the file. It won't move onto the next line. it copies the same line as it traverses the whole 2d array. i know that happens because the counter for the scanning the next line doesn't increase before it reaches the end of the 2d array. how can i increase the counter for scanning the next line? heres my code: (tempString is the 1D array already created before this loop)
for(int i = 0; i < 7; i++){
tempString = scnr.nextLine().split(" ");
//add lines to 2d array
for(int r = 0; r < 7; r++){
int x = 0; //moves along each element in tempString
for(int c = 0; c < tempString.length; c++){
temp[r][c] = Double.parseDouble(tempString[x]);
x++;
}
}
}
You have 3 loops, but you only need two. Each input row read from the file will become a row of the 2-D array :
for(int r = 0; r < 7; r++){
tempString = scnr.nextLine().split(" ");
temp[r] = new double[tempString.length];
for(int c = 0; c < tempString.length; c++){
temp[r][c] = Double.parseDouble(tempString[c]);
}
}
I am not quite sure with what exactly you need. But what I have derived from the question is that you have a file and you need to split it in a 2D array, in which the columns should contain the individual items within each line and each row should be in a new line.
My recommendation is to use ArrayList which will handle the dynamic lengths for you.
See the below example:
Say I have a file 'text.txt' which contains some data like this
abc def ghi
jhl mnop qrs uv
wx yz
Then here is a program which forms a 2D array, first dimension containing each row and the second dimension containing tokens from each line.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Split {
public static void main(String args[]){
ArrayList<ArrayList<String>> columns = new ArrayList<ArrayList<String>>();
columns.add(new ArrayList<String>());//Col 1
columns.add(new ArrayList<String>());//Col 2
columns.add(new ArrayList<String>());//Col 3
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader("src\\text.txt"));
String sCurrentLine;
int j=0;
while ((sCurrentLine = br.readLine()) != null) {
String sLine[] = sCurrentLine .split(" ");
for(int i = 0; i < sLine.length; i++)
{
columns.get(j).add(sLine[i]);
}
j++;
}
for(ArrayList<String> line:columns){
for(String tokens:line)
System.out.println(tokens);
System.out.println();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
If this is not what you need, please try to elaborate your question further if possible with examples.
Please note that I'm using spaces (" ") to split the tokens, you can replace it by anything that you are using.
I hope it helps :)
Related
I was working through a project and I have to use charAt to continuously add elements of an array from a text file to a new array that i would have specified. The size of the array differs depending on the text file being used so it is best to assume that the contents of the file are unknown, however i will provide an example.
I keep on getting a "StringIndexOutOfBoundException" when i run my code and i am not sure why, or how to fix it.
What the code should be doing is taking the user input to get the exact text file location, then it will be reading that line by line and adding that to a new array. The first two lines of the text file array are the array row and column size.
my code is as follows:
public static void main(String[] args) throws FileNotFoundException
{
System.out.println("Enter the location of the board file using the FULL PATH NAME.");
Scanner input = new Scanner(System.in);
String n = input.nextLine();
input.close();
File a = new File(n);
Scanner sc = new Scanner(a);
int row = sc.nextInt();
int col = sc.nextInt();
char[][] board = new char[row][col];
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
sc.close();
GridGame game = new GridGame (row, col, board);
game.playGame();
An example input text file:
10 10
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
SWWWWWWWWW
EEEEEEEEES
TWWWWWWWWW
The issue you are facing is because a Java array has 0-based index i.e. the index of the first element is 0 and that of the last element is array.length - 1. Therefore, your loop with the variable as the index of the array should not go beyond array.length - 1. Your terminating condition, numRow < row+1 is taking the value of numRow up to the length of the array instead of array.length - 1.
Replace
for (int numRow = 0; numRow < row+1; numRow ++)
{
String string = sc.next();
for (int numCol = 0; numCol < col+1; numCol++)
{
board[row][col] = string.charAt(numCol);
}
}
with
for (int r = 0; r < row && sc.hasNextLine(); r++) {
board[r] = sc.nextLine().toCharArray();
}
The other concept you need to understand is a 2-D array in Java an array of arrays i.e. board[0] should hold the array of characters from the first line of the file, board[1] should hold the array of characters from the second line of the file and so on. Now, if you want to access the 4th character of the 3rd line from the file, you can access it as board[2][3].
The last but not the least is regarding closing the Scanner for System.in. You should never close this Scanner because it also closes the System.in. So, you should remove the line, input.close() from your code.
Update
You can write the above mentioned single loop as a nested loop as well but it is unnecessary.
for (int r = 0; r < row && sc.hasNextLine(); r++) {
char[] lineChars = sc.nextLine().toCharArray();
for(int c = 0; c < col; c++) {
board[r][c] = lineChars [c];
}
}
You need a nested loop in order to access/process individual characters but to store/access/process each row of a 2-D array, you do not need a nested loop. As I have already mentioned, a 2-D array is an array of 1-D arrays and therefore to access each of these 1-D arrays (not individual elements inside these 1-D arrays), you need a single loop, not a nested loop.
https://drive.google.com/a/navasotaisd.org/file/d/0B3eMFMufj6uVaVNpR0JYNnV4OTQ/view
Okay, so the problem above asks that you read in a file with a message and, using and x, y coordinate system, find the characters being read in and print out the character of that index value. I honestly have tried multiple solutions with making and array of arraylists, a arraylist of arraylists and many other failed data structures. All I need to know, is how would go about reading in the message so that I can search for it?
File f = new File("cipher.in");
f.createNewFile();
Scanner scan = new Scanner(f);
int numOfLines = scan.nextInt();
scan.nextLine();
ArrayList<Character> list = new ArrayList();
String code = "";
for (int i = 0; i < numOfLines; i++) {
code = scan.nextLine();
for (int j = 0; j < code.length(); j++) {
list.add(code.charAt(j));
}
}
int index = 0;
char[][] matrix = new char[(int)(list.size())][(int)(list.size())];
for (int r = 0; r < matrix.length; r++) {
for (int c = 0; c < matrix[r].length; c++) {
matrix[r][c] = list.get(index);
index++;
if(index>=list.size())
index--;
}
}
Sorry if this problem is a bit long. It's for my class I need to turn this problem in to be able to make a 100 in the gradebook. I'm just utterly stuck and frustrated.
Try to use a hash table to store the data. You will be able to search for it later on.
The key fits quite nicely into a two-dimensional charcter array (char[][]). I would consider reading the first line (which specifies the number of lines on the key (rows of the array), and then construct the array. You have a constraint defined that a row can be no longer than 100 characters long so you can now define the complete "map".
After that i would read each line of the key, use an operator as charAt(index) and fill the map.
From there you have a very convenient structure to lookup the messages in the next part of the assignment.
Try this out , this is you code with changes and comments so that you can understand the changes and the way this code works based on the instruction in your link, I did not try to compile it, so if it has any compilation errors try to fix them. I kept your code and commented out the items that are not needed so that you can look at the differences,
File f = new File("cipher.in");
//f.createNewFile(); //* you are overwriting the file here
Scanner scan = new Scanner(f);
int numOfLines = scan.nextInt();
//str = scan.nextLine(); //* you just skipped one line from the numOfLInes
//ArrayList<Character> list = new ArrayList(); //* this does not help, you need to index into the line number, char index
TreeMap charMap = new TreeMap(); //* use this to map the line number to a char array
String code = "";
for (int i = 0; i < numOfLines; i++) {
strubg code = scan.nextLine();
charMap.put(i, code.toCharArray()); //* map the line number with the char array of each line
//for (int j = 0; j < code.length(); j++) {
// list.add(code.charAt(j));
//}
}
int numOfMessageLines = scan.nextInt(); //* get the number of message lines next
for (int i = 0; i < numOfMessageLines; i++) {
string str = scan.nextLine();
string[] pairs = str.split(" "); //* each line has several key pairs for line number char number seprated by spaces
ArrayList<char> list = new ArrayList(); //* this does not help, you need to index into the line number, char index
for(int j=0; j<pairs.length; j++)
{
string[] st = pairs[j].trim().split(","); //* example 2,13 indicate line 2 character 13 non zero indexed
int lineNum = Integer.parse(st[0]) - 1; //* zero indexed line number since we stored the lines in zero index map
int charNum = Integer.parse(st[1]) - 1; //* zero indexed char number since we stored the char array in zero indexed array
char[] chars = charMap.get(lineNum); //* get the char array for this line number
char c = chars[charNum]; //* get the character for the first message
list.add(c);
}
String message = new String(list.toArray()); //* construct the message from the char array
System.out.println(message);
}
//int index = 0;
//char[][] matrix = new char[(int)(list.size())][(int)(list.size())];
//for (int r = 0; r < matrix.length; r++) {
// for (int c = 0; c < matrix[r].length; c++) {
// matrix[r][c] = list.get(index);
// index++;
// if(index>=list.size())
// index--;
// }
//}
Im trying to read a txt file with numbers and saving each number in a String matrix but there some things i dont get.
1.-If i run the code in Eclipse i get printed like 16 times everything and the numbers get smaller and smaller..
2.-After beeing printed there is a null value on the bottom . why?
3.-Is it ok that the variable j is beeing defined outside the while loop? or should it be inside?
Thanks fot the help!
I wrote this so far:
The text file is contains the following:
0000000000000000
0000000000000000
0000000400000000
0001111111160000
0001115111110000
0001161121510000
0001111511110000
0001110001110000
0000011311000000
0000011111000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
and the programm:
package Tests;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
public class Test2 {
public static void main(String [] args){
try {
File fil = new File("/Users/MaxRuizTagle/Desktop/AbschlussprojektWiSe1415/Canberra Fox - The Key Huntress/lvl/level0.txt");
FileReader inputFil = new FileReader(fil);
BufferedReader in = new BufferedReader(inputFil);
String s = in.readLine();
int largo = s.length();
String [][] matrix = new String [largo][largo];
String line;
int j=0;
while ((line=in.readLine() ) != null){
for (int i=0;i<16;i++){
matrix[i][j] = line.substring(i);
}
j++;
}
for(int i=0;i<16;i++){
for( j=0;j<16;j++){
System.out.println(matrix[i][j]+" ");
}
System.out.println("");
}
}catch (IOException e1){
e1.printStackTrace();
}
}
}
1) The reason that 16 blocks of numbers are printed is that you print 16 blocks of numbers here:
for(int i=0;i<16;i++){
for( j=0;j<16;j++){
System.out.println(matrix[i][j]+" "); // <-- each one a line.
}
System.out.println("");
}
The reason that they get shorter is that you previously saved ever shorter substrings here:
for (int i=0;i<16;i++){
matrix[i][j] = line.substring(i); // <-- substring from pos i to end
}
You weren't very clear about your requirements, so I have to guess a little; it looks to me as though what you wanted to do was extract strings of one character each:
for (int i=0;i<16;i++){
matrix[i][j] = line.substring(i, i + 1); // substring from i to i + 1
}
And later print each column in a line (transposing the image):
for(int i=0;i<16;i++){
for( j=0;j<16;j++){
System.out.print(matrix[i][j]+" "); // print instead of println
}
System.out.println("");
}
Although I wonder why you bother with an array of Strings if you could use a char[][] matrix and line.charAt(i) or save the lines as they come and extract individual characters as lines[j].charAt(i) in the output loop.
2) You discard a line in the beginning:
String s = in.readLine();
int largo = s.length();
// s is not used after this
because of this, your matrix shrinks from 16x16 to 15x16, and the loop
while ((line=in.readLine() ) != null){
...
doesn't initialize the last column of matrix, which remains filled with nulls. The least invasive fix for that would be to, well, treat the first line in the loop like all others, as in
String line = s;
while(line != null) {
...
line = in.readLine();
}
3) I see no problem with that.
4) The way you treat your array dimensions is a bit odd. You appear to read them from the file, but later they're hard-coded. If your code is only going to work with a 16x16 matrix, why do you bother with largo, and if it should work with matrices of other sizes, why is the size of 16 hardcoded everywhere else?
2.-After beeing printed there is a null value on the bottom . why?
Because the first line is not put in the matrix, you only use that for s.length().
Then the while loop will use only the 15 remaining lines, instead of 16.
As a result, the last j index will have null values.
3.-Is it ok that the variable j is beeing defined outside the while loop? or should it be inside?
It's not great to be outside and reused. It's better to declare it inside.
Maybe you're looking for something more like this:
for (int j = 0; j < 16; j++) {
matrix[0][j] = String.valueOf(s.charAt(j));
}
for (int i = 1; (line = in.readLine()) != null; ++i) {
for (int j = 0; j < 16; j++) {
matrix[i][j] = String.valueOf(line.charAt(j));
}
}
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println("");
}
I have a .txt file with 1302 lines, which divides evenly to 14 x 93 (corresponding to 14 columns and 93 rows). I would like to parse the 1302 lines into a [93][14] multi-dimensional array. I have the following script that traverses each individual "cell", but as for the file parsing, I have some questions.
int rows = 93;
int columns = 14;
int i;
int j;
int count = 0;
String[][] array = new String[rows][columns];
for(i = 0; i < rows; i++){
for(j = 0; j < columns; j++){
System.out.println(i + "," + j);
count++;
}
}
How do I assign each "line" of the text file into each cell?
My Recommendation (aside from changing using double[][] to something like List<List<Double>>) would be to go through each text line as such:
InputStream fis;
BufferedReader br;
String line;
fis = new FileInputStream("the_file_name");
br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
while ((line = br.readLine()) != null) {
// Deal with the line
}
// Done with the file
br.close();
br = null;
fis = null;
With this, you should be able to get each individual 'line' of the file. The reason I mention above using the List<List<Double>> instead of double[][] is because you get two things out of that:
1) dynamic resizeability. Even if you know the size and want to give that list a default size to help with performance, you aren't LIMITED to that size, which is worth it's weight in.. flops? programmers gold.
2) using the primitive double (lowercase d) as opposed to the Java object Double (uppercase D) really kill you as far as not getting access to a LOT of great methods and useability built into Double (capitol D object). for more explanation on this, see: Double vs. double
Also note, the code above has no error checking, so you'll want to build some of that into it, it's a pretty basic implementation.
EDIT::
Alright, so in your code that you posted at: code snipped you have a double for-loop INSIDE of the readLine() loop. like so:
while ((line = br.readLine()) != null) {
for (int i = 0; i < rows; i++){
for(int j = 0; j< columns; j++){
line = array[i][j];
}
}
}
Now, there are two problems with this:
1) you are setting LINE equal to the content of array[i][j] which means nothing, since array is just an empty 2-dimensional array.
2) for EVERY line in the text file you are looping 1302 times (and then some more because you're doing (1302 * columns) * 1302
really what this code above does, is it takes care of your 'row' loop. so instead of what you're doing, just do:
int i = 0;
while ((line = br.readLine()) != null) {
array[i][0] = line;
i++
}
that will fill up your array with all of the strings from the file.
Read in the lines (rows) with Scanner or BufferedReader, then use split("\\s+"); to split the lines into tokens (columns). Then use Double.parseDouble() on each of the tokens and then insert it into your array.
In order to assign anything to a 2D matrix, you can do something like this:
for (int r=0; r<NUM_ROWS; r++)
for (int c=0; c<NUM_COLS; c++)
matrix[r][c] = get_line(r*NUM_COLS + c)
Where get_line(i) will get the i'th line in the file
I'm having trouble with this, maybe you could help me:
I have 3 strings like: word1, word2, word3 and I have to build a matrix with them, like this:
on the first row : word1("ABC"), second row: word2("DEF") and third row: word3("GHI").
A|B|C
D|E|F
G|H|I
I need this because after that I have to check if the formed words ("ADG","BEH","CFI") are in an array of words. And I don't know how to put those strings in the matrix so I can check. Any help is useful.
Thanks
Based on this comment:
the words have the same size, because the matrix is actually like a puzzle. I choose randomly 3 words from an array, put them in a matrix and check after that if the words resulted are from the same array.
I'll assume some things in order to make this work (since we don't have enough info):
You have an array of Strings where you have all the words
private String[] words;
You have a method to randomly pick up 3 Strings from this array.
private String s1, s2, s3;
public void pickThreeRandomWords() {
s1 = aRandomWord(words);
s2 = aRandomWord(words);
s3 = aRandomWord(words);
//or maybe another fancy algorithm to get this...
}
So you would need an array of array of chars based on these 3 Strings. This code could do the work for you:
public char[][] createMatrixFromStrings(String s1, String s2, String s3) {
char[][] theMatrix = new char[3][]; //yes, hardcoded
theMatrix[0] = s1.toCharArray();
theMatrix[1] = s2.toCharArray();
theMatrix[2] = s3.toCharArray();
return theMatrix;
}
Of course, if you would want to make this method to support more than 3 Strings you can make the method to receive a random quantity of Strings:
public char[][] createMatrixFromStrings(String ... strings) {
if (strings == null || strings.length == 0) return null;
char[][] theMatrix = new char[strings.length][];
int i = 0;
for(String s : strings) {
theMatrix[i++] = s.toCharArray();
}
return theMatrix;
}
You can build the result words without a matrix:
List<String> verticalWords = new ArrayList<String>();
for (int i = 0; i < horizontalLen; i++){
String currentWord = "";
for (int j = 0; j < wordCount; j++)
currentWord += words.get(j).get(i);
verticalWords.add(currentWord);
}
P.S. For the currentWord you can use a StringBuilder to make it more efficient, but I doubt it is highly needed here.
Java doesn't have matrix.It has array of array
So,you can try this
List<char[]> lst=new ArrayList();//stores a list of char[]
lst.add(("ADC".toCharArray()));//adds array of characters i.e 'A','D','C'
lst.add(("DEF".toCharArray()));
lst.get(0)[0];//A
lst.get(1)[0];//D
Now you can iterate vertically
for(int i=0;i<lst.size();i++)temp+=lst.get(i)[0];
temp would have AD which you can now cross check with equals method
The main thrust of this goal is that you're taking a one-dimensional value, and converting it into a two-dimensional value. There are many ways you can do this, but here are the two that come off the top of my head:
Set up a nested while loop to iterate over the first dimension, and when it reaches the length, reset and cause the outer loop to increment, much like a clock
You can create a new subarray using ArrayUtils.toSubArray(), and with some finagling, get that to work:
Create a new row of the array each time, based on the dimension slices you want to hit up. I'll leave figuring this one out as an exercise for the reader. But here's a hint:
for(int i = 0; i < theDimension; i++, j += 3) {
ret[i] = ArrayUtils.subarray(word, i*theDimension, j);
}
Lastly, I assume that there's a restraint on the type of input you can receive. The matrix must be square, so I enforce that restriction before we build the array.
I strongly encourage you to poke and prod this answer, and not just blindly copy it into your schoolwork. Understand what it's doing so you can reproduce it when you're asked to again in the future.
public char[][] toMatrix(int theDimension, String theEntireWord) {
if(theEntireWord.length() != theDimension * theDimension) {
throw new IllegalArgumentException("impossible to add string to matrix of uneven dimension");
}
char[][] ret = new char[theDimension][theDimension];
int i = 0;
int j = 0;
while(i < theDimension) {
if(j == theDimension) {
j = 0;
++i;
} else {
ret[i][j] = theEntireWord.charAt((i * theDimension) + j);
j++;
}
}
return ret;
}
I think this will sort your problem.
package printing;
public class Matrix {
public static void main(String[] args) {
//Length can define as you wish
String[] max = new String[10];
String[] out = null;
//Your Inputs
max[0]="ADG";
max[1]="BEH";
max[2]="CFI";
//following for loop iterate your inputs
for (int i = 0; i < max.length; i++) {
if(out==null){out= new String[max.length];}
String string = max[i];
if(string==null){ break;}
//Here breaking input(words) one by one into letters for later contcatnating.
String[] row = string.split("");
for (int j = 0; j < row.length; j++) {
String string1 = row[j];
// System.out.println(string1);
//create the values for rows
if(out[j]!=null){ out[j]=out[j]+string1;}
else{
out[j]=string1;
}
}
}
//following for loop will out put your matrix.
for (int i = 0; i < out.length; i++) {
String string = out[i];
if(out[i]==null){break;}
System.out.println(out[i]);
}
}
}