Running multiple threads for row matrix multiplication - java

I have a program that takes a text file that has ints in it to look like a matrix. It has 2 of these here is an example.
1 1 1 1
1 1 1 1
1 1 1 1.
I have to use one single thread for each row dot matrix multiplication and then put it into the new matrix. The error I keep getting it that I get a repeat of the same thread number even though once its done the row matrix multiplication the thread should not be used again. The first part of the code is creating the new 2D array for the products of the row dot multiplication. The next set of code is the run() method doing the actual math. I do not know how to not get repeating threads to keep going. Any help is appreciated. enter code here
P = new int[x][z];
for(int i = 0; i < x; i++) {
for(int j = 0; j < z; j++) {
Thread t = new Thread(new MatrixThread(A,B,P,i,j,y));
t.setName( "[" + i + "] [" + j + "]");
t.start();
}
}
private static class MatrixThread implements Runnable {
private int[][] A,B,P;
private int row,col,y;
public MatrixThread(int[][] A, int[][] B, int[][] P, int i, int j,int y) {
this.A = A;
this.B = B;
this.P = P;
this.row = i;
this.col = j;
this.y = y;
}
public void run() {
System.out.println("Thread " + Thread.currentThread().getName() + " starts calculating");
for(int i = 0; i < y; i++) {
P[row][col] += A[row][i]* B[col][i];
}
System.out.println("Thread " + Thread.currentThread().getName() + " returns cell value " + P[row][col]);
}
}

Related

How to transpose a matrix in java (parallel/multithreaded)

