how to skip line when parsing text file? - java

This is the text file
gr.spinellis.ckjm.ClassVisitor 13 2 0 14 74 34 2 9
gr.spinellis.ckjm.ClassMetricsContainer 3 1 0 3 18 0 2 2
gr.spinellis.ckjm.MetricsFilter 7 1 0 6 30 11 2 5
gr.spinellis.ckjm.PrintPlainResults 2 1 0 2 8 0 1 2
gr.spinellis.ckjm.MethodVisitor 11 2 0 21 40 0 1 8
gr.spinellis.ckjm.CkjmOutputHandler 1 1 0 1 1 0 3 1
and this is the code I have written to pars through, I want to skip to one line in between the values, by the way I already skipped the first line by reading one line before entering the while loop .
package javaapplication39;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/* to read CSV file in Java. In this program we will read * list of metrics stored in CSV file as comma separated values. */
public class readallvalues {
public static void main(String... args) {
List<Metrics> metric = readMetricFromCSV("C:\\Users\\hp\\Desktop\\1.txt");
// let's print all the metric read from CSV file
for (Metrics m : metric) {
System.out.println(m);
}
}
private static List<Metrics> readMetricFromCSV(String fileName) {
List<Metrics> metricsss = new ArrayList<>();
Path pathToFile = Paths.get(fileName);
// create an instance of BufferedReader
// using try with resource, Java 7 feature to close resources
try (BufferedReader br = Files.newBufferedReader(pathToFile, StandardCharsets.US_ASCII)) {
br.readLine();
String line1=null;
// read the first line from the text file
String line = br.readLine();
while (line != null) { // loop until all lines are read
String[] attributes = line.split(" "); // the file, using a comma as the delimiter
Metrics valueOfMetric = createMetric(attributes);
metricsss.add(valueOfMetric); // adding metric into ArrayList
//skip empty line
// line.isEmpty() || line.trim().equals("") || line.trim().equals("\n"))
line = br.readLine();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return metricsss;
}
private static Metrics createMetric(String[] metadata) {
String name = metadata[0];
int WMC = Integer.parseInt(metadata[1]);
int DIT = Integer.parseInt(metadata[2]);
int NOC = Integer.parseInt(metadata[3]);
int CBO = Integer.parseInt(metadata[4]);
int RFC = Integer.parseInt(metadata[5]);
int LCOM= Integer.parseInt(metadata[6]);
int Ce = Integer.parseInt(metadata[7]);
int NPM = Integer.parseInt(metadata[8]);
return new Metrics(name,WMC,DIT,NOC,CBO,RFC,LCOM,Ce,NPM);//,cc
}
}
class Metrics {
private String name;
private int WMC;
private int DIT;
private int NOC;
private int CBO;
private int RFC;
private int LCOM;
private int Ce;
private int NPM;
public Metrics( String name,int WMC,int DIT,int NOC,int CBO,int RFC,int LCOM, int Ce, int NPM) {
this.name = name;
this. WMC =WMC ;
this. DIT =DIT ;
this. NOC = NOC;
this. CBO =CBO ;
this. RFC = RFC;
this.LCOM = LCOM;
this.Ce =Ce ;
this. NPM = NPM;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getWMC() { return WMC ; }
public void setWMC(int WMC) { this.WMC = WMC ; }
//WMC, DIT, NOC, CBO, RFC,LCOM, Ca, Ce, NPM,LCOM3,LOC, DAM, MOA, MFA, CAM,IC, CBM and AMC ,cc
public int getDIT() { return DIT ; }
public void setDIT(int DIT) { this.DIT = DIT ; }
public int getNOCC() { return NOC ; }
public void setNOC(int NOC) { this.NOC = NOC ; }
public int getCBO() { return CBO ; }
public void setCBO(int CBO) { this.CBO = CBO ; }
public int getRFC() { return RFC ; }
public void setRFC(int RFC) { this.RFC = RFC ; }
public int getLCOM() { return LCOM ; }
public void setLCOM(int LCOM) { this.LCOM = LCOM ; }
public int getCe() { return Ce ; }
public void setCe(int Ce) { this.Ce = Ce ; }
public int getNPM() { return NPM ; }
public void setNPM(int NPM) { this.NPM = NPM ; }
#Override
public String toString() {
return "name= " + name +" WMC= " + WMC + " DIT= " + DIT + " NOC " + NOC + " CBO " + CBO
+ " RFC " + RFC + " LCOM " + LCOM + " Ce " + Ce + " NPM " + NPM +"\n\n" ;//+ " cc " + cc
}
}

You are reading br.readLine(); outside the loop, just below the try with resource declaration, which skips the very first line.
Add br.readLine() call at the end of while loop, to skip empty line. Problem with this is it will also skip line with text if your file has two consecutive empty lines instead of one.
while ((line = br.readLine()) != null) {
//..logic
br.readLine();//add call to skip this line
}
You should better check whether line is empty or not to perform your logic.
while ((line = br.readLine()) != null) {
//trim will remove leading and trailing white space characters
if(!"".equals(line.trim()) {
//..logic
}
}
Apart from that you should follow naming convention, class name should start with capital case. So, your class name should be ReadAllvalues.

Related

Java - read file into array of objects

I am in need of some guidance. I am not sure how to go about reading in the sample text file into an array of objects. I know that the work needs to be in the while loop I have in main. I just do not know what I need to accomplish this.
I understand that I need to read in the file line by line (that's what the while loop is doing), but I don't know how to parse that line into an object in my array.
I know all of you like to see what people have tried before you help, but I honestly don't know what to try. I don't need a hand out, just some guidance.
Sample Text File:
100 3
120 5
646 7
224 9
761 4
Main:
public static void main(String[] args) {
Weight[] arrWeights = new Weight[25];
int count = 0;
JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
int returnValue = jfc.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
System.out.println(selectedFile.getAbsolutePath());
BufferedReader inputStream = null;
String fileLine;
inputStream = new BufferedReader(new FileReader(selectedFile.getAbsoluteFile()));
System.out.println("Weights:");
// Read one Line using BufferedReader
while ((fileLine = inputStream.readLine()) != null) {
count++;
System.out.println(fileLine);
}
System.out.println("Total entries: " + count);
}
}
Weight Class:
public class Weight {
private int pounds;
private double ounces;
private final int OUNCES_IN_POUNDS = 16;
public Weight(int pounds, double ounces) {
this.pounds = pounds;
this.ounces = ounces;
}
public boolean lessThan(Weight weight) {
return toOunces() < weight.toOunces();
}
public void addTo(Weight weight) {
this.ounces += weight.toOunces();
normalize();
}
public void divide(int divisor) {
if (divisor != 0) {
this.ounces = (this.toOunces() / divisor);
this.pounds = 0;
normalize();
}
}
public String toString() {
return this.pounds + " lbs " + String.format("%.3f", this.ounces) + " oz";
}
private double toOunces() {
return this.pounds * OUNCES_IN_POUNDS + this.ounces;
}
private void normalize() {
if (ounces >=16) {
this.pounds += (int) (this.ounces /OUNCES_IN_POUNDS);
this.ounces = this.ounces % OUNCES_IN_POUNDS;
}
}
}
I don't remember how to do that exactly in Java but I think this general guidance could help you:
In the while loop -
Parse the line you input from the read line using split function, you can use this as reference(first example can do the trick): http://pages.cs.wisc.edu/~hasti/cs302/examples/Parsing/parseString.html
Take the parsed line values, cast them to desired values per your class and create your object.
Append the created object to your list of objects: arrWeights

How to read from file and store array of objects while initializing each array elements using a constructor

I am trying to create program that shows 2 outputs to the screen.
The first one being null and the 2nd one, shows values from the input file that was stored in an array of objects.
Here is my code so far:
javax.swing.JOptionPane;
import java.util.Scanner;
import java.io.File;
public class Testing {
public static void main(String[] args) {
//error checking for commandline input
if(args.length != 1){
System.out.println("Please enter at least one input file into the argument.");
//terminates the program if more than 1 is entered
System.exit(1);
}
//make an array of bird objects
final Integer SIZE = 9;
HawaiiNativeForestBirds array[] = new HawaiiNativeForestBirds[SIZE];
//output array of Nature objects to the screen (should be "null" for all elements)
System.out.println("Hawai'i Native Forest Birds ");
System.out.println("index element ");
for (int i = 0; i < SIZE; i++) {
System.out.println(" " + i + " " + array[i] );
System.out.println();
//read from file and store data from file in your Nature array of objects
//by initializing each array element using the constructor
File file = new File(args[0]);
Scanner inputFromFile = null;
array[0] = new HawaiiNativeForestBirds("'akiapola'au"," hemignathus munroi"," yellow", 800);
array[1] = new HawaiiNativeForestBirds("akepa"," loxxops coccineus"," red", 9301);
array[2] = new HawaiiNativeForestBirds("hawai'i creeper"," oreomystis mana"," yellow green", 2501);
array[3] = new HawaiiNativeForestBirds("i'iwi"," vestiara conccinea"," red green", 2501);
array[4] = new HawaiiNativeForestBirds("apapane"," himatione sanguinea"," white red", 5001);
array[5] = new HawaiiNativeForestBirds("hawai'ian amakihi"," hemignathus virens"," yellow brown", 3001);
array[6] = new HawaiiNativeForestBirds("hawaii'an hawk"," buteo solitarius"," white gray", 1100);
array[7] = new HawaiiNativeForestBirds("puaiohi"," myadestes palmeri"," brown", 125);
array[8] = new HawaiiNativeForestBirds("anianiau"," magumma parva"," light yellow", 2000);
//use toString() to display the array again with data from input file
System.out.println("index name Scientific Name Color Population");
for(int x=0;x<SIZE;x++){
System.out.println(" " + i + " " + array[i]);
}
}//end of main() method
}// end of class LastnameFirstname08
/**
* Class HawaiianTheme stores and displays the data for each HawaiianTheme object
*
*
*/
class HawaiiNativeForestBirds {
// data fields that store each object's data
private String name;
private String scientificname;
private String color;
private Integer population;
//constructor - used to initialize the three data fields
/**
* Stores the name,scientific name, color and population of the Hawaiian Birds
* This is a Constructor, which is used to Create EAch Object & Initialize DAta Fields.
*
* #param
* #param
* #param
* #param
*/
public HawaiiNativeForestBirds(String birdName, String scientificName,String birdColor, Integer birdPopulation) {
name = birdName;
scientificname = scientificName;
color = birdColor;
population = birdPopulation;
}//end of constructor
//toString() method - returns a String with the 4 data fields
public String toString() {
String output = name +" "+ scientificname + " "+ color +" "+ population;
return output;
}//end of toString()
}//end of class HawaiianTheme
The only thing missing now is the method that reads from file and stores the array of objects by initializing the arrays.
I'm still no good at combining both of these and as you can see from the code, I don't have the method yet nor I know how the format would look like to combined both.
edit 2: I finally fixed my output . I initiliazed stuff, now how to read from file and store to the array? ;_;
Output:
Hawai'i Native Forest Birds
index element
0 null
1 null
2 null
3 null
4 null
5 null
6 null
7 null
8 null
9 null
index name Scientific Name Color Population
0 'akiapola'au hemignathus munroi yellow 800
1 akepa loxxops coccineus red 9301
2 hawai'i creeper oreomystis mana yellow green 2501
3 i'iwi vestiara conccinea red green 2501
4 apapane himatione sanguinea white red 5001
5 hawai'ian amakihi hemignathus virens yellow brown 3001
6 oma'o myadester obscurus gray 17001
7 hawaii'an hawk buteo solitarius white gray 1100
8 puaiohi myadestes palmeri brown 125
9 anianiau magumma parva light yellow 2000
All I want is to show two outputs but I gotta read and store the array of objects for the 2nd output
1.Display HawaiiNativeForestBirds array array[] without initializing elements:
2.Display HawaiiNativeForestBirds array[] again but shows the array values from the file after initializing elements:
edit:
My CSV Content:
birds.csv
Try reading in each String and storing it into its own index in a array of Strings. Then check out this algorithm and see if it works. I am sure this is not the best way to handle the situation, but I am in class and thought I would give it a intuitive shot. I am going off of the base that your constructor takes 4 parameters, and also assuming that the parameters in the txt file are in order of how they would be put into the constructor. You will also have to cast the 4th parameter into a int so it matches the expected argument type for your constructor.
//Create String array and use for loop to fill temp array with words from txt file
temp[i] = scan.next()
for(int i = 0; i < temp.length; i++) {
if (i != 0) {
i = i + 3;
HawaiiNativeForestBirds[i - (3*i/4)] = new HawaiiNativeForestBirds(temp[(i-4)+4], temp[(i-4)+5], temp[(i-4)+6], temp[(i-4)+7)];
}
else {
HawaiiNativeForestBirds[i] = new HawaiiNativeForestBirds(temp[i],temp[i+1], temp[i+2], temp[i+3]);
}
}
I would solve this problem in following way.
Create a HawaiiNativeForestBirds java class
class HawaiiNativeForestBirds {
private String name;
private String scientificname;
private String color;
private Integer population;
public HawaiiNativeForestBirds(){
}
public HawaiiNativeForestBirds(String name, String scientificname,
String color, Integer population) {
super();
this.name = name;
this.scientificname = scientificname;
this.color = color;
this.population = population;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getScientificname() {
return scientificname;
}
public void setScientificname(String scientificname) {
this.scientificname = scientificname;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Integer getPopulation() {
return population;
}
public void setPopulation(Integer population) {
this.population = population;
}
public String toString() {
String output = name +" "+ scientificname + " "+ color +" "+ population;
return output;
}
}
Edit: If you want read a csv file then you cans solve it as below:
Assuming csv file contains data in following format
puaiohi,myadestes palmeri,brown,125
puaiohi,magumma parva,yellow,2000
I have modified Testing class to read the csv file
public class Testing {
public static void main(String[] args) {
String csvFile = "birds.csv";
String line = "";
String cvsSplitBy = ",";
List<HawaiiNativeForestBirds> listofBirds = new ArrayList<HawaiiNativeForestBirds>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
// use comma as separator
String[] bird = line.split(cvsSplitBy);
HawaiiNativeForestBirds Hawaiinbird= new HawaiiNativeForestBirds(bird[0],bird[1],bird[2],Integer.valueOf(bird[3]));
listofBirds.add(Hawaiinbird);
}
} catch (IOException e) {
e.printStackTrace();
}
// First display null values
HawaiiNativeForestBirds[] hbirds=new HawaiiNativeForestBirds[listofBirds.size()];
System.out.println("index " + "element ");
int i=0;
for (HawaiiNativeForestBirds hbird:hbirds){
i++;
System.out.println(i+" "+hbird);
}
// Now display actual values
hbirds= listofBirds.toArray(new HawaiiNativeForestBirds[listofBirds.size()]);
System.out.println("index " + "name "+ "Scientific Name "+ "Color " + "Population ");
i=0;
for (HawaiiNativeForestBirds hbird:hbirds){
i++;
System.out.println(i+" "+hbird.toString());
}
}
}
Note: HawaiiNativeForestBirds class would remain as it is.

Java indexing error by increasing the frequency

I have a problem to increase frequency that the word occurs in each file,
I tested into 3 equal files and obtained different results in each.
Example: Each file the word "program" occurs 13 times
but the output I have is:
*the word in the search field as this "programa" and not program because of stemming function
[program]
----------------
Doc: site1.html Freq: 21
Doc: site2.html Freq: 11
Doc: site3.html Freq: 1
none of the outputs are correct.
The output had to be:
[program]
----------------
Doc: site1.html Freq: 13
Doc: site2.html Freq: 13
Doc: site3.html Freq: 13
Document class:
public class Documento {
private String docid;
private int frequencia;
public Documento(String docid, int frequencia) {
this.docid = docid;
this.frequencia = frequencia;
}
public String getDocid() {
return docid;
}
public int getFrequencia() {
return frequencia;
}
public void setFrequencia(int frequencia) {
this.frequencia = frequencia;
}
#Override
public boolean equals(Object o) {
if ((o instanceof Documento) && docid == ((Documento) o).docid && frequencia == ((Documento) o).frequencia) {
return true;
}
return false;
}
Function to insert and find document:
public class Dicionario {
public Map<String, List<Documento>> indice = new HashMap<>();
public void InsereDicionario(String palavra, String docid) {
if (!indice.containsKey(palavra)) {
indice.put(palavra, new ArrayList<Documento>());
indice.get(palavra).add(new Documento(docid, 1));
} else {
boolean inserido = false;
List<Documento> lista = indice.get(palavra);
for (int i = 0; i < lista.size(); i++) {
Documento d = lista.get(i);
if (d.getDocid().equals(docid)) {
// indice.get(palavra).add(new Documento(docid, 1));
inserido = true;
} else {
d.setFrequencia(d.getFrequencia() + 1);
}
System.out.println("");
}
if (!inserido) {
indice.get(palavra).add(new Documento(docid, 1));
}
}
}
public String Busca(String palavra) {
String saida = "";
System.out.println("Buscando [" + palavra + "]");
List<Documento> list = new ArrayList();
for (String p : indice.keySet()) {
if (p.equals(palavra)) {
list.addAll(indice.get(p));
for (Documento d : indice.get(p)) {
System.out.println("Doc: " + d.getDocid() + " Freq: " + d.getFrequencia());
saida += "Doc: " + d.getDocid() + " Freq: " + d.getFrequencia() + "".trim() + "\n";
}
}
}
return saida;
}
Function to call Buscar(Search function) in all words.
for (String palavra : query.split(" ")) {
resultado += ("\n[" + palavra + "]\n----------------\n");
resultado += dic.Busca(palavra.trim());
}
Look at this:
if (d.getDocid().equals(docid)) {
// indice.get(palavra).add(new Documento(docid, 1));
inserido = true;
} else {
d.setFrequencia(d.getFrequencia() + 1);
}
If dociid is found in the list -> then do nothning.
Otherwise (a current doc retrieved from the list is not equal to docid) -> then increment the counter.
Swap these operations, or use a negation in the condition.

How can I parse ASCII Art to HTML using Java or Javascript? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I saw that the Neo4j API uses ASCII Art very cleverly with its API:
http://jaxenter.com/getting-started-with-neo4j-the-java-graph-database-47955.html
I want to try something similar, but with ASCI Art to HTML. How can ASCII art be parsed, so for example, given an ASCII Art input something like:
--------------------------------
I I
I ------- ------- I
I I I I I I
I I A I I B I I
I I I I I I
I ------- ------- I
I I
I I
--------------------------------
: could result in HTML output something like:
<div>
<div style='display:inline;'>
A
</div>
<div style='display:inline;'>
B
</div>
</div>
Update
The question was closed citing that I need to "demonstrate a minimal understanding of the problem being solved.". I do have an understanding of the problem to be solved. The problem is that I want to solve is to make templated HTML easier to understand in source code for the following web framework:
https://github.com/zubairq/coils
: although the solution could be applied to any web framework. I have since seen someone attempt to make an initial version in C++ here:
https://github.com/h3nr1x/asciidivs2html/blob/master/asciidivs2html.cpp
: very impressive! If you can get it to work in Java or Clojure then if we can get the question reopened I will nominate a bounty so you can get more points for the solution :)
I ran the Java solution provided by #meewok and here is the result:
$ java AsciiToDIVs.RunConverter
Created a box(ID=0,X=0,Y=0,width=33,height=10)
Created a box(ID=1,X=2,Y=4,width=8,height=5,parent=0)
Created a char(Char=A,X=4,Y=7,parent=1)
Created a box(ID=2,X=2,Y=21,width=8,height=5,parent=0)
Created a char(Char=B,X=4,Y=24,parent=2)
<div><div><div>A</div></div><div><div>B</div></div></div>
Methodology
A solution to implement is the following:
create an in memory 2D array (array of arrays) which is similar to a chessboard.
Then i will create an algorith that when it detects "-" characters, i initialize acall to a method to detect the remaining corners ( top right, bottom left, bottom right) following the characters and where they end.
Example ( quick pseudocode ):
while(selectedCell==I)
selectedCell=selectedCell.goDown();
Using such a strategy you can map out your boxes and which boxes are contained within which.
Remaining would be to print this info as html..
Quick and Dirty Implementation
Since I was in the mood I spent an hour+ to quickly cook up a toy implementation.
The below is non-optimized in respect to that I do not make use of Iterators to go over Cells, and would need refactoring to become a serious framework.
Cell.java
package AsciiToDIVs;
public class Cell {
public char Character;
public CellGrid parentGrid;
private int rowIndex;
private int colIndex;
public Cell(char Character, CellGrid parent, int rowIndex, int colIndex)
{
this.Character = Character;
this.parentGrid = parent;
this.rowIndex = rowIndex;
this.colIndex = colIndex;
}
public int getRowIndex() {
return rowIndex;
}
public int getColIndex() {
return colIndex;
}
}
CellGrid.java
package AsciiToDIVs;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
public class CellGrid {
private ArrayList<ArrayList<Cell>> CellGridData;
public CellGrid(String asciiFile) throws IOException {
readDataFile(asciiFile);
}
public ArrayList<FoundObject> findBoxes(FoundBoxObject parent)
{
int startRowIndex = 0, startColIndex = 0,
parentRowLimit = Integer.MAX_VALUE,
parentColLimit = Integer.MAX_VALUE,
startingColIndex = 0;
if(parent != null)
{
startRowIndex = parent.getRowIndex()+1;
startColIndex = startingColIndex = parent.getColIndex()+1;
parentRowLimit = parent.getRowIndex() + parent.getHeight();
parentColLimit = parent.getColIndex() + parent.getWidth();
}
ArrayList<FoundObject> results = new ArrayList<FoundObject>();
Cell currentCell;
if(startRowIndex>=CellGridData.size())
return null;
for(; startRowIndex<CellGridData.size() && startRowIndex<parentRowLimit; startRowIndex++ )
{
startColIndex = startingColIndex;
for(; startColIndex< CellGridData.get(startRowIndex).size() && startColIndex<parentColLimit; startColIndex++)
{
FoundBoxObject withinBox = checkWithinFoundBoxObject(results, startRowIndex, startColIndex);
if(withinBox !=null)
startColIndex+=withinBox.getWidth();
currentCell = getCell(startRowIndex, startColIndex);
if(currentCell!=null)
{
if(currentCell.Character == '-') // Found a TOP-CORNER
{
int boxHeight = getConsecutiveIs(startRowIndex+1, startColIndex) + 1;
if(boxHeight>1)
{
int boxWidth = getConsecutiveDashes(startRowIndex, startColIndex);
FoundBoxObject box = new FoundBoxObject(startRowIndex, startColIndex, boxWidth, boxHeight, parent);
results.add(box);
findBoxes(box);
startColIndex+=boxWidth;
}
}
//This is a character
else if(currentCell.Character != '-' && currentCell.Character != 'I' && currentCell.Character != ' '
&& currentCell.Character != '\n' && currentCell.Character != '\n' && currentCell.Character != '\t')
{
FoundCharObject Char = new FoundCharObject(startRowIndex, startColIndex, parent, currentCell.Character);
results.add(Char);
}
}
}
}
if(parent!=null)
parent.containedObjects = results;
return results;
}
public static String printDIV(ArrayList<FoundObject> objects)
{
String result = "";
Iterator<FoundObject> it = objects.iterator();
FoundObject fo;
while(it.hasNext())
{
result+="<div>";
fo = it.next();
if(fo instanceof FoundCharObject)
{
FoundCharObject fc = (FoundCharObject)fo;
result+=fc.getChar();
}
if(fo instanceof FoundBoxObject)
{
FoundBoxObject fb = (FoundBoxObject)fo;
result+=printDIV(fb.containedObjects);
}
result+="</div>";
}
return result;
}
private FoundBoxObject checkWithinFoundBoxObject(ArrayList<FoundObject> results, int rowIndex, int colIndex)
{
Iterator<FoundObject> it = results.iterator();
FoundObject f;
FoundBoxObject fbox = null;
while(it.hasNext())
{
f = it.next();
if(f instanceof FoundBoxObject)
{
fbox = (FoundBoxObject) f;
if(rowIndex >= fbox.getRowIndex() && rowIndex <= fbox.getRowIndex() + fbox.getHeight())
{
if(colIndex >= fbox.getColIndex() && colIndex <= fbox.getColIndex() + fbox.getWidth())
{
return fbox;
}
}
}
}
return null;
}
private int getConsecutiveDashes(int startRowIndex, int startColIndex)
{
int counter = 0;
Cell cell = getCell(startRowIndex, startColIndex);
while( cell!=null && cell.Character =='-')
{
counter++;
cell = getCell(startRowIndex, startColIndex++);
}
return counter;
}
private int getConsecutiveIs(int startRowIndex, int startColIndex)
{
int counter = 0;
Cell cell = getCell(startRowIndex, startColIndex);
while( cell!=null && cell.Character =='I')
{
counter++;
cell = getCell(startRowIndex++, startColIndex);
}
return counter;
}
public Cell getCell(int rowIndex, int columnIndex)
{
ArrayList<Cell> row;
if(rowIndex<CellGridData.size())
row = CellGridData.get(rowIndex);
else return null;
Cell cell = null;
if(row!=null){
if(columnIndex<row.size())
cell = row.get(columnIndex);
}
return cell;
}
public Iterator<ArrayList<Cell>> getRowGridIterator(int StartRow) {
Iterator<ArrayList<Cell>> itRow = CellGridData.iterator();
int CurrentRow = 0;
while (itRow.hasNext()) {
// Itrate to Row
if (CurrentRow++ < StartRow)
itRow.next();
}
return itRow;
}
private void readDataFile(String asciiFile) throws IOException {
CellGridData = new ArrayList<ArrayList<Cell>>();
ArrayList<Cell> row;
FileInputStream fstream = new FileInputStream(asciiFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
// Read File Line By Line
int rowIndex = 0;
while ((strLine = br.readLine()) != null) {
CellGridData.add(row = new ArrayList<Cell>());
// System.out.println (strLine);
for (int colIndex = 0; colIndex < strLine.length(); colIndex++) {
row.add(new Cell(strLine.charAt(colIndex), this, rowIndex,colIndex));
// System.out.print(strLine.charAt(i));
}
rowIndex++;
// System.out.println();
}
// Close the input stream
br.close();
}
public String printGrid() {
String result = "";
Iterator<ArrayList<Cell>> itRow = CellGridData.iterator();
Iterator<Cell> itCol;
Cell cell;
while (itRow.hasNext()) {
itCol = itRow.next().iterator();
while (itCol.hasNext()) {
cell = itCol.next();
result += cell.Character;
}
result += "\n";
}
return result;
}
}
FoundBoxObject.java
package AsciiToDIVs;
import java.util.ArrayList;
public class FoundBoxObject extends FoundObject {
public ArrayList<FoundObject> containedObjects = new ArrayList<FoundObject>();
public static int boxCounter = 0;
public final int ID = boxCounter++;
public FoundBoxObject(int rowIndex, int colIndex, int width, int height, FoundBoxObject parent) {
super(rowIndex, colIndex, width, height);
if(parent!=null)
System.out.println("Created a box(" +
"ID="+ID+
",X="+rowIndex+
",Y="+colIndex+
",width="+width+
",height="+height+
",parent="+parent.ID+")");
else
System.out.println("Created a box(" +
"ID="+ID+
",X="+rowIndex+
",Y="+colIndex+
",width="+width+
",height="+height+
")");
}
}
FoundCharObject.java
package AsciiToDIVs;
public class FoundCharObject extends FoundObject {
private Character Char;
public FoundCharObject(int rowIndex, int colIndex,FoundBoxObject parent, char Char) {
super(rowIndex, colIndex, 1, 1);
if(parent!=null)
System.out.println("Created a char(" +
"Char="+Char+
",X="+rowIndex+
",Y="+colIndex+
",parent="+parent.ID+")");
else
System.out.println("Created a char(" +
",X="+rowIndex+
",Y="+colIndex+")");
this.Char = Char;
}
public Character getChar() {
return Char;
}
}
FoundObject.java
package AsciiToDIVs;
public class FoundObject {
private int rowIndex;
private int colIndex;
private int width = 0;
private int height = 0;
public FoundObject(int rowIndex, int colIndex, int width, int height )
{
this.rowIndex = rowIndex;
this.colIndex = colIndex;
this.width = width;
this.height = height;
}
public int getRowIndex() {
return rowIndex;
}
public int getColIndex() {
return colIndex;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
Main Method
public static void main(String args[])
{
try {
CellGrid grid = new CellGrid("ascii.txt");
System.out.println(CellGrid.printDIV(grid.findBoxes(null)));
//System.out.println(grid.printGrid());
} catch (IOException e) {
e.printStackTrace();
}
}
Update
The 'printDIV' should be like this (more '' were being printed than needed).
public static String printDIV(ArrayList<FoundObject> objects)
{
String result = "";
Iterator<FoundObject> it = objects.iterator();
FoundObject fo;
while(it.hasNext())
{
fo = it.next();
if(fo instanceof FoundCharObject)
{
FoundCharObject fc = (FoundCharObject)fo;
result+=fc.getChar();
}
if(fo instanceof FoundBoxObject)
{
result+="<div>";
FoundBoxObject fb = (FoundBoxObject)fo;
result+=printDIV(fb.containedObjects);
result+="</div>";
}
}
return result;
}
Here's a fairly simple solution in JavaScript, tested via Node. Of course, you'll need to adjust the input and output methods.
var s = "\n\
--------------------------------\n\
I I\n\
I ------- ------- I\n\
I I I I I I\n\
I I A I I B I I\n\
I I I I I I\n\
I ------- ------- I\n\
I I\n\
I I\n\
--------------------------------\n\
";
var lines = s.split('\n');
var outer_box_top_re = /--+/g;
var i;
for (i=0; i<lines.length; i++) {
while ((res = outer_box_top_re.exec(lines[i])) != null) {
L = res.index
R = outer_box_top_re.lastIndex
process_box(i, L, R)
}
}
function process_box(T, L, R) {
console.log('<div top="' + T + '" left="' + L + '" right="' + R + '">')
blank_out(T, L, R)
var i = T;
while (1) {
i += 1;
if (i >= lines.length) {
console.log('Fell off bottom of ascii-art without finding bottom of box');
process.exit(1);
}
var line = lines[i];
if (line[L] == 'I' && line[R-1] == 'I') {
// interior
// Look for (the tops of) sub-boxes.
// (between L+1 and R-2)
var inner_box_top_re = /--+/g;
// Inner and outer need to be separate so that
// inner doesn't stomp on outer's lastIndex.
inner_box_top_re.lastIndex = L+1;
while ((res = inner_box_top_re.exec(lines[i])) != null) {
sub_L = res.index;
sub_R = inner_box_top_re.lastIndex;
if (sub_L > R-1) { break; }
process_box(i, sub_L, sub_R);
}
// Look for any other content (i.e., a box label)
content = lines[i].substring(L+1, R-1);
if (content.search(/[^ ]/) != -1) {
console.log(content);
}
blank_out(i, L, R);
}
else if (line.substring(L,R).match(/^-+$/)) {
// bottom
blank_out(i, L, R);
break;
}
else {
console.log("line " + i + " doesn't contain a valid continuation of the box");
process.exit(1)
}
}
console.log('</div>')
}
function blank_out(i, L, R) {
lines[i] = (
lines[i].substring(0,L)
+ lines[i].substring(L,R).replace(/./g, ' ')
+ lines[i].substring(R)
);
}
What you want is the idea of 2-dimensional parsing, which detects 2D entities and verifies they have legitimate relationships.
See http://mmi.tudelft.nl/pub/siska/TSD%202DVisLangGrammar.pdf‎
What will be difficult is defining the sets of possible "ASCII Art" constraints.
Do only want to to recognize letters? Made only of the same-letter characters?
"cursive" letters? boxes? (Your example has boxes whose sides aren't made of the same
ASCII character). Boxes with arbitrary thick walls? Nested boxes? Diagrams with (thin/fat) arrows? Kilroy-was-here-nose-over-the-wall?
Pictures of Mona Lisa in which character pixels provide density relations?
What exactly do you mean by "ASCII art"?
The real problem is defining the range of things you intend to recognize. If
you limit that range, your odds of success go way up (see the referenced paper).
The problem here has little to to do specifically with Java or Javascript. This is far more related
to algorithms. Pick a limited class of art, choose the right algorithms, and then what you have is a coding problem which should be relatively easy to solve. No limits, no algorithms --> no amount of Javascript will save you.

Topological graph sorting java

I've got some problems with the topological sorting. It can find lops, but it counts some of the tasks (or "nodes" if you want to call it) several times. I think the problem is something with how I read or the Edge class, but I just can't see where it goes wrong. Any help would be really appreciated :)
enter code here
import java.util.*;
import java.io.*;
import java.lang.*;
class Task {
int id, time, staff;
int depA, depB;
String name;
int eStart, lStart;
Edge outEdge;
int cntPredecessors;
boolean visited;
Task(int id, String name, int time, int staff) {
this.id = id;
this.name = name;
this.time = time;
this.staff = staff;
visited = false;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}
class Edge {
Task id, name, time, staff;
Edge neste;
Task fra, til;
Edge(Task id) {
this.id = id;
}
}
class Input {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("enter a filename!");
System.exit(1);
} else if (args.length == 1) {
String fil = args[0]+".txt";
LesFraFil(fil);
// skrivUt();
topSort();
} else {
System.out.println("too many parameters, try again...");
}
}
static int antTask;
static Task[] ids;
static int tTid;
static void LesFraFil(String fil) {
int i = 0;
int j;
try {
String lest;
Scanner in = new Scanner(new FileReader(fil));
Edge til;
int counter = 0;
antTask = in.nextInt();
ids = new Task[antTask];
System.out.println(antTask);
while (in.hasNextLine()) {
lest = in.nextLine();
// hvis tom linje, så hopper den over
if(lest.trim().length() == 0) continue;
String split[] = lest.split("\\s+");
int id = Integer.parseInt(split[0]);
String act = split[1];
int tid = Integer.parseInt(split[2]);
int staff = Integer.parseInt(split[3]);
int depA = Integer.parseInt(split[4]);
tTid += tid;
ids[i] = new Task(id, act, tid, staff);
j = 4;
/*
* Lesingen av inputen skal avbrytes når den leser 0.
* j er den som holder på hvor langt vi er i split arrayet
* når den møter på 0
*/
while(split[j].compareTo("0") != 0) {
int tmp = Integer.parseInt(split[j])-1;
// System.out.println(tmp+1 + " Aktivitetens navn : " + act); //+ " tiden aktiviteten tar tid: " + tid + " avhengihet: " + split[j]);
j++;
if (ids[tmp] == null) {
ids[tmp] = new Task(id, act, tid, staff);
ids[tmp].visited = true;
}
ids[i].cntPredecessors++;
if(ids[tmp].outEdge == null) {
ids[tmp].outEdge = new Edge(ids[i]);
} else {
til = ids[tmp].outEdge;
while(til.neste != null) {
til = til.neste;
}
til.neste = new Edge(ids[i]);
}
}
counter++;
i++;
}
if (antTask == counter) {
System.out.println("Lesinga gikk som planlagt av fil: " + fil);
System.out.println("Total arbeidstid: " + tTid);// + antTask + " == " + counter );
} else {
System.out.println("Noe gikk galt avslutter!");
System.out.println(antTask + " || " + counter);
System.exit(2);
}
in.close();
} catch (Exception e) {
System.err.println("ERROR!" + e.getMessage());
}
}
static void skrivUt() {
for (Task sort : ids) {
System.out.print(sort.id + " " + sort.name);
Edge til = sort.outEdge;
while (til != null) {
System.out.print(" " + til.id.id);
til = til.neste;
}
System.out.println();
}
}
static void topSort() {
LinkedList<Task> list = new LinkedList<Task>();
ArrayList<Task> array = new ArrayList<Task>();
Task temp;
int count = 0;
int totalTime = 0;
// Legger taskene i lista
for (Task t : ids) {
if(t.cntPredecessors == 0) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
for (Task t : ids) {
if(t.cntPredecessors == 1) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
// går i evig løkke til lista er tom.
while (!list.isEmpty()) {
temp = list.pop(); // fjerner elementet fra lista
array.add(temp); // legger inn i arraylisten
count++;
// System.out.println(temp);
for(Edge til = temp.outEdge; til!=null;til=til.neste) {
til.id.cntPredecessors--;
if(til.id.cntPredecessors==0) {
list.add(til.id);
}
}
}
if(count < antTask) {
System.out.println("A loop has been found. Terminating...");
System.exit(0);
}
System.out.println("Topological sort: " + Arrays.toString(array.toArray()));// den sorterte "arraylisten"
System.out.println("Total time spend: " + totalTime);
}
} // End class Input
Here is an example of an input file
8
1 Build-walls 4 2 5 0
2 Build-roofs 6 4 1 0
3 Put-on-wallpapers 1 2 1 2 0
4 Put-on-tiles 1 3 2 0
5 Build-foundation 4 2 0
6 Make-floor 2 2 5 0
7 Put-carpet-floor 4 2 6 2 0
8 Move-in 4 4 3 7 0
The problem is with this loop (inside topSort()):
for (Task t : ids) {
if(t.cntPredecessors == 1) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
You just need to remove it.
Reason: this loop adds to list nodes that have 1 incoming edge. Later (in the while loop), it is possible that for these nodes the cntPredecessors field will be decreased to 0 which will make them being pushed back onto list, thus counted twice.
In the future, please try to narrow down your code to something that contains less "noise", that is: the smallset (or nearly smallest) code that illustrates the problem. This will ease the understanding on potential answerers (not to mention that it may help you see the problem yourself).

Categories

Resources