MergeSort - ArrayIndexOutOfBoundsException - java

I am sorry if this has already been answered somewhere, I have spent over an hour searching through many previous questions and none of them were able to help me with this error.
I randomly receive an error, probably 70% of the time:
--------------------Configuration: MergeSort - JDK version 1.7.0_45 <Default> - <Default>- -------------------
Random array: 17 14 3 4 1 10 13 9 3 1 6 9 10 2 17 8 10 5 7 8
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at MergeSort.merge(MergeSort.java:64)
at MergeSort.mergeSort(MergeSort.java:26)
at Driver.main(Driver.java:18)
Process completed.
Line 64 would refer to: "scratch[scratch_index] = list[i];"
public void merge(int[] list, int first, int middle, int last)
{
int[] scratch = new int[list.length];
int midpoint = (first+last)/2;
int left_index = first;
int right_index = middle + 1;
int scratch_index = left_index;
while((left_index <= midpoint) && (right_index <= last))
{
if(list[left_index] <= list[right_index])
{
scratch[scratch_index] = list[left_index];
left_index +=1;
}
else
{
scratch[scratch_index] = list[right_index];
right_index +=1;
}
scratch_index +=1;
}
for(int i=left_index;i<=midpoint;i++)
{
scratch[scratch_index] = list[i];
scratch_index +=1;
}
for(int i=right_index;right_index<=last;i++) // I am line 64
{
scratch[scratch_index] = list[i];
scratch_index +=1;
}
for(int i=0;i<list.length;i++)
{
list[i] = scratch[i];
}
}
This is my first question ever on this site, sorry if I have not formatted this question correctly, any advice is appreciated.
If any other information is needed to help me with solving this error, just let me know.
Thank you!

At the comment // I am line 64 You are incrementing the i and not the right_index which will cause the index to keep increasing until reaching index out of bound, so replace this,
for(int i=right_index;right_index<=last;i++) // I am line 64
by this:
for(int i=right_index; i<=last;i++)

Indexes use "zero-based numbering" >> https://en.wikipedia.org/wiki/Zero-based_numbering
String example = "01234";
System.out.println(example.size()); //Prints out 5
System.out.println(exmaple.indexOf("1")); //Prints out 1
Your for statement needs to be checking up TO the last index
for(int i=right_index;right_index<last;i++)
OR (not recommended)
for(int i=right_index;right_index<=last-1;i++) //Works, but not recommended due to conventions
//index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Random array: 17 14 3 4 1 10 13 9 3 1 6 9 10 2 17 8 10 5 7 8
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20

Related

Calculating total weight of MST using Prim's and a heap

Attempting to implement a method that builds a MST using prim's and a min heap (using priority queue) and returns the total weight of the MST.
My code seems to produce different results to what is expected, however, looking at my code it seems to be fundamentally correct and follows closely to other examples online.
for (int v = 0; v < size; v++) {
key[v] = Integer.MAX_VALUE;
pred[v] = null;
visited[v] = false;
}
int s = 0;
key[s] = 0;
for (int v = 0; v < size; v++) {
minHeap.add(new T(v, key[v], pred[v]));
}
while (!minHeap.isEmpty()) {
int u = minHeap.poll().vertex;
for (int v = 0; v < size; v++) {
if (g.getWeight(u, v) > 0 && !visited[v]) {
if (g.getWeight(u, v) < key[v]) {
key[v] = g.getWeight(u, v);
pred[v] = u;
minHeap.add(new T(v, key[v], pred[u]));
}
}
}
visited[u] = true;
}
int distance = 0;
for (int i = 0; i < size; i++) {
distance += key[i];
if (!visited[i])
return -1;
}
return distance;
current input is an adjacency array:
5 16 5 8 19 9 8 1 5 8
16 10 19 7 7 5 15 4 7 18
5 19 1 7 1 20 12 15 9 2
8 7 7 14 11 18 13 5 11 14
19 7 1 11 0 15 10 17 0 8
9 5 20 18 15 0 11 20 10 7
8 15 12 13 10 11 8 14 20 20
1 4 15 5 17 20 14 12 0 8
5 7 9 11 0 10 20 0 5 7
8 18 2 14 8 7 20 8 7 15
expected output is: 36
current output is: 32
Perhaps your minHeap is sorting items to the largest key[v] rather than smallest. Maybe try
minHeap.add(new T(v, Integer.MAXVALUE - key[v], pred[u]));
The problem was in where the visited[u] = true statement was.
moving that statement to after polling for vertex with highest priority in minHeap and before the loop checking for adjacent vertices fixed it.

Is there a best approach to create four times 1 - 12 blocks through a loop

There is a loop that increments the counter 48 times to write certain values to an Excel file.
In the range 1 - 48, 4 blocks from 1 - 12 are to be written.
Expected example:
1 2 3 4 5 6 7 8 9 10 11 12 - 1 2 3 4 5 6 7 ... and so on (4 times).
I have tried different approaches, if/else, switch/case but here I have not come to any result.
My last approach is an if condition with the modolu operator.
for (int i = 1; i <= 48; i++) {
if (i % 12 != 0) {
for (int j = 1; j <= 12; j++) {
workBook.setNumber(HEADLINE_ROW, i + 6, j);
}
} else {
workBook.setNumber(HEADLINE_ROW, i + 6, 12);
}
}
But with this approach I get 12 12 12 12 and so on.
I recognize the error, but currently have no idea how to solve the problem. The part where data is written to the Excel file is rather unimportant. I am concerned with the logic.
I'm stuck in the logic here and can't get any further. Do you have any ideas or suggestions for improvement on how I can generate four 1 - 12 blocks side by side?
do something like that
python
for i in range(48):
index = i % 12 + 1
# do what ever you want here
print(index)
java
for(int i = 0; i < 48; i++) {
int index = i % 12 + 1;
// do something here
}
I think the pseudo code for what you want would be:
for (int i=1; i <= 48; i++) {
int j = i % 12 + 1; // 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 ...
// do something with i and (j + 1)
}
That is, work with the outer loop counter mod 12, which would give you the sequence 1, 2, ..., 12, four times.