We all know how useful matrix transposition is, and writing a general algorithm for sequential use is no problem. However, I am having some trouble doing the same for multithreaded purposes, and have only gotten this small case for 4 x 4 to work properly.
My approach is to assign equal parts of a double[][] structure, in this case 2 x 2, to each out of four threads. In this case, that means starting positions of 0,0 & 0,2 & 2,0 & 2,2. This is passed in with "kol" and "rad".
However, I cannot get this to work on larger matrices, so any help would be appreciated. The closest answer to this problem I've found is here: How to to parallelize the matrix transpose?
This is also my inspiration for splitting the double[][] structure into four parts. My (working) 4 x 4 code can be found below, so how can I modify it to work for four threads?
Cheers!
public double[][] transponerMatrise(double[][] matrise, int rad, int
kol, int id)
{
if((id != 2))
{
for (int i = rad; i < n/2 + rad; i++)
{
for (int j = kol+1; j < n/2 + kol; j++)
{
System.out.println("Traad " + id + " bytter " + i + "," + j + " med " + j + "," + i);
System.out.println("Value is " + matrise[i][j] + ", " + matrise[j][i]);
element = matrise[i][j];
matrise[i][j] = matrise[j][i];
matrise[j][i] = element;
}
}
}
else
{
for (int i = rad; i < n/2 + rad-1; i++)
{
for (int j = kol; j < n/2 + kol; j++)
{
System.out.println("Traad " + id + " bytter " + i + "," + j + " med " + j + "," + i);
System.out.println("Value is " + matrise[i][j] + ", " + matrise[j][i]);
element = matrise[i][j];
matrise[i][j] = matrise[j][i];
matrise[j][i] = element;
}
}
}
return matrise;
}
PS: I know the code works properly, because I have a checking method against a working sequential variant.
This is an a priori lost fight against O(N^2) costs-function
If I may turn your attention to a smarter approach, having an almost O(1) ( constant ) cost, the trick would help you start working in a way more promising direction.
May try to add one thin abstraction layer above the high-performance tuned ( cache-lines friendly "raw"-storage of the matrix elements. This abstracted layer will help to access the "raw"-storage ( using indexing-axes, index-striding and slicing tricks - the very same way as HPC FORTRAN libraries have inspired the well-known numpy and it's striding tricks) and this way the .T-method will do nothing expensive ( alike bulldozing N^2 memory locations, swapping there and back ) but simply swap axes-parameters in the abstract layer, responsible for the indirection mapper, taking a few tens of nanoseconds for whatever large matrise[N,N]; where N = 10, 100, 1000, 10000, 100000, 1000000, 10000000+ still a few [ns].
There is nothing faster in doing this or other, more complex, matrix operations and both the FORTRAN and numpy, performance polished, methods are a proof per-se of such observation.
Maybe it could be an simple idea to use a thread to swap a row to col but therefore you need twice the memory for you matrix which could be a problem on huge matrices. also if you have a 6 Core CPU i think there is not much benefit from using 100 thread so my thread pool is very small. And as #user3666197 mentioned its a still a expensive solution - but paralell ;-)
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MatrixTransposition {
public static void main(final String[] args) throws InterruptedException {
final MatrixTransposition transposition = new MatrixTransposition();
final int[][] source = transposition.create(32);
final int[][] transposed = transposition.solve(source);
System.out.println("Compare source and transpositon = " + transposition.compare(source, transposed));
final int[][] result = transposition.solve(transposed);
System.out.println("Compare source and double transpositon = " + transposition.compare(source, result));
transposition.print(source);
transposition.print(transposed);
}
public boolean compare(final int[][] a, final int[][] b) {
for (int r = 0; r < a.length; r++) {
for (int c = 0; c < a[0].length; c++) {
if (a[r][c] != b[r][c]) return false;
}
}
return true;
}
public int[][] create(final int size) {
final int[][] result = new int[size][size];
for (int r = 0; r < size; r++) {
for (int c = 0; c < size; c++) {
result[r][c] = r * size + c;
}
}
return result;
}
public void print(final int[][] input) {
final int size = input.length;
final int maxNr = size * size;
final int digits = new String(maxNr + "").length();
final String cellFormat = "%0" + digits + "d ";
for (int r = 0; r < input.length; r++) {
final int[] row = input[r];
for (final int c : row) {
System.out.print(String.format(cellFormat, c));
}
System.out.println("");
}
System.out.println("");
}
public int[][] solve(final int[][] input) throws InterruptedException {
final int width = input.length;
final int height = input[0].length;
final int[][] result = new int[width][height];
final CountDownLatch latch = new CountDownLatch(width);
for (int r = 0; r < width; r++) {
final int row = r;
threadPool.execute(() -> {
solvePart(result, input, row);
latch.countDown();
});
}
latch.await();
return result;
}
private void solvePart(final int[][] result, final int[][] input, final int r) {
System.out.println("Solve row " + String.format("%02d", r) + " in thread " + Thread.currentThread().getName());
final int[] row = input[r];
for (int c = 0; c < row.length; c++) {
result[c][r] = row[c];
}
}
private final ExecutorService threadPool = Executors.newFixedThreadPool(6);
}
based on the aproach of user3666197 you could do something like that:
public class Matrix {
private class Index {
Index(final int row, final int col) {
super();
this.row = row;
this.col = col;
}
int col;
int row;
}
public Matrix(final int rows, final int cols) {
this.rows = rows;
this.cols = cols;
data = new int[rows][cols];
}
public int get(final int row, final int col) {
return get(getIndex(row, col));
}
public void set(final int row, final int col, final int value) {
set(getIndex(row, col), value);
}
public void transpose() {
transpositioned = !transpositioned;
}
private int get(final Index index) {
return data[index.row][index.col];
}
private Index getIndex(final int row, final int col) {
return transpositioned ? new Index(col, row) : new Index(row, col);
}
private void set(final Index index, final int value) {
data[index.row][index.col] = value;
}
private final int cols;
private final int[][] data;
private final int rows;
private boolean transpositioned;
}

Multiple java threads on a 2-core Mac - Slow

I've been writing the following code for my OS course and I got some weird results. The code creates x threads and runs them concurrently in order to multiply two squared matrices. Every thread will multiply Number_of_rows/Number_of_threads rows of the input matrices.
When running it on a 1024X1024 matrices, with 1...8 threads, I get that the fastest multiplication happens when using only one thread. I would expect that a MacBook pro with i5 processor (2-cores) will utilize the two cores and that will yield faster results when using two threads.
Running time goes from about ~9.2 seconds using one thread, ~9.6 seconds to 27 seconds using 8.
Any idea why this is happening?
BTW, A few things about the code:
a. Assume that both matrices have identical dimensions and are square.
b. Assume that number of threads <= number of rows/columns.
public class MatrixMultThread implements Runnable {
final static int MATRIX_SIZE = 1024;
final static int MAX_THREADS = MATRIX_SIZE;
private float[][] a;
private float[][] b;
private float[][] res;
private int startIndex;
private int endIndex;
public MatrixMultThread(float[][] a, float[][]b, float[][] res, int startIndex, int endIndex) {
this.a = a;
this.b = b;
this.res = res;
this.startIndex = startIndex;
this.endIndex = endIndex;
}
public void run() {
float value = 0;
for (int k = startIndex; k < endIndex; k++) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
value += a[k][j]*b[j][i];
}
res[k][i] = value;
value = 0;
}
}
}
public static float[][] mult(float[][] a, float[][] b, int threadCount){
// Get number of rows per each thread.
int rowsPerThread = (int) Math.ceil(MATRIX_SIZE / threadCount);
float[][] res = new float[MATRIX_SIZE][MATRIX_SIZE];
// Create thread array
Thread[] threadsArray = new Thread[threadCount];
int rowCounter = 0;
for (int i = 0; i < threadCount; i++) {
threadsArray[i] = new Thread(new MatrixMultThread(a,b,res,rowCounter, Math.max(rowCounter + rowsPerThread, MATRIX_SIZE)));
threadsArray[i].start();
rowCounter += rowsPerThread;
}
// Wait for all threads to end before finishing execution.
for (int i = 0; i < threadCount; i++) {
try {
threadsArray[i].join();
} catch (InterruptedException e) {
System.out.println("join failed");
}
}
return res;
}
public static void main(String args[]) {
// Create matrices and random generator
Random randomGenerator = new Random();
float[][] a = new float[MATRIX_SIZE][MATRIX_SIZE];
float[][] b = new float[MATRIX_SIZE][MATRIX_SIZE];
// Initialize two matrices with initial values from 1 to 10.
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
a[i][j] = randomGenerator.nextFloat() * randomGenerator.nextInt(100);
b[i][j] = randomGenerator.nextFloat() * randomGenerator.nextInt(100);
}
}
long startTime;
for (int i = 1; i <= 8; i++) {
startTime = System.currentTimeMillis();
mult(a,b,i);
System.out.println("Total running time is: " + (System.currentTimeMillis() - startTime) + " ms");
}
}
}
Firstly a bit of logging helps. I did logging for this and found out a bug in your logic.
Here is the log
Starting execution for thread count: 1
Start index: 0
End index: 1024
Starting execution: MatrixMultiplier: 0
Ending executionMatrixMultiplier: 0
Total running time is: 6593 ms
Starting execution for thread count: 2
Start index: 0
End index: 1024 <------ This is the problem area
Start index: 512
End index: 1024
Starting execution: MatrixMultiplier: 1
Starting execution: MatrixMultiplier: 0
Your first thread in all iterations is performing whole multiplication everytime. That's why you are not seeing results. Figure out the bug.

