I have a file which has millions of vertices and around billions of edges and its format as edgelist is as follows :
7 5
1 2
2 4
2 5
3 6
3 7
this graph is undirected however I need to change the graph into directed and adjacency list and weighted (each edge has weight 1) form as follows:
7 5
2 1
1 1 4 1 5 1
6 1 7 1
2 1
2 1
3 1
3 1
It has a header with the number of vertices and edges.
I have implemented a code like this using hashmap. However, in very large graphs when the edges exceed billions I get memory exceeding error because of using hashmap. Does anybody have any idea to make this code applicable for any size of graph?
Here is my code :
public class Mygraphgenerator {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String fileName = "test.edgelist";
String line = null;
String [] lineSepartor;
int currentvertice=1;
int edgecounter=0;
int vertice;
int adjacents;
PrintWriter pw = new PrintWriter(new File("test.adjlist"));
HashMap<Integer, ArrayList<String>> directedMaker = new HashMap<Integer, ArrayList<String>>();
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String firstline;
String adjLists="";
String sentinel=" ";
boolean f = true;
while((line = bufferedReader.readLine()) != null)
{
//changeto networkxformat
//lineSepartor=line.split("\t");
lineSepartor=line.split(" ");
vertice=Integer.parseInt(lineSepartor[0]) + 1;
adjacents=Integer.parseInt(lineSepartor[1]) + 1;
//if switched from current vertices to the next one (0 to 1)
if (currentvertice==vertice){
if(!f)
pw.write(" " + adjacents + " " + "1");
else
{
pw.write(adjacents + " " + "1");
f=false;
}
ArrayList<String> edges;
if (directedMaker.containsKey(adjacents)){
edges=directedMaker.get(adjacents);
edges.add(vertice + "");
}else {
edges=new ArrayList<String>();
edges.add(vertice + "");
}
directedMaker.put(adjacents,edges);
//System.out.println(currentvertice);
//System.out.println(adjLists);
}else {
sentinel = "\n";
//System.out.println("Insde first while" + currentvertice + " adjLists " + adjLists);
pw.write(sentinel);
if (vertice -currentvertice>1)
for (int i = currentvertice + 1; i < vertice; i++){
if (directedMaker.containsKey(i)){
f=false;
List<String> edges = directedMaker.get(i);
for (int j = 0; j< edges.size(); j++){
if(j!=0)
pw.write(" " + edges.get(j) + " " + "1");
else
pw.write(edges.get(j) + " " + "1");
}
directedMaker.remove(i);
}
pw.write("\n");
}
if (directedMaker.containsKey(vertice)){
f=false;
List<String> edges = directedMaker.get(vertice);
for (int i =0; i< edges.size(); i++){
if(i!=0)
pw.write(" " + edges.get(i) + " " + "1");
else
pw.write(edges.get(i) + " " + "1");
}
directedMaker.remove(vertice);
pw.write(" " + adjacents + " " + "1");
}else
pw.write(adjacents + " " + "1");
ArrayList<String> edges;
if (directedMaker.containsKey(adjacents)){
edges=directedMaker.get(adjacents);
edges.add(vertice+"");
}else {
edges=new ArrayList<String>();
edges.add(vertice+"");
}
directedMaker.put(adjacents,edges);
}
currentvertice=vertice;
edgecounter++;
}
//System.out.println("In middle " + currentvertice + " adjLists " + adjLists);
pw.write(adjLists);
while (directedMaker.size()!=0){
pw.write("\n");
currentvertice++;
//System.out.println("Outside first while " + currentvertice);
if (directedMaker.containsKey(currentvertice)){
List<String> edges = directedMaker.get(currentvertice);
for (int i =0; i< edges.size(); i++){
if(i!=0)
pw.write(" " + edges.get(i) + " " + "1");
else
pw.write(edges.get(i) + " " + "1");
}
directedMaker.remove(currentvertice);
}
}
pw.close();
System.out.println("done!");
System.out.println("edges of this graph : " + edgecounter);
} catch(FileNotFoundException ex)
{
System.out.println(
"Unable to open file '" +
fileName + "'");
}
}
}
Okay so now I got my code to compile and run, but the output is incorrect now. I need to be able to select an option and then for 2, and 3 have 3 additional options after selecting that option. How should I adapt my coding to do this?
Task:
List of all information
List of all surgeries for a specific doctor (prompt for the doctor)
List of all surgeries of a specific type (prompt for the surgery type)
Total amount of surgery fees paid to each Doctor
Average Fees
Data File (patient.txt):
11111,Smith,Norris,Thyroid,1000.00
11112,Obama,Norris,Lasek,500.00
11113,Hoover,Norris,Dental,100.00
11114,Cena,Norris,Lasek,500.00
11115,Leto,Norris,Thyroid,1000.00
22221,Clark,Bond,Thyroid,1000.00
22222,Chang,Bond,Lasek,500.00
22223,Dent,Bond,Dental,100.00
22224,Nixon,Bond,Lasek,500.00
22225,Washington,Bond,Dental,100.00
33331,Jones,Lee,Dental,100.00
33332,Ross,Lee,Lasek,500.00
33333,Gates,Lee,Thyroid,1000.00
33334,Johnson,Lee,Thyroid,1000.00
33335,Carter,Lee,Dental,100.00
Code so far for reference:
package Patient_Reports_Package;
/**
* Created by bzink on 8/28/2015.
*/
import javax.swing.*;
import java.io.*;
import java.util.StringTokenizer;
/**
* The Patient_Reports_File class reads the data file into an array, and then has a menu for 5 reports.
*/
class Patient_Reports {
private final int[] id = new int[100];
private final String[] patient = new String[100];
private final String[] doctor = new String[100];
private final String[] surgery = new String[100];
private final double[] cost = new double[100];
private int count = -1;
private int i;
public static void main (String[] args) {
int selection;
String report_number;
Patient_Reports patient = new Patient_Reports();
patient.start_system();
report_number = patient.menu();
selection = Integer.parseInt(report_number);
while (selection !=6) {
if (selection == 1) {
patient.allInformationReport();
} else if (selection == 2) {
patient.surgeryDoctorReport();
} else if (selection == 3) {
patient.surgeryTypeReport();
} else if (selection == 4) {
patient.doctorFeesReport();
} else if (selection == 5) {
patient.averageFeesReport();
}
report_number = patient.menu();
selection = Integer.parseInt(report_number);
}//while loop
patient.writeReports();
System.exit(0);
}//main
//Read Data File into Array
private void start_system() {
String newLine;
try {
//define a file variable for Buffered read
BufferedReader Patient_Reports = new BufferedReader(new java.io.FileReader("C:\\Users\\Brandon\\" +
"Downloads\\Patient_Reports_File\\patient.txt"));
//read lines in file until there are no more lines in the file to read
while ((newLine = Patient_Reports.readLine()) != null) {
//there is a "," between each data item in each line
StringTokenizer delimiter = new StringTokenizer(newLine, ",");
count = count + 1;
id[count] = Integer.parseInt(delimiter.nextToken());
patient[count] = delimiter.nextToken();
doctor[count] = delimiter.nextToken();
surgery[count] = delimiter.nextToken();
cost[count] = Double.parseDouble(delimiter.nextToken());
}//while loop
Patient_Reports.close();
}//end try
catch (IOException error) {
//there was an error on the file writing
System.out.println("Error on file read " + error);
}//end catch
}//end start_system
//Report Menu
private String menu () {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Id ").append(" \n");
stringBuilder.append("Patient ").append(" \n");
stringBuilder.append("Doctor ").append(" \n");
stringBuilder.append("Surgery ").append(" \n");
stringBuilder.append("Cost ").append(" \n");
for (int i = 0; i < 6; i++) {
stringBuilder.append(i).append(" Name"+i).append('\n');
}
String startTag ="<font size='2' color='red'>";
String endTag = "</font>";
stringBuilder.append(startTag).append("Some content").append(endTag);
JOptionPane.showMessageDialog(null, stringBuilder.toString());
return stringBuilder.toString();
}//end menu\
/*
//Report Menu
private String menu() {
String report;
String Output = "Reports" + "\n" + "1. All_Information_Report" + "\n" +
"2. Surgeries_Doctor_Report" + "\n" +
"3. Surgeries_Type_Report" + "\n" +
"4. Doctor_Fees_Report" + "\n" +
"5. Average_Fees_Report" + "\n" +
"6. Exit" + "\n" +
" " + "\n" +
"Select a Report >";
report = JOptionPane.showInputDialog(null,
Output, "", JOptionPane.QUESTION_MESSAGE);
return report;
}//end menu\
*/
//Report containing all of the information
private void allInformationReport() {
System.out.println("All Information Report");
for (i = 0; i <= count; ++i) {
System.out.println(id[i] + " " + patient[i] + " " + doctor[i] + " " + surgery[i] + " " + cost[i] + " ");
}//for loop
}//end report
/* void selectDoctor()
{
//select doctor
String doctorOutput;
//int intNum=0,intNum1=0,i,x=-1;
count=count+1;
doctorOutput = "Enter the Doctor's Name";
doctor[count] =JOptionPane.showInputDialog(null,doctorOutput,
"",JOptionPane.QUESTION_MESSAGE);
}//end select doctor
//Start Doctor Menu
public static void doctorMenu (String[] args) {
int selection;
String doctorName;
Patient_Reports doctor = new Patient_Reports();
doctor.start_system();
doctorName = doctorMenu();
selection = Integer.parseInt(doctorName);
while (selection !=4) {
if (selection == 1) {
doctor.norrisSurgeries();
} else if (selection == 2) {
doctor.bondSurgeries();
} else if (selection == 3) {
doctor.leeSurgeries();
}
doctorName = doctorMenu();
selection = Integer.parseInt(doctorName);
}//while loop
doctor.writeReports();
System.exit(0);
}//End Doctor Menu
//Report on all surgeries by Dr. Norris
private void norrisSurgeries() {
System.out.println("Norris Surgeries Report");
for (i = 0; i <= count; ++i) {
System.out.println(doctor[i] + " " + surgery[i] + " ");
}//for loop
}//end report
//Report on all surgeries by Dr. Bond
private void bondSurgeries() {
System.out.println("Bond Surgeries Report");
for (i = 0; i <= count; ++i) {
System.out.println(doctor[i] + " " + surgery[i] + " ");
}//for loop
}//end report
//Report on all surgeries by Dr. Lee
private void leeSurgeries() {
System.out.println("Lee Surgeries Report");
for (i = 0; i <= count; ++i) {
System.out.println(doctor[i] + " " + surgery[i] + " ");
}//for loop
}//end report
*/
//Report on all surgeries of a specific doctor (prompt for the doctor)
private void surgeryDoctorReport() {
System.out.println("Surgeries Doctor Report");
for (i = 0; i <= count; ++i) {
System.out.println(id[i] + " " + patient[i] + " " + doctor[i] + " " + surgery[i] + " " + cost[i] + " ");
}//for loop
}//end report
/*
void selectSurgery()
{
//select surgery
String surgeryOutput;
//int intNum=0,intNum1=0,i,x=-1;
count=count+1;
surgeryOutput = "Enter the Surgery Type";
doctor[count] =JOptionPane.showInputDialog(null,surgeryOutput,
"",JOptionPane.QUESTION_MESSAGE);
}//end select surgery
*/
//Report on all surgeries of a specific type(Prompt for the surgery type)
private void surgeryTypeReport() {
System.out.println("Surgeries Type Report");
for (i = 0; i <= count; ++i) {
System.out.println(id[i] + " " + patient[i] + " " + doctor[i] + " " + surgery[i] + " " + cost[i] + " ");
}//for loop
}//end report
//Report on the total amount of fees paid to each doctor
private void doctorFeesReport() {
System.out.println("Doctor Fees Report");
for (i = 0; i <= count; ++i) {
System.out.println(id[i] + " " + patient[i] + " " + doctor[i] + " " + surgery[i] + " " + cost[i] + " ");
}//for loop
}//end report
//Report on the Average Fee
private void averageFeesReport() {
System.out.println("Average Fees Report");
for (i = 0; i <= count; ++i) {
System.out.println(id[i] + " " + patient[i] + " " + doctor[i] + " " + surgery[i] + " " + cost[i] + " ");
}//for loop
}//end report
//Store Data File in Array
private void writeReports()
{
try {
BufferedWriter Patient_Reports = new BufferedWriter(new java.io.FileWriter("patient_out.txt"));
for (i = 0; i <= count; ++i) {
//put "," between each data item in the file
Patient_Reports.write(id[i] + "," + patient[i] + "," + doctor[i] + "," +
surgery[i] + "," + cost[i] + ",");
//write a new line in the file
Patient_Reports.newLine();
}//for loop
Patient_Reports.close();
}//end try
catch (IOException error) {
//there was an error on the write to file
System.out.println("Error on file write " + error);
}//end error
}//end write_reports
}
'
Use String or StringBuilder or StringBuffer to do this. But instead of String use either StringBuilder or StringBuffer. Since for String, you need some extra objects for String manipulation.
Ex:
StringBuilder sb = new StringBuilder();
sb.append("Id ").append(" Name\n");
for (int i = 0; i < 10; i++) {
sb.append(i).append(" Name"+i).append('\n');
}
JOptionPane.showMessageDialog(null, sb.toString());
Use HTML tags to produce better formatted results like <font>, <table>, etc.
Ex:
String startTag ="<font size='2' color='red'>";
String endTag = "</font>";
sb.append(startTag+"Some content"+endTag);
In my code below, I am having an issue where I add the customer name to one room, but instead it adds the customer to every room. I can't figure out what in my code the issue is. I have tried removing the procedure but that still produced the same problem.
package test;
import java.util.*;
public class test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String choice, custName = "";
int roomNum = 1;
String[] hotel = new String[12];
String[] customer = new String[12];
hotelInitialise(hotel);
custInitialise(customer);
while ( roomNum < hotel.length-1 ) {
for (int i = 0; i < hotel.length-1; i++) {
System.out.println("This is the Hotel Menu. Please choose from the following options:\n");
System.out.println("A: " + "This will add a new entry\n");
System.out.println("V: " + "View all rooms\n");
choice = input.next().toUpperCase();
if (choice.equals("A")) {
System.out.println("Enter room number(1-10)");
roomNum =input.nextInt();
System.out.println("Enter name for room " + roomNum + " : " ) ;
custName = input.next();
addNewBooking(hotel, custName);
System.out.println(" ");
}
if (choice.equals("V")) {
seeAllRooms(hotel, custName);
}
}
}
}
// When the program loads it will assign all the values of the array as being empty
private static void hotelInitialise( String hotelRef[] ) {
for (int x = 0; x < 11; x++){
hotelRef[x] = "Room " + x + " is empty.";
}
System.out.println( "Welcome to the Summer Tropic Hotel.\n");
}
private static void custInitialise (String custRef[]) {
for (int i = 0; i < 11; i++) {
custRef[i] = ", no customer has occupied this room";
}
}
private static void addNewBooking(String hotel[], String customer) {
for (int x =1; x <11; x++) {
if (hotel[x].equals("Room " + hotel[x] + " is empty."))
System.out.println("Room " + x + " is empty.");
else {
System.out.println("Room " + x + " is occupied by "+ customer);
}
}
}
private static void seeAllRooms(String hotel[], String customer) {
for (int i = 0; i < hotel.length-1; i++) {
int j=0;
String custName = customer;
hotel[j]= custName;
if (hotel[i].equals("Room " + i + " is empty."))
System.out.println("Room " + i + " is empty.");
else {
System.out.println("Room " + i + " is occupied by "+ hotel[j] + ".");
}
}
}
}
In addNewBooking method you have this line:
if (hotel[x].equals("Room " + hotel[x] + " is empty."))
However hotel[x] has a value of "Room x is empty" e.g. hotel[1] is "Room 1 is empty" So the final check is becoming "hotel[x].equals(Room Room x is empty is empty.)" which is never equals to your hotel[x]
You have to change your code to
if (hotel[x].equals("Room " + x + " is empty."))
//do something there like add the booking
I'm trying to populate a 2d list array using 2 user inputs.
Problem I'm having is that in the code below, the 1st for statement isn't producing the outcome I'm expecting, the 2nd for is doing what is needed. Also, with the code below I'm unable to close scanner.
public static void main(String[] args) {
ArrayList<String> listCon = new ArrayList<String>();
ArrayList<String> listCol = new ArrayList<String>();
Scanner txtInput = new Scanner(System.in);
char addTo = 'y';
do {
System.out.println("\nCurrent list is " + listCon + listCol + "\n");
System.out.println("Would you like to add a country to the list?\n\t"
+ "( y ) = YES\n\t( n ) = NO");
addTo = txtInput.next().toLowerCase().charAt(0);
if (addTo == 'y') {
System.out.println("Enter country name: ");
listCon.add(txtInput.next().toLowerCase());
System.out.println("Enter colour: ");
listCol.add(txtInput.next().toLowerCase());
} else if (addTo == 'n') {
int i = 1;
int countCon = listCon.size();
if(countCon == 0) {
System.out.println("No countries have been entered.");
} else {
String str = "country";
if(countCon > 1) {
str = "countries";
}
System.out.println("Thankyou for your input. We found " + countCon + " " +
str + " in the list.");
System.out.println("Listed " + str + ":\n");
for(String n : listCon) {
char[] conDigit = n.toCharArray();
conDigit[0] = Character.toUpperCase(conDigit[0]);
n = new String(conDigit);
for(String b : listCol) {
char[] colDigit = b.toCharArray();
colDigit[0] = Character.toUpperCase(colDigit[0]);
b = new String(colDigit);
System.out.println("Country " + i + " : " + n + " - \t" + b);
i = i + 1;
}
break;
}
break;
}
} else {
System.out.println("Incorrect input detected. please try again. \n");
}
} while (true);
}
}
You need to remove extra break from the first for loop to iterate. Otherwise, you break after first iteration.
for(String n : listCon) {
....
for(String b : listCol) {
...
}
break; //remove this!
}
break;
EDIT
The result im after is Country 1 : France - Blue Country 2 : UK -
White Country 3 : Ireland - Green
You need to iterate like this:
for (int i = 0; i < listCon.size() && i < listCol.size(); i++) {
String n = listCon.get(i);
char[] conDigit = n.toCharArray();
conDigit[0] = Character.toUpperCase(conDigit[0]);
n = new String(conDigit);
String b = listCol.get(i);
char[] colDigit = b.toCharArray();
colDigit[0] = Character.toUpperCase(colDigit[0]);
b = new String(colDigit);
System.out.println("Country " + i + " : " + n + " - \t" + b);
}
Here is the main problem:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at ExamAnalysis.main(ExamAnalysis.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
The program compiles and runs. It's just that I am either getting the java.util.NoSuchElementException along with my five jother errors with (answer.charAt(i) == char) near the bottom. Here is my program:
import java.io.*;
import java.util.Scanner;
class ExamAnalysis
{
public static void main(String [] args) throws FileNotFoundException
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Please type the correct answers to the exam questions, one right after the other: ");
String answers = keyboard.nextLine();
System.out.println("Where is the file with all the student responses? ");
String responses = keyboard.nextLine();
Scanner read = new Scanner(new File(responses));
while (read.hasNextLine())
{
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
int p = 1;
p += i;
System.out.println("Student " + p + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on 9 students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
}
}
public static void resultsByStudents(String responses, String answers)
{
System.out.println ("Student # Correct Incorrect Blank");
System.out.println ("~~~~~~~~~ ~~~~~~~ ~~~~~~~~~ ~~~~~");
int student = 0;
int correct = 0;
int incorrect = 0;
int blank = 0;
for (int i = 0; i <= 9; i++)
{
for (int j = 0; j <= responses.length(); j++)
{
if ((responses.charAt(j)) == answers.charAt(j))
correct++;
else if ((responses.charAt(j)) != answers.charAt(j))
incorrect++;
else
blank++;
}
System.out.println(student + " " + correct + " " + incorrect + " " + blank);
student++;
}
}
public static void analysis(String responses)
{
System.out.println("QUESTION ANALYSIS (* marks the correct response)");
System.out.println("~~~~~~~~~~~~~~~~~");
//stores the percentage of each choice chosen
double A = 0;
double B = 0;
double C = 0;
double D = 0;
double E = 0;
double X = 0;
// tallys every variable chosen per question
for (int i = 0; i <= 10; i++) // go through all the questions
{
for (int j = 0; j <= responses.charAt(i); j++) //go through all the student responses
{
// variable that are being tallied
int chooseA = 0;
int chooseB = 0;
int chooseC = 0;
int chooseD = 0;
int chooseE = 0;
int chooseBlank = 0;
//variables take percentage of choices that have been chosen from each student
A = chooseA/9;
B = chooseB/9;
C = chooseC/9;
D = chooseD/9;
E = chooseE/9;
X = chooseBlank/9;
// variables that will print the asterisk with certain character of correct answer
String a = "A";
String b = "B";
String c = "C";
String d = "D";
String e = "E";
String blank = "blank";
if (responses.charAt(j) == A)
chooseA++;
else if (responses.charAt(j) == B)
chooseB++;
else if (responses.charAt(j) == C)
chooseC++;
else if (responses.charAt(j) == D)
chooseD++;
else if (responses.charAt(j) == E)
chooseE++;
else
chooseBlank++;
System.out.println("Question #" + i);
if (answers.charAt(i) == 'A') a = "A*"; // answers cannot be resolved(I already made it a global variable in my main method.)
else if (answers.charAt(i) == 'B') b = "B*";// answers cannot be resolved
else if (answers.charAt(i) == 'C') c = "C*";// answers cannot be resolved
else if (answers.charAt(i) == 'D') d = "D*";// answers cannot be resolved
else if (answers.charAt(i) == 'E') e = "E*";// answers cannot be resolved
System.out.println(a + " " + b + " " + c + " " + d + " " + e + " " + blank);
System.out.println (chooseA + " " + chooseB + " " + chooseC + " " + chooseD + " " + chooseE + " " + chooseBlank );
System.out.println (A + " " + B + " " + C + " " + D + " " + E + " " + X);
}
}
}
}
while (read.hasNextLine())
{
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
int p = 1;
p += i;
System.out.println("Student " + p + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on 9 students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
}
}
Your logic here is confusing you. read.nextLine(); "Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line."
So you are saying, does it have a line? If so, read the next 10...well...11 lines, which isn't what you want. You don't know if there are 11 lines past this point. Don't know what that text file looks like, but you will want to restructure this part to either say, "While it has a next line", or "Read 11 lines"
Remove the for loop may resolve the issue. You are checking only once by using while(hasNextLine() ) but calling read.nextLine() 10 times in for loop.
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
.......
}
int i = 0;
int numberOfStudents = 9;
while (i < numberOfStudents && read.hasNextLine()){
responses = read.nextLine();
i++;
System.out.println("Student " + i + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on "+ numberOfStudents +" students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
i < numberOfStudents : makes the required number of inserts
read.hasNextLine() : checks if there is input from console. If not the program waits for input.
for (int i = 0; i <= 10; i++)
count from 0 -> 10 = 11 students