For-loop output explanation needed?

I need an explanation of how the output prints 9(S), 7(S), 5(S) and 3(S).
10 > 3 is correct and goes to y 1 <= 2 which is correct so 2 x 10 - 2 = 18 but the output prints 9. I don't understand the logic here. Why does it print 9(s) instead of 18(s)?
public class Q2{
public static void main(String args[]) {
int x,y;
for(x= 10; x > 3; x = x - 2) {
for(y = 1; y <= 2 * x - 2; y = y + 2)
System.out.print("S");
System.out.print("\n");
}
}
}
Its correct Y <= 18 , but you are incrementing Y by 2, so it gets printed 9 times.
To understand, write down on a piece of paper what the values of your variables will be.
First, write down the values of x:
x: 10 8 6 4
Next, write down the calculated upper boundary value for y, i.e. the result of expression 2 * x - 2:
x : 10 8 6 4
yMax: 18 14 10 6
Last, write down the values of y:
x : 10 8 6 4
yMax: 18 14 10 6
y : 1 1 1 1
3 3 3 3
5 5 5 5
7 7 7
9 9 9
11 11
13 13
15
17
Finally, count the number of y values for each x value, i.e. the number of times S is printed:
x : 10 8 6 4
count: 9 7 5 3
Then realize that the code would have been much easier to understand if it had just been written like this:
for (int count = 9; count >= 3; count -= 2) {
for (int i = 0; i < count; i++) {
System.out.println("S");
}
}
Of course, that wouldn't have taught you what they were trying to teach you, which is:
Conclusion: If you don't understand what the code is doing, follow the logic step by step, and write down what it is doing.

Outputting values 1 to A, with B values per row (Java)

public static void applicationB(int A, int B) {
int number = 1;
for (int row = 0; row < A; row++) {
for (int col = 0; col < B; col++) {
int output = number + row++;
System.out.printf("% 4d", output);
}
// does it skip because of this?
System.out.println("");
}
}
It outputs with A = 20, B = 5
1 2 3 4 5
7 8 9 10 11
13 14 15 16 17
19 20 21 22 23
The correct output should be
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
I cannot figure out how to get it to stop skipping 6, 12, and 18.
Am I just doing this a horrible way? or am I on the right track?
You are incrementing row in two places. Also, it would be easier to just have one loop, and output a line break every B elements (you can use i % B to test for this).
I would suggest the following approach. Iterate over the values you want to print out, from 1 to the maximum value (A). Then, print a newline whenever the remainder of value divided by the number of columns (B) is zero.
for (int value = 1; value <= A; value++) {
System.out.printf("% 4d", value);
if (value % B == 0) {
System.out.println("");
}
}

Array Printf issue

I'm working on simple program that is supposed to list the numeric values in an array; a certain way. This is how I would like to have the output look like:
Printing Array:
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22
It has to be lined as seen above and line must only contain 10 numbers.
I seem to have everything formatted correctly but my output doesn't look like that.
Here is what I am getting:
Printing Array:
1
2 3 4 5 6 7 8 9 10 11
12 13 14 15 16 17 18 19 20 21
22
I'm not sure exactly what I'm doing wrong but here's my code:
//disregard the name 'Juice', I like to give my programs weird names
public class Juice
{
public static void main(String[] args)
{
//sets up the array
int[] numbers = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22};
//title
System.out.println("Printing Array: ");
//counting the elements
for (int i = 0; i < numbers.length; i++)
{
//prints each element value with 4 spaces in between
System.out.printf("%4d", numbers[i]);
//once line reaches ten values; print new line
if (i % 10 == 0)
{
System.out.printf("\n");
}
}
}
}
if ((i+1) % 10 == 0)
{
System.out.printf("\n");
}
Your code does what you asked it to.
On first loop, i=0, but i % 10 == 0 is also true, so it prints new line.
You can use many different approaches to fix this, but probably easiest one will be to replace this condition to (i+1) % 10 == 0 or to i % 10 == 9.
you almost did it
public class Juice
{
public static void main(String[] args)
{
//sets up the array
int[] numbers = {1,2,3,4,5,6,7,8,9,10,12,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};
//title
System.out.println("Printing Array: ");
//counting the elements
for (int i = 0; i < numbers.length; i++)
{
//prints each element value with 4 spaces in between
System.out.printf("%4d", numbers[i]);
//once line reaches ten values; print new line
if (i % 10 == 9)
{
System.out.printf("\n");
}
}
}
}
i've modified a conditions to if (i % 10 == 9)
OUTPUT
Printing Array:
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32
Alternatively to avoid the confusion between the index to the array element and the element count switch to using a foreach loop.
//counting the elements
int i = 1;
for (int number : numbers) {
//prints each element value with 4 spaces in between
System.out.printf("%4d", number);
//once line reaches ten values; print new line
if (i % 10 == 0) {
System.out.println();
}
i++;
}

Categories