How to compare integer elements within ArrayList?

I am trying to solve a problem by fetching the maximum number from each row in a triangle. So far am able to generate a triangle but how do I fetch the max number from each row?
Here is my code
private static Integer solve(Triangle triangle)
{
//triangle is extending an ArrayList
System.out.println(triangle);
return 0;
}
This is what am producing so far:
6
3 5
9 7 1
4 6 8 4
but now I want to get the result which says:
"In this triangle the maximum total is: 6 + 5 + 9 + 8 = 26"
Here is the complete code:
public class HellTriangle {
private static final int TRIANGLE_HEIGHT = 10;
public static void start() {
Triangle triangle = generateTriangle();
//System.out.println(triangle);
long start = System.currentTimeMillis();
Integer result = solve(triangle);
long end = System.currentTimeMillis();
System.out.println("Result:" + result);
System.out.println("Resolution time: " + (end - start) + "ms");
}
private static Triangle generateTriangle() {
Triangle triangle = new Triangle();
Random random = new Random();
for (int i = 0; i < TRIANGLE_HEIGHT; i++) {
Row row = new Row();
for (int j = 0; j <= i; j++) {
row.add(random.nextInt(100));
}
triangle.add(row);
}
return triangle;
}
private static class Row extends ArrayList<Integer> {
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size(); i++) {
sb.append(String.format("%02d", get(i)));
//rows.add(get(i));
if (i < (size() - 1)) {
sb.append(" ");
}
}
return sb.toString();
}
}
private static class Triangle extends ArrayList<Row> {
public String toString() {
// sb is used to make modification to the String
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size(); i++) {
for (int j = 0; j < (TRIANGLE_HEIGHT - 1 - i); j++) {
sb.append(" ");
}
sb.append(get(i));
if (i < (size() - 1)) {
sb.append("\n");
}
}
return sb.toString();
}
}
private static Integer solve(Triangle triangle) {
System.out.println(triangle);
return 0;
}
public static void main(String[] args) {
start();
}
}
Any help would be appreciated!
Here, just change with your solve()
private static void solve(Triangle triangle) {
System.out.println(triangle);
ArrayList<Integer> result = new ArrayList<Integer>();
int total = 0;
for(Row row : triangle){
Collections.sort(row);
total += row.get(row.size()-1);
result.add(row.get(row.size()-1));
}
for(Integer intr : result)
System.out.println("Largest elements of the rows: " + intr);
System.out.println("Total: " + total);
}
As there is no ordering in your rows and this would lead to O(n) to get the maximum value per row i would look up the maximum value during insertion. Something like that (not tested and you probably have to override the other add methods also, depending on your use case):
public class Row extends ArrayList<Integer> {
public String toString() {
...
}
private Integer max = null;
#Override
public boolean add(Integer elem) {
if (elem != null && (max == null || max < elem)) {
max = elem;
}
return super.add(elem);
}
public Integer getMax() {
return max;
}
}
Try
private static int getTriangleMax(final Triangle rows)
{
int max = 0;
for (final Row row : rows)
{
final int rowMax = getRowMax(row);
max += rowMax;
}
return max;
}
private static int getRowMax(final Row row)
{
int rowMax = Integer.MIN_VALUE;
for (final Integer integer : row)
{
if (rowMax < integer)
{
rowMax = integer;
}
}
return rowMax;
}
Simple-Solution:
1.Add the static list as here:
private static List maxRowVal=new ArrayList();
2.Replace your generateTriangle() function with this:
private static Triangle generateTriangle()
{
Triangle triangle = new Triangle();
Random random = new Random();
for (int i = 0; i < TRIANGLE_HEIGHT; i++) {
Row row = new Row();
int maxTemp=0;
for (int j = 0; j <= i; j++) {
int rand=random.nextInt(100);
row.add(rand);
if(rand>maxTemp)
maxTemp=rand; //will get max value for the row
}
maxRowVal.add(maxTemp);
triangle.add(row);
}
return triangle;
}
Simple indeed!!
This is not exactly what you asked for, but I would like to show you a different way to go about this problem. People have done this for me before, and I really appreciated seeing different ways to solve a problems. Good luck with your coding!
Below is the code in its entirety, so you can just copy, paste and run it.
public class SSCCE {
public static void main(String[] args) {
// Here you specify the size of your triangle. Change the number dim to
// whatever you want. The triangle will be represented by a 2d-array.
final int dim = 5;
int[][] triangle = new int[dim][dim];
// Walks through the triangle and fills it with random numbers from 1-9.
for (int r = 0; r < dim; r++) {
for (int c = 0; c < r + 1; c++) {
triangle[r][c] = (int) (9 * Math.random()) + 1;
}
}
// This piece just prints the triangle so you can see what's in it.
for (int r = 0; r < dim; r++) {
for (int c = 0; c < r + 1; c++) {
System.out.print(triangle[r][c] + " ");
}
System.out.println();
}
// This part finds the maximum of each row. It prints each rows maximum
// as well as the sum of all the maximums at the end.
int sum = 0;
System.out.print("\nIn this triangle the maximum total is: ");
for (int r = 0; r < dim; r++) {
int currentMax = 0;
for (int c = 0; c < r + 1; c++) {
if (triangle[r][c] > currentMax) {
currentMax = triangle[r][c];
}
}
sum += currentMax;
if (r != 0) {
System.out.print(" + ");
}
System.out.print(currentMax);
}
System.out.println(" = " + sum + ".");
}
}
Output:
9
9 2
1 7 3
1 7 3 3
5 7 5 1 9
In this triangle the maximum total is: 9 + 9 + 7 + 7 + 9 = 41.

