Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
EDIT: I have tried to store the lines character by character into a 2D Array.
However, the problem is to get all possible paths of a maze from 0 to 1 inside of a text file. And the asterisk are the walls or obstacle.
Maze looks like this
8,8
********
*0 *
* *
* ** *
* ** *
* *
* 1*
********
I'm not sure if it's achievable to put it into a Two Dimensional Array string. And do a recursion or dynamic programming afterwards.
Note that the only movements allowed is right and down, also the 0 destination could be somewhere on 2nd, 3rd and so on column. Same as 1 destination as well.
Any tips or suggestions will be appreciated, thank you in advance!
Yep, this is fairly easy to do:
Read the first line of the text file and parse out the dimensions.
Create an array of length n.
For every (blank) item in the array:
Create a new length-n array as the data.
Parse the next line of the text file as individual characters into the array.
After this, you'll have your n x n data structure to complete your game with.
Using a Map to store this File Seems like a good idea.
While I don't think reading a file character by character would be an issue,
BufferedReader br = new BufferedReader(new FileReader(file));
String line = br.readLine();
You have specified the grid dimensions say (n x n)
A Simple way I could visualize is by generating unique keys for every coordinate.
More like a Parser method to store Keys in the Map:
public String parseCoordinate(int x, int y){
return x + "" + y;
}
Map<String, Boolean> gridMap = new HashMap<>();
So when you read file by Characters, you could put parsed coordinates as keys in the map:
gridMap.put(parseCoordinate(lineCount, characterCount), line.charAt(characterCount) == '*');
I'm assuming the only problem you are facing is to decide how to read the file correctly for processing or applying the algorithm to determine the number of unique paths in the given maze.
private static int[][] getMatrixFromFile(File f) throws IOException {
//Read the input file as a list of String lines
List<String> lines = Files.lines(f.toPath())
//.map(line -> line.substring(1 , line.length() - 1))
.collect(Collectors.toList());
//Get the dimensions of the maze from the first line
String[] dimensions = lines.get(0).split("\\*");
//initalize a sub matrix of just the maze dimensions ignoring the walls
int[][] mat = new int[Integer.valueOf(dimensions[0]) - 2 ][Integer.valueOf(dimensions[1]) - 2];
//for each line in the maze excluding the boundaries , if you encounter a * encode as 0 else 1
for( int i = 2 ; i < lines.size() - 1 ; i++) {
String currLine = lines.get(i);
int j = 0;
for(char c : currLine.toCharArray())
mat[i - 2][j] = (c == '*') ? 0 : 1;
}
return mat;
}
With this in place you can now focus on the algorithm for actually traversing the matrix to determine the number of unique paths from top-right to bottom-left.
Having said that , once you have the above matrix you are not limited to traversing just top-right to bottom-left , rather any arbit point in you maze can serve as start and end points.
If you require help with figuring out the number of unique paths , i can edit to include the bit , but Dynamic programming should help in getting the same.
private char[][] maze;
private void read() {
final InputStream inputStream = YourClass.class.getResourceAsStream(INPUT_PATH);
final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
final String header = reader.readLine();
final String[] tokens = header.split(",");
if (tokens.length < 2) {
throw new RuntimeException("Invalid header"); // Use a dedicated exception
}
final int dimX = parseInt(tokens[0]);
final int dimY = parseInt(tokens[1]);
maze = new char[dimX][dimY];
for (int i = 0; i < dimY; i++) {
final String line = reader.readLine();
maze[i] = line.toCharArray();
}
} catch (final IOException e) {
// handle exception
} finally {
try {
reader.close();
} catch (IOException e) {
// handle exception
}
}
}
Now, some assumptions: I assumed the first line contains the declaration of the maze size, so it will be used to initialize the two dimensional array. The other assumption is that you can make use of a char array, but that's pretty easy to change if you want.
From here you can start working on your path finding algorithm.
By the way, this thing you're trying to implement reminds me a lot of this challenge in the Adventofcode challenge series. There are a lot of people discussing their solutions to the challenge, just have a look in Reddit for instance and you'll find plenty oh tips on how to go on with your little experiment.
Have fun!
Related
I want to read term from clueweb09 corpora and find its position to check that term is an entity or not based on dataset that was created here. They claim they calculate the position based on:
**" The zero (0) location used for calculating the annotation offsets is the beginning of the HTTP headers*. This is the first byte after the WARC document header."* .
I calculate the length of each term by calling term.getBytes().length function and sum all positions to find the position of the entity. Unfortunately my position is about 400 byte less than the reported position. I calculate position by reading each warcfile file based on following code.
ArrayList<Integer> pos = new ArrayList<Integer>();
int position=-1;
String text;
try{
FileReader fileReader = new FileReader("05");
BufferedReader bufferedReader = new BufferedReader(fileReader);
while(true){
String line= bufferedReader.readLine();
if(line==null)
break;
else
{
int index=line.indexOf(word);
if(index==-1)
position=position+line.getBytes().length;
else{
int poss= position +index;
pos.add(poss);
position=position+line.getBytes().length;
}
}
}
bufferedReader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
Could you please tell me what is the problem(s)?
To Find a position of the Clueweb dataset terms in byte I used this code which implement the annotation version of this data set here. The lemur.cw.ann.DetectEncoding class returns the annotation which are not match with clueweb dataset based on their positions. I change that class and lemur.cw.ann.Matcher class to calculate the postion of the Clueweb terms based on byte offset.
I'm trying to read my file in notepad using CSVReader but I cannot get it work. it says ArrayIndexOutOfBoundsException: 2 line "y[i][2]". eventhough I intiallize my array rows in 100. I'm currently new in using Java and CSVReader.
public static void main(String[] args) throws IOException {
double[][] x = new double[100][3];
double[][] y = new double[100][1];
String line[];
try{
CSVReader br=new CSVReader(new FileReader("ex2data2.txt"),',');
int i = 0;
while((line=br.readNext())!=null){
x[i][0] = Double.parseDouble(line[0]);
x[i][1] = Double.parseDouble(line[1]);
y[i][2] = Double.parseDouble(line[2]);
i++;
}
br.close();
}
catch (IOException e) {
e.printStackTrace();
}
It's completely unclear as to why you would be storing the data as you are after reading it from the file, but ...
double[][] y = new double[100][1];
This allocates an array of 100 double arrays, each with a length of 1
Here:
y[i][2] = Double.parseDouble(line[2]);
You attempt to store something at the third element of one of those 100 arrays. They aren't that large; you created them to have a length of one.
I suspect you meant to do:
y[i][0] = Double.parseDouble(line[2]);
since the only thing you're storing in the y arrays is that single value.
All that being said, this is a poor way to store these values. In general you are better served using a dynamic data structure so you don't have to worry about what the length (number of lines) of the file is. In addition, why would you need two different 2D arrays? Even a List<Double[]>, for example, would be better.
You have create
double[][] y = new double[100][1];
i.e. 100 rows and 1 column. but trying to put value at position y[i][2]. thats why you are getting ArrayIndexOutOfBoundsException. create like
double[][] y = new double[100][3];
or you can simply put value as (in this case you don't need to create 2D array given as above)
y[i][0] = Double.parseDouble(line[2]);
I got a task. The input of the Java Decathlon program is a CSV-like text file. The task is to output an XML file with all athletes in ascending order of their places, containing all the input data plus total score and the place in the competition (in case of equal scores, athletes must share the places, e.g. 3-4 and 3-4 instead of 3 and 4)
This is my cvs file:
Jana Kari;12.61;5.00;9.22;1.50;60.39;16.43;21.60;2.60;35.81;5.25.72
Eva Narun;13.04;4.53;7.79;1.55;64.72;18.74;24.20;2.40;28.20;6.50.76
Maja Hope;13.75;4.84;10.12;1.50;68.44;19.18;30.85;2.80;33.88;6.22.75
Kirke Kanda;13.43;4.35;8.64;1.50;66.06;19.05;24.89;2.20;33.48;6.51.01
I got these constants for each decathlon event
double[] A = new double[]{25.4347,0.14354,51.39,0.8465,1.53775,5.74352,12.91,0.2797,10.14,0.03768};
double[] B = new double[]{18,220,1.5,75,82,28.5,4,100,7,480};
double[] C = new double[]{1.81,1.4,1.05,1.42,1.81,1.92,1.1,1.35,1.08,1.85};
Formula for points is
Points = INT(A(B — P)^C) for track events (faster time produces a better score)
Points = INT(A(P — B)^C) for field events (greater distance or height produces a better score)
"P" is persons records (from cvs). I dont really understand how to read properly from file that it would allow me to do calculations with numbers only. Should i use two dimensional array for cvs file ? Its very confusing and im stuck.
EDIT
Well i believe for outputing later to xml file one dimensional array is better. The point of my task is code simplicity, but CVS file may be expanded to N lines so i never know how much rows it will have. I want to use number array in this code:
double[] A = new double[]{25.4347,0.14354,51.39,0.8465,1.53775,5.74352,12.91,0.2797,10.14,0.03768};
double[] B = new double[]{18,220,1.5,75,82,28.5,4,100,7,480};
double[] C = new double[]{1.81,1.4,1.05,1.42,1.81,1.92,1.1,1.35,1.08,1.85};
double PTS;
double finalscore;
for (int i = 0; i < P.length;i++ )
{
finalscore=0;
if (i == 0)
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
else if (i == 4)
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
else if (i == 5 || i == 9)
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
else
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
finalscore = finalscore + PTS;
}
System.out.println(finalscore);
}
}
Where P[] would be array first lane of number without name.
P.S it seems code above gives me result NaN when i use
double[] P = new double[]{12.61,5.00,9.22,1.50,60.39,16.43,21.60,2.60,35.81,5.272};
Yes, you have the right idea - you can use a two dimensional array. I would also recommend you create a class called Person, as this is Java programming and Java is object-oriented, but if you have not studied creating multiple classes yet, you can skip that bit and just do it with two arrays, one one-dimensional array for the names and one two-dimensional array for the numbers.
For the one-dimensional array approach
public class Person {
String name;
double[] scores;
int minutes;
int seconds;
int hundredths;
public Person(String line) {
String[] splitted = line.split(";");
name = splitted[0];
// now fill in the other fields
for(int i = 1; i < splitted.length - 1; i++) {
scores[i - 1] = Double.parseDouble(splitted[i]);
}
String times = splitted[splitted.length - 1].split("\\.");
minutes = Integer.parseInt(time[0]);
// etc. - fill in the rest
}
}
(Actually, this might be wrong, because I assumed most of the numbers are scores, but I guess they are really seconds and hundredths of a second. It doesn't really matter, unless you could have a time over one minute for those events.)
Then you need to have an array of Person objects in your other class - let's make it quite big so that it will be big enough hopefully:
Person[] array = new Person[10000];
Now have a loop, and whenever you read a line from the file you just call the constructor.
array[j] = new Person(line);
Nice approach, isn't it?
I've got an issue getting a method to read a file, then converting it to an integer. Here is a brief explanation of the program. It is essentially a car dealership inventory that keeps track of the vehicles in the lot by keeping them written down in a text file. When the program starts it will need to read the file and put all the current cars into an array so they can be displayed. Then the rest of the program will do other things like remove cars and add news ones etc. The part I am at is when the program first starts it needs to read the file, but I can't seem to get it to work.
The text file consists of 6 lines in total; 4 numbers first then 2 words respectively. I want the method to read the first four lines and convert those into integers and store them in a temporary array. Then after that it will read the next two lines and store those in a temporary array as well. Afterwards I take all these stored values and send them to a constructor. The constructor is then stored in an Arraylist and the Arraylist can be accessed anytime. In the output it does all of this just fine. But it wants to run through the method a second time despite barriers in place to prevent this.
Here is the code. Its a class and not the main program. I will try to explain the program as best I can inside the code.
public class Vehicle {
//All the different private variables for the constructors and methods
private int intholder[], year, type, kilometres, price, loop;
private String make, model, myline, holder[];
//The Arraylist that the different vehicle objects will be stored
ArrayList<Vehicle> allCars = new ArrayList<Vehicle>();
//The Default constructor
public Vehicle(){
make = "Vehicle Make";
model = "Vehicle Model";
type = 0;
year = 0;
kilometres = 0;
price = 0;
}
//The constructor that has information sent to it
public Vehicle(int _type, int _year, int _kilometres, int _price, String _make, String _model){
make = _make;
model = _model;
type = _type;
year = _year;
kilometres = _kilometres;
price = _price;
}
//Text file information
/*
* CAR TYPE CODE:
* 1 - Sedan
* 2 - Truck
* 3 - Crossover
* 4 - SUV
* 5 - Sports
*
* There is a total of 6 lines for each car and are as follows
* 1 - int Type integer
* 2 - int Year
* 3 - int Kilometres
* 4 - int Asking price
* 5 - String Make
* 6 - String Model
*/
//The method in question. It reads through the file, converts the integers and stores them,
//stores the strings, and sends all the information to the constructor
public void readCars()throws IOException{
BufferedReader readFile = new BufferedReader(new FileReader("C:/Users/David/Desktop/FinalProject/Carlot.txt"));
//Setting the length of the temporary arrays
holder = new String[2];
intholder = new int[4];
//The main loop in the method.
do{
//Read the first 4 lines of the file and convert them to integers.
//The try catch shouldn't have to be there because the first 4 lines
//of the file are all numbers, but I put it in there to see when it was messing up.
for(int i = 0; i < 4; i++){
myline = readFile.readLine();
try{
intholder[i] = Integer.parseInt(myline);
}
catch(NumberFormatException e){
System.out.println(e);
}
//Had this in here to see how many lines down the file it would go before messing up.
System.out.println(myline);
}
//Loop to store the Strings
for(int i = 0; i < 2; i++){
myline = readFile.readLine();
holder[i] = myline;
System.out.println(myline);
}
//Sends all the data to the constructor
Vehicle V = new Vehicle(intholder[0], intholder[1], intholder[2], intholder[3], holder[0], holder[1]);
//Several if statements to determine which subclass of vehicle it is.
if(intholder[0]==1){
Sedan S = new Sedan();
allCars.add(S);
}
else if(intholder[0]==2){
Truck T = new Truck();
allCars.add(T);
}
else if(intholder[0]==3){
Crossover C = new Crossover();
allCars.add(C);
}
else if(intholder[0]==4){
SUV U = new SUV();
allCars.add(U);
}
else if(intholder[0]==5){
Sports P = new Sports();
allCars.add(P);
}
//Only break the loop if the myline equals null
}while(myline != null);
//if the loop breaks, close the file
readFile.close();
}
Now I think I know where it is going wrong. At the end of the do/while, it checks if "myline" is null. And because the last time it read the file it was still a String the loop continues. The last time it goes through the loop, everything is null so trying to convert the integer is impossible so I get errors. But I have no idea how to get it to read the file at the end of the loop without going to the next line. Here is what the text file looks like.
1
2007
150250
5000
Toyota
Corolla
2
2005
240400
4500
Chevorlet
Silverado
I can't have it read at the end of the loop because if it does and there are still more cars after the one I just did, It goes into the next line when the loop restarts everything is thrown off.
Any help is appreciated, Thanks!
Use a labeled break statement in your for loops to simply exit out of the main do while loop when myline becomes null. The way other objects are being instantiated within the loop doesn't leave much room for easy refactoring hence the use of a labeled break makes sense here.
outerloop:
do {
for (int i = 0; i < 4; i++) {
if ((myline = readFile.readLine()) == null) break outerloop;
// ..
}
for (int i = 0; i < 2; i++) {
if ((myline = readFile.readLine()) == null) break outerloop;
// ..
}
// ..
} while (myline != null);
Maybe you could use a while loop instead of a do-while loop and read the next line from the file before anything else. Something like this:
String myline = null;
while( (myline = readFile.readLine()) != null ) {
// All your logic...
}
readFile.close();
The condition of while loop does the following: first, read the next line of the file with myline = readFile.readLine(). The previous statement returns the value of myline, so now we check that it is not null with the comparison:
(myline = readFile.readLine()) != null
I am really struggling with parsing a text file. I have a text file which is in the following format
ID
Float Float
Float Float
.... // variable number of floats
END
ID
Float Float
Float Float
....
END
etc However the ID can represent one of two values, 0 which means it is a new field, or -1 which means it is related to the last new field. The number of times a related field can repeat it self is unlimited. Which is where the problem is occurring.
As I have a method in a library which takes an ArrayList of the new Floats, then an ArrayList of an ArrayList of the related floats.
When I try and code the logic for this I just keep getting deeper and deeper embedded while loops.
I would really appreciate any suggestions as to how I should go about this. Thanks in advance.
Here is the code I have so far.
BufferedReader br = new BufferedReader(new FileReader(buildingsFile));
String[] line = br.readLine().trim().split(" ");
boolean original = true;
while(true)
{
if(line[0].equals("END"))
break;
startCoordinate = new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1]));
while(true)
{
line = br.readLine().trim().split(" ");
if(!line[0].equals("END") && original == true)
polypoints.add(new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1])));
else if(!line[0].equals("END") && original == false)
cutout.add(new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1])));
else if(line[0].equals("END") && original == false)
{
cutouts.add(cutout);
cutout.clear();
}
else if(line[0].equals("-99999"))
original = false;
else if(line[0].equals("0"))
break;
}
buildingDB.addBuilding(mapName, startCoord, polypoints, cutouts);
}
New Code
int i = 0;
BufferedReader br = new BufferedReader(new FileReader(buildingsFile));
String[] line;
while(true)
{
line = br.readLine().trim().split(" ");
if(line[0].equals("END"))
break;
polygons.add(new Polygon(line));
while(true)
{
line = br.readLine().trim().split(" ");
if(line[0].equals("END"))
break;
polygons.get(i).addCoord(new Coordinate(Double.parseDouble(line[0]), Double.parseDouble(line[1])));
}
i++;
}
System.out.println(polygons.size());
int j = 0;
for(i = 0; i< polygons.size(); i++)
{
Building newBuilding = new Building();
if(polygons.get(i).isNew == true)
{
newBuilding = new Building();
newBuilding.startCoord = new Coordinate(polygons.get(i).x, polygons.get(i).y);
}
while(polygons.get(i).isNew == false)
newBuilding.cutouts.add(polygons.get(i).coords);
buildings.add(newBuilding);
}
for(i = 0; i<buildings.size(); i++)
{
System.out.println(i);
buildingDB.addBuilding(mapName, buildings.get(i).startCoord, buildings.get(i).polypoint, buildings.get(i).cutouts);
}
Maybe you should use map for new floats and related floats..if got your question it should help..example:
HashMap hm = new HashMap();
hm.put("Rohit", new Double(3434.34));
I assume that a "field" means an ID and a variable number of coordinates (pairs of floats), that, judging from your code, represents a polygon in fact.
I would first load all the polygons, each into a separate Polygon object:
class Polygon {
boolean isNew;
List<Coordinate> coordinates;
}
and store the polygons in another list. Then in a 2nd pass go through all the polygons to group them according to their IDs into something like
class Building {
Polygon polygon;
List<Polygon> cutouts;
}
I think this would be fairly simple to code.
OTOH if you have a huge amount of data in the file, and/or you prefer processing the read data little by little, you could simply read a polygon and all its associated cutouts, until you find the next polygon (ID of 0), at which point you could simply pass the stuff read so far to the building DB and start reading the next polygon.
You can try using ANTLR here, The Grammar defines the format of the text you are expecting and then you can wrap the contents in a Java object. The * and + Wildcards will resolve the complexity of while and for. Its very simple and easy to use, you dont have to construct AST you can take the parsed content from java objects directly. But the only overhead is you have to add the ANTLR.jar to your path.