I'm working on a program which sorts an array by dividing it into smaller max-heaps and extracting the max-integer out of each one, then deleting it from the heap and running again until every heap is empty, but I can't seem to figure it out.
From where I stand the code looks good, but I don't get the results which I am looking for. My input is created randomly, and makes an array of 512 integers. Here is what it prints for one example run -
Original Array -391 176 -380 -262 -474 327 -496 214 475 -255 50 -351 179 -385 -442 -227 465 127 -293 288
Sorted Array 475 465 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327
n = 20 k = 2
The number of comparisons is 243
Can anyone spot what's wrong with my code? I will be really gladful.
(1) Main Program
import java.io.File;
import java.util.*;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.IOException;
public class Project {
static final int n = 20;
static final int k = 2;
static int counter = 0;
private static Scanner scan;
public static void main(String[] args) throws IOException {
// Optional - reading from a file containing 512 integers.
InputCreator.main();
File f = new File("random.txt");
// File f = new File("increase.txt");
// File f = new File("decrease.txt");
try { scan = new Scanner(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace(); }
int [] L = new int[n];
System.out.print("Original Array ");
for (int i = 0; i < n ; i++)
{ counter++; L[i] = scan.nextInt(); System.out.print(" " + L[i]); }
Projectsort(L);
}
private static void Projectsort(int [] L) {
// int [][] Li = new int [k] [n-(n/k*(k-1))]; // The size of the rest of the integers (n-(n/k*(k-1)) will always be bigger than n/k
int [] temp = new int [n/k], extra = new int [n-(n/k)*(k-1)];
int extraIndex = 0, max, maxIndex = 0, r = 0;
ProjectMaxHeap [] Li = new ProjectMaxHeap [k];
// The following loop's time effiency is O(k) * O(N/k) = O(N)
for (int i=0; i<k-1; i++) { counter++; // copying all the integers from Array L into K-1 smaller arrays
for (int j=0; j<n/k ; j++)
{ counter++; temp [j] = L[i*(n/k)+j]; }
Li[i] = new ProjectMaxHeap (temp); }
for (int i=(n/k)*(k-1) ; i<n ; ++i) // The rest of the integers on array L
{ counter++; extra [extraIndex] = L[i]; extraIndex++; }
Li[k-1] = new ProjectMaxHeap(extra);
System.out.print("\nSorted Array ");
for (int i = n ; i > 0 ; i--) { counter++;
r = 0;
do{max = Li[r].extractMax(); r++; }while(Li[r].isEmpty() && r < k - 1);
for (int j = r; j < k; j++) // Time efficiency O(k)*O(N/k)
{ counter++;
if(!Li[j].isEmpty()) {
if (Li[j].extractMax() > max) {
counter++;
max = Li[j].extractMax();
maxIndex = j; }
}
System.out.print(max + " ");
Li[maxIndex].deleteMax(); } }
System.out.println("\nn = " + n + " k = " + k +"\nThe number of comparisons is " + counter);
}
}
(2) Max Heap Class
public class ProjectMaxHeap
{
private int [] _Heap;
private int _size;
public ProjectMaxHeap (int [] A){
_size = A.length;
_Heap = new int[A.length];
System.arraycopy(A, 0, _Heap, 0, A.length);
for (int i = _size / 2 ; i >=0 ; i--) {
Project.counter++;
maxHeapify(i); }
}
private int parent(int pos)
{ return pos / 2; }
private int leftChild(int pos)
{ return (2 * pos); }
private int rightChild(int pos)
{ return (2 * pos) + 1; }
private void swap(int fpos,int spos) {
int tmp;
tmp = _Heap[fpos];
_Heap[fpos] = _Heap[spos];
_Heap[spos] = tmp; }
private void maxHeapify (int i) {
int l = leftChild(i), r = rightChild(i), largest;
if(l < _size && _Heap[l] > _Heap[i]) {
Project.counter+=2;
largest = l; }
else largest = i;
if(r < _size && _Heap[r] > _Heap[largest]) {
largest = r;
Project.counter+=2; }
if (largest != i) {
Project.counter++;
swap(i, largest);
maxHeapify (largest); }
}
protected boolean isEmpty() { return _size == 0; }
protected void deleteMax() {
if (_size > 1) {
Project.counter++;
maxHeapify(0);
int max = _Heap[0];
_size--;
swap(0, _size);
maxHeapify(0); }
else _size = 0;
}
protected int extractMax() {
maxHeapify(0);
return _Heap[0];
}
}
(3) Input Creator
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.io.FileReader;
import java.io.BufferedReader;
public class InputCreator {
public static void main() {
randomizer();
decrease();
increase();
}
private static void randomizer() {
// The target file
File out = new File("random.txt");
FileWriter fw = null;
int n = 0;
// Try block: Most stream operations may throw IO exception
try {
// Create file writer object
fw = new FileWriter(out);
// Wrap thק writer with buffered streams
BufferedWriter writer = new BufferedWriter(fw);
int line;
Random random = new Random();
while (n < Project.n) {
// Randomize an integer and write it to the output file
line = random.nextInt(1000)-500;
writer.write(line + "\r\n");
n++;
}
// Close the stream
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
private static void increase() {
// The target file
File out = new File("increase.txt");
FileWriter fw = null;
int n = 0;
int temp = 0;
// Try block: Most stream operations may throw IO exception
try {
// Create file writer object
fw = new FileWriter(out);
// Wrap thק writer with buffered streams
BufferedWriter writer = new BufferedWriter(fw);
int line;
Random random = new Random();
while (n < Project.n) {
// Randomize an integer and write it to the output file
line = random.nextInt((n+1)*10);
if(line > temp) {
writer.write(line + "\r\n");
n++;
temp = line; }
}
// Close the stream
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
private static void decrease() {
// The target file
File out = new File("decrease.txt");
FileWriter fw = null;
int n = 0;
int temp = 10000;
// Try block: Most stream operations may throw IO exception
try {
// Create file writer object
fw = new FileWriter(out);
// Wrap thק writer with buffered streams
BufferedWriter writer = new BufferedWriter(fw);
int line;
Random random = new Random();
while (n < Project.n) {
// Randomize an integer and write it to the output file
line = 10000 - random.nextInt((n+1)*20);
if(line < temp) {
writer.write(line + "\r\n");
n++;
temp = line; }
}
// Close the stream
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
}
The problem is with max = Li[0].extractMax(); You are not checking if Li[0] might be empty.
Always check preconditions and fail fast. The problem would have become immediately obvious had you started extractMax and deleteMax with
if (_size == 0) {
throw new IllegalStateException("empty heap");
}
Here's the fixed final loop:
for (int i = 0; i < n; i++) {
int maxIndex = -1; // remove these variable declarations from top of method
int max = Integer.MIN_VALUE; // it's best to confine variables to narrow scope
for (int j = 0; j < k; j++) {
if (!Li[j].isEmpty()) {
int current = Li[j].extractMax();
if (maxIndex == -1 || current > max) {
maxIndex = j;
max = current;
}
}
}
assert maxIndex != -1;
Li[maxIndex].deleteMax();
System.out.print(max + " ");
}
Related
While trying out the problem "Nuclear Reactors" , i'm getting the results on my computer ,but in CodeChef there is a timelimit of 0.2 secs and while submitting my answer i'm getting a TLE(time limit exceeded) error and in one test i'm getting wrong answer.
I don't have a clue what is causing this.
Any hints would be helpful.
Link :https://www.codechef.com/problems/NUKES
My code :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args) {
FastReader fr = new FastReader();
// I/P
int a = fr.nextInt();
int n = fr.nextInt();
int k = fr.nextInt();
// ARRAY TO STORE RESULT
int react[] = new int[k];
// ARRAY OF ZERO AND ONES
int temp_one[]=new int[k];
int temp_zero[]=new int[k];
for (int i = 0; i < k; i++){
react[i] = 0;
temp_zero[i]=react[i];
temp_one[i]=1;
}
while (a != 0) { // TO REPEAT TILL ALL (A) ARE USED
int j = 0;
while(react[j]>=n){ // CHECK(value in K>=A)
react[j] = 0;
j++;
}
react[j]++;
if(Arrays.equals(react,temp_one)){ // CHECK(all K are filled)
react=temp_zero;
}
a--;
}
for(int i=0;i<k;i++){
System.out.print(react[i]+" ");
}
}
//////////////////// FAST IO //////////////////////
static class FastReader{
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
}
catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
Results given by CodeChef
This code should work for your algorithm.
int[] ret = new int[k];
for(int i = (int)(Math.log(a)/Math.log(n+1)); i >= 0; i--) {
int val = (int)(a/Math.pow(n+1,i));
a -= val*Math.pow(n+1,i);
if (i < k) ret[i] = val;
}
ret is your return array.
It basically finds the base n+1 representation of a, which is the answer they want you to get. If you want more information on why it works, feel free to ask!
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am new to Java and I am trying to execute the code below regarding Stable Marrage algorithm, but when executing the code below you get the following error:
Error: For input string: "3 " Exception in thread "main"
java.lang.NullPointerException at
br.com.entrada.GaleShapley.(GaleShapley.java:21) at
br.com.entrada.GaleShapley.main(GaleShapley.java:166)
Gale Shapley Marriage Algorithm
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class GaleShapley
{
private int N, engagedCount;
private String[][] menPref;
private String[][] womenPref;
private String[] men;
private String[] women;
private String[] womenPartner;
private boolean[] menEngaged;
/** Constructor **/
public GaleShapley(String[] m, String[] w, String[][] mp, String[][] wp)
{
N = mp.length;
engagedCount = 0;
men = m;
women = w;
menPref = mp;
womenPref = wp;
menEngaged = new boolean[N];
womenPartner = new String[N];
calcMatches();
}
/** function to calculate all matches **/
private void calcMatches()
{
while (engagedCount < N)
{
int free;
for (free = 0; free < N; free++)
if (!menEngaged[free])
break;
for (int i = 0; i < N && !menEngaged[free]; i++)
{
int index = womenIndexOf(menPref[free][i]);
if (womenPartner[index] == null)
{
womenPartner[index] = men[free];
menEngaged[free] = true;
engagedCount++;
}
else
{
String currentPartner = womenPartner[index];
if (morePreference(currentPartner, men[free], index))
{
womenPartner[index] = men[free];
menEngaged[free] = true;
menEngaged[menIndexOf(currentPartner)] = false;
}
}
}
}
printCouples();
}
/** function to check if women prefers new partner over old assigned partner **/
private boolean morePreference(String curPartner, String newPartner, int index)
{
for (int i = 0; i < N; i++)
{
if (womenPref[index][i].equals(newPartner))
return true;
if (womenPref[index][i].equals(curPartner))
return false;
}
return false;
}
/** get men index **/
private int menIndexOf(String str)
{
for (int i = 0; i < N; i++)
if (men[i].equals(str))
return i;
return -1;
}
/** get women index **/
private int womenIndexOf(String str)
{
for (int i = 0; i < N; i++)
if (women[i].equals(str))
return i;
return -1;
}
/** print couples **/
public void printCouples()
{
System.out.println("Couples are : ");
for (int i = 0; i < N; i++)
{
System.out.println(womenPartner[i] +" "+ women[i]);
}
}
/** main function **/
public static void main(String[] args)
{
System.out.println("Gale Shapley Marriage Algorithm\n");
/** list of men **/
String[] m = {"1", "2", "3"};
/** list of women **/
String[] w = {"1", "2", "3"};
/** men preference **/
String[][] mp = null ;
/** women preference **/
String[][] wp= null ;
// Input.txt is like
// 3 <--defines the size of array
// male preference array
// 1 3 2
// 1 2 3
// 2 3 1
//female preference array
//1 3 2
//2 1 3
//2 1 3
try{
FileInputStream fstream = new FileInputStream("input.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
int line=0;
int k=0;
int n=0;
int i=0;
while ((strLine = br.readLine()) != null) {
if(line==0){
n =Integer.valueOf(strLine);
mp=new String[n][n];
wp=new String[n][n];
line++;
}
else{
String[] preferences=strLine.split(" ");
if(i<n){
mp[i]=preferences;
}
else{
wp[i-n]=preferences;
}
i++;
}
}
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
GaleShapley gs = new GaleShapley(m, w, mp, wp);
}
}
The program is not reading the input.txt input file completely. It is reading only the first line of this file. And I can't solve this. I think the problem should be in the code part below.
while ((strLine = br.readLine()) != null) {
if(line==0){
n =Integer.valueOf(strLine);
mp=new String[n][n];
wp=new String[n][n];
line++;
}
else{
String[] preferences=strLine.split(" ");
if(i<n){
mp[i]=preferences;
}
else{
wp[i-n]=preferences;
}
i++;
}
}
Below is the input file: input.txt
3
male preference array
1 3 2
1 2 3
2 3 1
female preference array
1 3 2
2 1 3
2 1 3
The error is thrown due this : 3 => it contains a whitespace
And when you call the Integer.parse(N), N cannot be parsed to Integer while there's this whitespaces,
To resolve this, i used strLine.trim();
women[i].equals(str) : you are comparing here a string to an Integer is always false and the result of your function womenIndexOf is -1, and this is going to throw an exception of IndexOutOfBounds Exception when using the -1 as index
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class GaleShapley {
private int N, engagedCount;
private String[][] menPref;
private String[][] womenPref;
private String[] men;
private String[] women;
private String[] womenPartner;
private boolean[] menEngaged;
/** Constructor **/
public GaleShapley() {
}
public GaleShapley(String[] m, String[] w, String[][] mp, String[][] wp) {
N = mp.length;
engagedCount = 0;
men = m;
women = w;
menPref = mp;
womenPref = wp;
menEngaged = new boolean[N];
womenPartner = new String[N];
calcMatches();
}
/** function to calculate all matches **/
private void calcMatches() {
while (engagedCount < N) {
int free;
for (free = 0; free < N; free++)
if (!menEngaged[free])
break;
for (int i = 0; i < N && !menEngaged[free]; i++) {
int index = womenIndexOf(menPref[free][i]);
if (womenPartner[index] == null) {
womenPartner[index] = men[free];
menEngaged[free] = true;
engagedCount++;
} else {
String currentPartner = womenPartner[index];
if (morePreference(currentPartner, men[free], index)) {
womenPartner[index] = men[free];
menEngaged[free] = true;
menEngaged[menIndexOf(currentPartner)] = false;
}
engagedCount++;
}
}
}
printCouples();
}
/** function to check if women prefers new partner over old assigned partner **/
private boolean morePreference(String curPartner, String newPartner, int index) {
for (int i = 0; i < N; i++) {
if (womenPref[index][i].equals(newPartner))
return true;
if (womenPref[index][i].equals(curPartner))
return false;
}
return false;
}
/** get men index **/
private int menIndexOf(String str) {
for (int i = 0; i < N; i++)
if (men[i].equals(str))
return i;
return -1;
}
/** get women index **/
private int womenIndexOf(String str) {
for (int i = 0; i < N; i++) {
if (women[i].equals(str))
return i;
}
return -1;
}
/** print couples **/
public void printCouples() {
System.out.println("Couples are : ");
for (int i = 0; i < N; i++) {
System.out.println(womenPartner[i] + " " + women[i]);
}
}
/** main function **/
public static void main(String[] args) {
System.out.println("Gale Shapley Marriage Algorithm\n");
/** list of men **/
String[] m = { "1", "2", "3" };
/** list of women **/
String[] w = { "1", "2", "3" };
/** men preference **/
String[][] mp = null;
/** women preference **/
String[][] wp = null;
try {
FileInputStream fstream = new FileInputStream("C:\\Users\\Youssef\\Projects\\STS\\TEST\\src\\input");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
int line = 0;
int n = 0;
int i = 0;
while ((strLine = br.readLine()) != null) {
if (line == 0) {
n = Integer.valueOf(strLine.trim());
mp = new String[n][n];
wp = new String[n][n];
line++;
} else {
if (strLine != null && !strLine.equals("") && !strLine.contains("male")
&& !strLine.contains("female")) {
String[] preferences = strLine.split(" ");
if (i < n) {
mp[i] = preferences;
} else {
if (i - n < w.length) {
wp[i - n] = preferences;
}
}
i++;
}
}
}
in.close();
new GaleShapley(m, w, mp, wp);
} catch (Exception e) {// Catch exception if any
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
}
}
}
Follows the code running below:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class GaleShapley
{
private int N, engagedCount;
private String[][] menPref;
private String[][] womenPref;
private String[] men;
private String[] women;
private String[] womenPartner;
private boolean[] menEngaged;
public GaleShapley() {}
/** Constructor **/
public GaleShapley(String[] m, String[] w, String[][] mp, String[][] wp)
{
N = mp.length;
engagedCount = 0;
men = m;
women = w;
menPref = mp;
womenPref = wp;
menEngaged = new boolean[N];
womenPartner = new String[N];
calcMatches();
}
/** function to calculate all matches **/
private void calcMatches()
{
while (engagedCount < N)
{
int free;
for (free = 0; free < N; free++)
if (!menEngaged[free])
break;
for (int i = 0; i < N && !menEngaged[free]; i++)
{
int index = womenIndexOf(menPref[free][i]);
if (womenPartner[index] == null)
{
womenPartner[index] = men[free];
menEngaged[free] = true;
engagedCount++;
}
else
{
String currentPartner = womenPartner[index];
if (morePreference(currentPartner, men[free], index))
{
womenPartner[index] = men[free];
menEngaged[free] = true;
menEngaged[menIndexOf(currentPartner)] = false;
}
}
}
}
printCouples();
}
/** function to check if women prefers new partner over old assigned partner **/
private boolean morePreference(String curPartner, String newPartner, int index)
{
for (int i = 0; i < N; i++)
{
if (womenPref[index][i].equals(newPartner))
return true;
if (womenPref[index][i].equals(curPartner))
return false;
}
return false;
}
/** get men index **/
private int menIndexOf(String str)
{
for (int i = 0; i < N; i++)
if (men[i].equals(str))
return i;
return -1;
}
/** get women index **/
private int womenIndexOf(String str)
{
for (int i = 0; i < N; i++)
if (women[i].equals(str))
return i;
return -1;
}
/** print couples **/
public void printCouples()
{
System.out.println("Couples are : ");
for (int i = 0; i < N; i++)
{
System.out.println(womenPartner[i] +" "+ women[i]);
}
}
/** main function **/
public static void main(String[] args) {
System.out.println("Gale Shapley Marriage Algorithm\n");
/** list of men **/
String[] m = { "1", "2", "3" };
/** list of women **/
String[] w = { "1", "2", "3" };
/** men preference **/
String[][] mp = null;
/** women preference **/
String[][] wp = null;
try {
FileInputStream fstream = new FileInputStream("src\\input.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
int line = 0;
int n = 0;
int i = 0;
while ((strLine = br.readLine()) != null) {
if (line == 0) {
n = Integer.valueOf(strLine.trim());
mp = new String[n][n];
wp = new String[n][n];
line++;
} else {
if (strLine != null && !strLine.equals("") && !strLine.contains("male")
&& !strLine.contains("female")) {
String[] preferences = strLine.split(" ");
if (i < n) {
mp[i] = preferences;
} else {
if (i - n < w.length) {
wp[i - n] = preferences;
}
}
i++;
}
}
}
in.close();
new GaleShapley(m, w, mp, wp);
} catch (Exception e) {// Catch exception if any
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
}
}
}
The result is:
Gale Shapley Marriage Algorithm
Couples are :
1 1
2 2
3 3
I have an array called myArray that contains words separated by a space and trimmed from a PDF from the first page to the last page. I wrote a simple print array method that iterates through and prints each element one by one and it looks great!
Immediately after I have it go through another for loop for the length of the array and checks if (myArray[i].equals("(19)")) {//print something} When printing the array to the console it is clear that the value (19) exists in the array.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
public class Main {
static File file;
static PDFTextStripper textStripper;
static PDDocument pdDoc;
static COSDocument cosDoc;
static String parsedText;
static int sum = 0;
static String[] myArray;
static String[] events = {"400", "800", "1500",
"3000", "5000", "10000"};
public static void main(String[] args) {
//Read the PDF file into instance variable file
readFile();
try {
parsePDF(file);
} catch (IOException e) {
e.printStackTrace();
}
myArray = parsedText.split(" ");
removeWhiteSpace(myArray);
printArray(myArray);
//System.out.println();
String currentEvent = "";
for (int i = 0; i < myArray.length; i++) {
if (contains(myArray[i])) {
currentEvent = myArray[i];
}
if (!currentEvent.equals("")) {
if (myArray[i].charAt(0) == '(' && (myArray[i].charAt(myArray[i].length() - 1) == ')')) {
String formatedRunners = "";
//It is possible to see some numbers such as (19)) or (19)
if (containsCharacter(myArray[i], ')') == 2) {
formatedRunners = myArray[i].substring(1, myArray[i].length() - 2);
} else {
formatedRunners = myArray[i].substring(1, myArray[i].length() - 1);
}
int numberOfRunners = Integer.parseInt(formatedRunners);
int distance = Integer.parseInt(currentEvent);
sum += numberOfRunners * distance;
//reset currentEvent
currentEvent = "";
}
}
}
//Print total distance in meters
System.out.println(sum + " meters");
//Convert meters to miles using the following equation: meters / 1609.344
System.out.println( Math.round((sum / 1609.344)) + " miles");
}
public static void readFile() {
Scanner c = new Scanner(System.in);
System.out.println("Enter a file path: ");
String filePath = c.nextLine();
file = new File(filePath);
}
public static void parsePDF(File file) throws IOException {
textStripper = new PDFTextStripper();
pdDoc = PDDocument.load(file);
//Parse PDF
textStripper.setStartPage(1);
//textStripper.setEndPage();
//Parsed String
parsedText = textStripper.getText(pdDoc);
}
public static boolean contains(String s) {
for (int i = 0; i < events.length; i++) {
if (s.equals(events[i])) {
return true;
}
}
return false;
}
public static void printArray(String[] a) {
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
public static void removeWhiteSpace(String[] a) {
for (int i = 0; i < myArray.length; i++) {
if (myArray[i].equals("")) {
//Use some filler to avoid crashes when checking characters
myArray[i] = "NULL";
}
//Trim off all extra whitespace
myArray[i] = myArray[i].trim();
}
}
public static int containsCharacter(String str, char c) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == c) {
count++;
}
}
return count;
}
}
Here is what I want:
Parsing and trimming etc. (OK)
Iterating over myArray (in the main method) and detecting events (OK)
If an event occurred then the next value must be (Any number) like (19)
(NOK)
The number from step 3. will be used to compute another number
Reset the current event to repeat the process over and
over again.
It seems like that it is reading each event correctly but only picks up (19)) instead of (19).
There are several problems in you code (No Exceptionhandling, everything static, small bugs etc.) but I will focus on the major issue. (I removed the code which I did not change)
public class Main {
static File file;
static PDFTextStripper textStripper;
static PDDocument pdDoc;
static COSDocument cosDoc;
static String parsedText;
static int sum = 0;
static String[] myArray = {"Seeded", "3000", "random", 25, "(44)", "1500", "random", "(13)"};
static String[] events = {"400", "800", "1500", "3000", "5000", "10000", "200.000"};
public static void main(String[] args) {
//Read the PDF file into instance variable file
readFile();
try {
parsePDF(file);
} catch (IOException e) {
e.printStackTrace();
}
myArray = parsedText.split(" ");
removeWhiteSpace(myArray);
String currentEvent = "";
for (int i = 0; i < myArray.length; i++) {
if (contains(myArray[i])) {
currentEvent = myArray[i];
}
else if (!currentEvent.isEmpty()) {
Integer value = extractNumber(myArray[i]);
if (!myArray[i].isEmpty() && value!=null) {
int distance = Integer.parseInt(currentEvent);
sum += value.intValue() * distance;
//reset currentEvent
currentEvent = "";
}
}
}
//Print total distance in meters
System.out.println(sum + " meters");
//Convert meters to miles using the following equation: meters / 1609.344
System.out.println( Math.round((sum / 1609.344)) + " miles");
}
public static Integer extractNumber(String toCheck) {
Pattern r = Pattern.compile("^.*?\\([^\\d]*(\\d+)[^\\d]*\\).*$");
Matcher m = r.matcher(toCheck);
if(m.find()) {
return Integer.valueOf(m.group(1));
}
return null;
}
public static void removeWhiteSpace(String[] a) {
for (int i = 0; i < myArray.length; i++) {
//Trim off all extra whitespace
myArray[i] = myArray[i].trim();
}
}
The result is
151500 meters
94 miles
I'm working on an assignment that takes a data file with a number matrix and determines if it is a magic square. If it is then it also needs to report the sum of the rows and columns. With the output:
The matrix is a magic square.
The sum of all the rows and columns is 34.
I'm not sure how to go about this with one method, I feel like its asking me to return 2 values. The closest I have came is by adding a System.out.println with the sum at the end of my method when it returns true.
But the issue with that is that my output is backwords:
The sum of all the rows and columns is 34.
The matrix is a magic square.
How do I get the sum when I've only been asked to create one method? Below is my code, the instructor gave the bottom 3 methods so I'm only concerned with the first 2.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class chp8magic
{
public static void main(String args[])
{
int matrix[][] = initMatrix();
printData(matrix);
if (isMagic(matrix)) {
System.out.println("The matrix is a magic square.");
}
else {
System.out.println("Not a magic square");
}
}
public static boolean isMagic(int[][] mat)
{
int n = mat.length;
int nSquare = n*n;
int M = (n*n*(n*n+1)/2)/n;
int sumRow = 0, sumColoumns = 0, sumPriDiag = 0, sumSecDiag = 0;
boolean[] flag = new boolean[n*n];
for(int row = 0; row < n; row++){
sumRow = 0;
sumColoumns = 0;
for(int col = 0; col < n; col++)
{
if( mat[row][col] < 1 || mat[row][col] > nSquare )
return false;
if(flag[mat[row][col]-1] == true)
return false;
flag[mat[row][col]-1] = true;
sumRow += mat[row][col];
sumColoumns += mat[col][row];
}
sumPriDiag += mat[row][row];
sumSecDiag += mat[row][n-row-1];
if(sumRow!=M || sumColoumns!=M)
return false;
}
if(sumPriDiag!=M || sumSecDiag!=M)
return false;
else
return true;
}
public static int[][] initMatrix()
{
int matrix[][];
Scanner filein = null;
try {
filein = new Scanner(new File("matrix.txt"));
int numRows = Integer.parseInt(filein.nextLine());
matrix = new int[numRows][];
parseData(matrix, filein);
filein.close();
return matrix;
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
if(filein != null)
filein.close();
return null;
}
}
public static void parseData(int matrix[][], Scanner in)
{
for(int r = 0; r < matrix.length; r++)
{
String splitLine[] = in.nextLine().split(" ");
matrix[r] = new int[splitLine.length];
for(int c = 0; c < matrix[r].length; c++){
matrix[r][c] = Integer.parseInt(splitLine[c]);
}
}
}
public static void printData(int matrix[][])
{
for(int r = 0; r < matrix.length; r++){
for(int c = 0; c < matrix[r].length; c++){
System.out.print(matrix[r][c] + " ");
}
System.out.println();
}
}
}
Probably you just need to do:
System.out.println("is magic: " + isMagic);
System.out.ptintln("sum: " + sum);
However this is not really returning the values, just printing them. To return two values there are several options. You could return an object:
public class MagicSquareProperties {
private boolean magic;
private int sum;
public MagicSquareProperties(boolean magic, int sum) {
this.magic = magic;
this.sum = sum;
}
public boolean isMagic() {
return magic;
}
public int getSum() {
return sum;
}
}
// now to return both values: return new MagicSquareProperties(true, 34);
But in my opinion the best solution would be the following:
Create a class MagicSquare.
Add property declarations (e.g. private int sum).
Add a constructor, for example MagicSquare(File file), this constructor reads the file and populates the properties.
Add getters and setters if needed (e.g. getSum())
Execute the main method in another class and call new MagicSquare(...) to create a magic square object. Afterwards you can call the getters on the object whenever you need the value.
My code at the moment:
import java.util.*;
import java.io.*;
public class Percolation {
// given an N-by-N matrix of open sites, return an N-by-N matrix
// of sites reachable from the top via a vertical path of open sites
private static Scanner scan = null;
public static boolean[][] readOpenFromFile() {
final File f = new File("file.txt");
try {
scan = new Scanner(f);
}
catch(FileNotFoundException ex) {
System.exit(0);
}
final int m = scan.nextInt();
final int n = scan.nextInt();
final boolean[][] grid = new boolean[m][n];
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
grid[i][j] = readBoolean();
}
}
return grid;
}
public static boolean readBoolean() {
final String s = scan.next();
if(s.equalsIgnoreCase("true")) {
return true;
}
if(s.equalsIgnoreCase("false")) {
return false;
}
if(s.equals("1")) {
return true;
}
if(s.equals("0")) {
return false;
}
throw new java.util.InputMismatchException();
}
public static boolean[][] flow(final boolean[][] open) {
final int n = open.length;
final boolean[][] full = new boolean[n][n];
for(int j = 0; j < n; j++) {
flow(open, full, 0, j);
}
return full;
}
public static void flow(final boolean[][] open, final boolean[][] full, final int i, final int j) {
final int n = open.length;
// base cases
if(( i < 0) ||( i >= n)) {
return; // invalid row
}
if(( j < 0) ||( j >= n)) {
return; // invalid column
}
if(!open[i][j]) {
return; // not an open site
}
if(full[i][j]) {
return; // already marked as full
}
// mark i-j as full
full[i][j] = true;
flow(open, full, i + 1, j); // down
flow(open, full, i, j + 1); // right
flow(open, full, i, j - 1); // left
flow(open, full, i - 1, j); // up
}
// does the system percolate?
public static boolean percolates(final boolean[][] open) {
final int n = open.length;
final boolean[][] full = flow(open);
for(int j = 0; j < n; j++) {
if(full[n - 1][j]) {
System.out.println("percolates");
return true;
}
}
System.out.println("does not percolate");
return false;
}
public static void print(final boolean[][] grid) {
final int m = grid.length;
final int n = grid[0].length;
System.out.println(m + " " + n);
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(grid[i][j]) {
System.out.print("1 ");
} else {
System.out.print("0 ");
}
}
System.out.println("");
}
}
public static void main(String[] args) {
final boolean[][] open = readOpenFromFile();
print(flow(open));
System.out.println(percolates(open));
}
}
It can be seen that this program works by grabbing input from the file.txt file. However, how could I modify this code so as to request require a file name (perhaps at the command-line) each time the program is run, and use that as input?
I would think to add a String as an argument, then change that String into a file name. But this is easier said than done. Suggestions?
You can take it as an argument and modify code to -
public static void main(String[] args) {
// args[0] - Full path of the file
final boolean[][] open = readOpenFromFile(args[0]);
print(flow(open));
System.out.println(percolates(open));
}
public static boolean[][] readOpenFromFile(String filepath) {
final File f = new File(filepath);
try {
scan = new Scanner(f);
}
catch(FileNotFoundException ex) {
System.exit(0);
}
final int m = scan.nextInt();
final int n = scan.nextInt();
final boolean[][] grid = new boolean[m][n];
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
grid[i][j] = readBoolean();
}
}
return grid;
}
You can use this code:
public static boolean[][] readOpenFromFile(String file) {
final File f = new File( file );
// same code ...
}
public static void main(String[] args) {
if(args != null && args.length == 1) {
String file = args[0];
final boolean[][] open = readOpenFromFile(file);
print(flow(open));
System.out.println(percolates(open));
}
}
You need something like this, but you have to add checking file name:
InputStreamReader converter = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(converter);
while (!(CurLine.equals("quit"))){
CurLine = in.readLine();
if (!(CurLine.equals("quit"))){
System.out.println("You typed: " + CurLine);
}
}
Link to site where you can find it