Writing a program calculating exponents

I'm trying to write a program that prints the results of the exponents of the number 2 and I want to print it out 10 times. I want to create a a method that calculates the value of the exponents using the Math.pow(x,y) method.
2 to the power of 0 = 1
2 to the power of 1 = 2
2 to the power of 2 = 4
I have a couple of questions. Can you use the Math.pow method in a for loop like I did below? How do you declare the value of x and y in the method Math.pow(x, y) inside a for loop or do you have to do it outside a for loop? Also, in the raiseIntPower method in Eclipse when I use int n as a parameter it gives me a "duplicate local variable error." My understanding is the method parameters specifies the argument the method requires. I don't understand the meaning of that duplicate error.
import acm.program.*;
public class Exponents extends ConsoleProgram {
public void run(){
for (int n = 0; n <= 10; n++) {
println("2 to the power of " + n + " = " + raiseIntPower(n));
}
}
private int raiseIntPower (int n){
int total = 0;
for( int n = 0; n <= 10; n++){
total = Math.pow(2, n);
}
return total;
}
}
I dont understand what are you trying to do
just replace the statement
println("2 to the power of " + n + " = " + raiseIntPower(n));
with
println("2 to the power of " + n + " = " + Math.pow(2,n));
and it should do it , no need for raiseIntPower()
I think you are confused about the usage of Math.pow() , please refer here for clarifications Math.pow()
Math#pow(double a, double b) where a is the base and b is the exponent, ab and it returns double so if you want to discard precision then you have to format return value.
you can remove raiseIntPower method.
for (int n = 0; n <= 10; n++) {
println("2 to the power of " + n + " = " + Math.pow(2,n));
}
check this one
import acm.program.*;
public class Exponents extends ConsoleProgram {
public void run(){
for (int n = 0; n <= 10; n++) {
println("2 to the power of " + n + " = " + raiseIntPower(n));
}
}
private int raiseIntPower (int n){
int total = 0;
total = (int)Math.pow(2, n);
return total;
}
}
Eclipse gives you a "duplicate local variable error" because there is a duplicate variable.
private int raiseIntPower (int n){
int total = 0;
for( int n = 0; n <= 10; n++){
total = Math.pow(2, n);
}
return total;
}
You declared a variable n for input. In the for loop, you declared another variable n. The int n and references to it in the for loop should be changed to another name, such as int i.

Merge Sort. Error-- Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2

Good day, everyone! I have here a program that sorts 50,000 words from a file using merge sort. I followed Thomas Cormen's pseudocode in his Introduction to Algorithms and it seems right when I'm "debuuging" it by hand manually. However, when I run the program it says Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 . Yes, I think it is due to the large NO_OF_WORDS (ie, 50,000) but even though I decreased it to 10, still, it shows the same error.
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static void merge(String[] A, int p, int q, int r) {
int n1 = q-p+1;
int n2 = r-q;
String[] L = new String[n1+1];
String[] R = new String[n2+1];
for (int i=1; i<n1; i++) {
L[i] = A[p+i-1];
}
for (int j=1; j<n2; j++) {
R[j] = A[q+j];
}
L[n1+1] = "zzzzz"; //for infinity because if I use Math.floor, it will return a double
R[n2+1] = "zzzzz";
int i=1;
int j=1;
for (int k=p; k<=r; k++) {
int comparison = L[i].compareTo(R[j]);
if (comparison <= 0){
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
}
}
public static void mergeSort (String[] A, int p, int r) {
if (p<r) {
int q = (p+r)/2;
mergeSort(A, p, q);
mergeSort(A, q+1, r);
merge(A, p, q, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 50000;
try {
Scanner file = new Scanner(new File(args[0]));
String[] words = new String[NO_OF_WORDS];
int i = 0;
while(file.hasNext() && i < NO_OF_WORDS) {
words[i] = file.next();
i++;
}
long start = System.currentTimeMillis();
mergeSort(words, 0, words.length-1);
long end = System.currentTimeMillis();
System.out.println("Sorted Words: ");
for(int j = 0; j < words.length; j++) {
System.out.println(words[j]);
}
System.out.print("Running time: " + (end - start) + "ms");
}
catch(SecurityException securityException) {
System.err.println("Error");
System.exit(1);
}
catch(FileNotFoundException fileNotFoundException) {
System.err.println("Error");
System.exit(1);
}
}
}
I think it's because of the declaration of String[] L and R. Or not. Please help me what's the problem. Thank you very much!
EDIT
Cormen's Pseudocode
MERGE(A, p, q, r )
n1 ← q − p + 1
n2 ←r − q
create arrays L[1 . . n1 + 1] and R[1 . . n2 + 1]
for i ← 1 to n1
do L[i ] ← A[p + i − 1]
for j ← 1 to n2
do R[ j ] ← A[q + j ]
L[n1 + 1]←∞
R[n2 + 1]←∞
i ← 1
j ← 1
for k ← p to r
do if L[i ] ≤ R[ j ]
then A[k] ← L[i ]
i ←i + 1
else A[k] ← R[ j ]
j ← j + 1
I don't know what is your pseudocode but your implementation seems wrong. I've look at the wikipedia merge sort and it's quite different.
So I will not give you the full working algorithm here. I'll just give you the solution to resolve your problem of indexOutOfBounds but you still have to work more on your implementation.
In Java when you do that :
String[] L = new String[5];
You declare an array of string that can contains 5 strings within.
The access to those strings is made this way : L[anIndex].
The first element is at index 0.
So if you have an array of size 5 then the last element is at index 4 (because we start from 0).
In your code you do this :
String[] L = new String[n1+1];
String[] R = new String[n2+1];
then :
L[n1+1] = "zzzzz";
R[n2+1] = "zzzzz";
So here you always try to access a string at an index that doesn't exist.
The last element in each array is respectively n1 and n2 (because arrays size are n1+1 and n2+1 ).
I hope you'll understand better how array works in Java with this explanation. Now you have to improve your implementation because it's still not working. Maybe give us the pseudocode you use if you don't understand it well.
EDIT :
Ok I made some correction.
Here is the working algorithm. I've had to change several index to fit Java "based-0 arrays", take a look :
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static void merge(String[] A, int p, int q, int r) {
int n1 = q-p+1;
int n2 = r-q;
if(A[p]==null || A[q]==null)return;
String[] L = new String[n1+1];
String[] R = new String[n2+1];
for (int i=0; i<n1; i++) {
L[i] = A[p+i];
}
for (int j=0; j<n2; j++) {
R[j] = A[q+j +1];
}
L[n1] = "zzzzz"; //for infinity because if I use Math.floor, it will return a double
R[n2] = "zzzzz";
int i=0;
int j=0;
for (int k=p; k<=r; k++) {
int comparison = L[i].compareTo(R[j]);
if (comparison <= 0){
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
}
}
public static void mergeSort (String[] A, int p, int r) {
if (p<r) {
int q = (p+r)/2;
mergeSort(A, p, q);
mergeSort(A, q+1, r);
merge(A, p, q, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 50000;
try {
Scanner file = new Scanner("bla blya blay byla ybla");
ArrayList<String> words = new ArrayList<String>();
while(file.hasNext() && words.size() < NO_OF_WORDS) {
words.add(file.next());
}
String [] wordsArray = new String[words.size()];
words.toArray(wordsArray);
long start = System.currentTimeMillis();
mergeSort(wordsArray, 0, wordsArray.length-1);
long end = System.currentTimeMillis();
System.out.println("Sorted Words: ");
for(int j = 0; j < wordsArray.length; j++) {
System.out.println(wordsArray[j]);
}
System.out.print("Running time: " + (end - start) + "ms");
}
catch(SecurityException securityException) {
System.err.println("Error");
System.exit(1);
}
}
}
Note that I've change your Main, now I use an arrayList to avoid null value, if your text contains less words than the original array size. With your solution if you don't fill the 50000 words you get null in the array and then nullPointerException in the merge algo.
There is a big problem with your merge() method:
String[] L = new String[n1+1];
String[] R = new String[n2+1];
will not play well with
L[n1+1] = "zzzzz"; //for infinity because if I use Math.floor, it will return a double
R[n2+1] = "zzzzz";
You will get an ArrayIndexOutOfBoundsException here regardless of the values of n1 and n2 since arrays are 0-based in Java.

Categories

Resources