Algorithms works some of the time, doesnt work other times. I'm using the JUnit tests found here http://www.vogella.com/tutorials/JavaAlgorithmsMergesort/article.html#mergesort_test
Thanks for any help.
Java Code
package sorting;
public class MergeSort {
public static int[] sort(int[] A) {
mergeSortHelper(A, new int[A.length], 0, A.length - 1);
return A;
}
private static void mergeSortHelper(int[] A, int[] helper, int p, int r) {
if (p < r) {
int mid = (p + r)/2;
mergeSortHelper(A, helper, p, mid);
mergeSortHelper(A, helper, mid + 1, r);
merge(A, helper, p, mid, r);
}
}
private static void merge(int A[], int[] helper, int p, int q, int r) {
for (int i = p; i <= r; i++) {
helper[i] = A[i];
}
int j = p;
int k = q + 1;
int count = 0;
while (j <= q && k <= r) {
if (helper[j] <= helper[k]) {
A[p+count] = helper[j++];
} else {
A[p+count] = helper[k++];
}
count++;
}
while (j <= q) {
A[p+count] = A[j++];
count++;
}
while (k <= r) {
A[p+count] = A[k++];
count++;
}
}
}
JUnit
package tests;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import sorting.MergeSort;
public class MergeSortTest {
private int[] numbers;
private final static int SIZE = 7;
private final static int MAX = 20;
#Before
public void setUp() throws Exception {
numbers = new int[SIZE];
Random generator = new Random();
for (int i = 0; i < numbers.length; i++) {
numbers[i] = generator.nextInt(MAX);
}
}
#Test
public void testMergeSort() {
long startTime = System.currentTimeMillis();
MergeSort.sort(numbers);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Mergesort " + elapsedTime);
for (int i = 0; i < numbers.length - 1; i++) {
if (numbers[i] > numbers[i + 1]) {
fail("Should not happen");
}
}
assertTrue(true);
}
#Test
public void itWorksRepeatably() {
for (int i = 0; i < 200; i++) {
numbers = new int[SIZE];
Random generator = new Random();
for (int a = 0; a < numbers.length; a++) {
numbers[a] = generator.nextInt(MAX);
}
MergeSort.sort(numbers);
for (int j = 0; j < numbers.length - 1; j++) {
if (numbers[j] > numbers[j + 1]) {
fail("Should not happen");
}
}
assertTrue(true);
}
}
#Test
public void testStandardSort() {
long startTime = System.currentTimeMillis();
Arrays.sort(numbers);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("Standard Java sort " + elapsedTime);
for (int i = 0; i < numbers.length - 1; i++) {
if (numbers[i] > numbers[i + 1]) {
fail("Should not happen");
}
}
assertTrue(true);
}
}
Wrong:
while (j <= q) {
A[p+count] = A[j++];
count++;
}
while (k <= r) {
A[p+count] = A[k++];
count++;
}
Corrected:
while (j <= q) {
A[p+count] = helper[j++];
count++;
}
while (k <= r) {
A[p+count] = helper[k++];
count++;
}
I modified the code :) to pass tests but I'm not sure if it's 100% secure code. Use it at your own risk.
package sorting;
public class MergeSort {
public static int[] sort(int[] A) {
mergeSortHelper(A, new int[A.length], 0, A.length - 1);
return A;
}
private static void mergeSortHelper(int[] A, int[] helper, int p, int r) {
if (p < r) {
int mid = (p + r)/2;
mergeSortHelper(A, helper, p, mid);
mergeSortHelper(A, helper, mid + 1, r);
merge(A, helper, p, mid, r);
}
}
private static void merge(int A[], int[] helper, int p, int q, int r) {
for (int i = p; i <= r; i++) {
helper[i] = A[i];
}
int j = p;
int k = q + 1;
int count = 0;
while (j <= q && k <= r) {
if (helper[j] < helper[k]) {
A[p+count] = helper[j++];
} else {
A[p+count] = helper[k++];
}
count++;
}
while (j <= q) {
A[p+count++] = helper[j++];
}
while (k <= r) {
A[p+count++] = helper[k++];
}
}
}
These are the changes incured
diff --git a/src/sorting/MergeSort.java b/src/sorting/MergeSort.java
index 0f5c8e4..dbf6689 100644
--- a/src/sorting/MergeSort.java
+++ b/src/sorting/MergeSort.java
## -35,7 +35,7 ##
int count = 0;
while (j <= q && k <= r) {
- if (helper[j] <= helper[k]) {
+ if (helper[j] < helper[k]) {
A[p+count] = helper[j++];
} else {
A[p+count] = helper[k++];
## -45,13 +45,11 ##
}
while (j <= q) {
- A[p+count] = A[j++];
- count++;
+ A[p+count++] = helper[j++];
}
while (k <= r) {
- A[p+count] = A[k++];
- count++;
+ A[p+count++] = helper[k++];
}
}
}
\ No newline at end of file
// https://github.com/kangchen/SortAlgorithm
import java.util.ArrayList;
import java.util.List;
public final class MergeSort implements Runnable, Sort {
private List<Integer> list;
private List<Integer> temp = new ArrayList<Integer> ();
private long time = 0;
private boolean sortCompleted = false;
public MergeSort(List<Integer> item) {
this.list = item;
initializeTempList();
}
public void run() {
sort();
System.out.println(this.toString());
}
private void initializeTempList() {
for(int i=0; i<list.size(); i++) {
temp.add(0);
}
}
/*
* Merge Sort Algorithm O(N*LOGN)
*/
public void sort() {
long starttime = System.nanoTime();
mergePartition(0, list.size()-1);
long endtime = System.nanoTime();
time = endtime - starttime;
sortCompleted = true;
}
private void mergePartition(int low, int high) {
if (low == high) return;
else {
int mid = (low + high) / 2;
mergePartition(low, mid);
mergePartition(mid+1, high);
merge(low, mid+1, high);
}
}
private void merge(int lowPtr, int midPtr, int highPtr) {
int ci = 0;
int ai = lowPtr;
int mid = midPtr - 1;
int bi = highPtr - ai + 1;
while (lowPtr <= mid && midPtr <= highPtr) {
if (list.get(lowPtr) < list.get(midPtr)) {
temp.set(ci++, list.get(lowPtr++));
}
else {
temp.set(ci++, list.get(midPtr++));
}
}
/*
* copy remaining sorted elements
*/
while (lowPtr <= mid) {
temp.set(ci++, list.get(lowPtr++));
}
/*
* copy remaining sorted elements
*/
while (midPtr <= highPtr) {
temp.set(ci++, list.get(midPtr++));
}
/*
* replace original elements with sorted elements
*/
copy(ai, bi, temp);
}
private void copy(int from, int num, List<Integer> arrTemp) {
for(int i=0; i<num; i++){
list.set(from+i, arrTemp.get(i));
}
}
public long getTime() {
return time;
}
public String toString() {
return "Merge sort is completed in " + getTime() + " nanoseconds";
}
private void swap(int x, int y) {
int tmp = list.get(x);
list.set(x, list.get(y));
list.set(y, tmp);
}
public void reversedList() {
int idx = list.size()/2;
int high = list.size()-1;
for(int low=0; low<idx; low++) {
swap(low, high--);
}
}
public boolean isSortCompleted() {
return sortCompleted;
}
}
Related
I am writing a merge sort algorithm that will sort an ArrayList then search the sorted list to see if a value match's two numbers in the list. I am getting an error after the while loop in the merge method. The error is ConcurrentModificationException but I am not too sure why. Ideally keeping the code as similar as possible.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Value {
static List<Integer> test = new ArrayList<>();
static public void main(String[] args) {
System.out.println("Generate Array");
setUpArray(test);
System.out.println(Arrays.asList(test));
Scanner scan = new Scanner(System.in);
System.out.println("Please enter Value");
int value = scan.nextInt();
scan.close();
mergeSort(test);
boolean b = findValue(test,value);
if(b){
System.out.println("Found");
}else{
System.out.println("Couldn't Find");
}
}
public static void mergeSort(List<Integer> input) {
int inputLength = input.size();
int mid = inputLength / 2;
if (inputLength < 2) {
return;
}
List<Integer> left = input.subList(0, mid);
List<Integer> right = input.subList(mid, inputLength);
mergeSort(left);
mergeSort(right);
merge(input, left, right);
}
public static void merge(List<Integer> input, List<Integer> left, List<Integer> right) {
int i = 0, j = 0, k = 0;
while (i < left.size() && j < right.size()) {
if (left.get(i) <= right.get(j)) {
input.add(k, left.get(i));
i++;
} else {
input.add(k, right.get(j));
j++;
}
k++;
}
while (i < left.size()) {
input.add(k, left.get(i));
i++;
k++;
}
while (j < right.size()) {
input.add(k, right.get(j));
j++;
k++;
}
}
public static boolean findValue(List<Integer> input, Integer value) {
int i = 0;
int j = input.size() - 1;
while (i < j) {
if (input.get(i) + input.get(j) == value) {
return true;
} else if (input.get(i) + input.get(j) < value) {
i++;
} else {
j--;
}
}
return false;
}
public static void setUpArray(List<Integer> test) {
for (int i = 0; i < 20; i++) {
int value = (int) (Math.random() * 100);
Value.test.add(value);
}
}
}
The code still error, even though I have already fixed almost half the program
this initialized at main class:
Getting the below error:
Exception in thread "main"
java.lang.NullPointerException
at Tugas7.No3.seqSearch(No3.java:72)
at Tugas7.No3Main.main(No3Main.java:27)
what are you expecting to get out?
I excepting the code when run can search the number
package Tugas7;
public class No3 {
public int[] data;
public int jumData,min,max;
;
public int baris, kolom, posisiBar, posisiKol, posisi;
public void No3(int[] data) {
sort(data, 0, 8);
}
private void merge(int[] data, int left, int middle, int right) {
int[] temp = new int[data.length];
for (int i = left; i <= right; i++) {
temp[i] = data[i];
}
int a = left;
int b = middle + 1;
int c = left;
while (a <= middle && b <= right) {
if (temp[a] <= temp[b]) {
data[c] = temp[a];
a++;
} else {
data[c] = temp[b];
b++;
}
c++;
}
int s = middle - a;
for (int i = 0; i <= s; i++) {
data[c + i] = temp[a + i];
}
}
private void sort(int data[], int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
sort(data, left, middle);
sort(data, middle + 1, right);
merge(data, left, middle, right);
}
}
public void printArray(int arr[]) {
int n = arr.length;
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public int[] Searching(int[] Data, int jmlData) {
this.jumData = 10;
data = new int[jumData];
for (int i = 0; i < jumData; i++) {
data[i] = Data[i];
}
return data;
}
public int seqSearch(int cari) {
this.posisi = -1;
for (int j = 0; j < 11; j++) {
if (data[j] == cari) {
posisi = j;
break;
}
}
return posisi;
}
public void TampilData() {
for (int i = 0; i < 10; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
public void searchMax(int[] data) {
min = data[0];
max = data[0];
for (int i = 0; i < 10; i++) {
if (data[i] < min) {
min = data[i];
} else if (data[i] > max) {
max = data[i];
}
}
}
}
I would like to make my code more implementable for others applications.
I don't have problems with the code, it works perfectly. I would just like to rewrite it to use it in other contexts.
My original code:
import java.util.concurrent.*;
class Sum extends RecursiveTask<Double> {
final int seqThresHold = 500;
double[] data;
int start, end;
Sum(double[] vals, int s, int e ) {
data = vals;
start = s;
end = e;
}
protected Double compute() {
double sum = 0;
if((end - start) < seqThresHold) {
for(int i = start; i < end; i++) sum += data[i];
}
else {
int middle = (start + end) / 2;
Sum subTaskA = new Sum(data, start, middle);
Sum subTaskB = new Sum(data, middle, end);
subTaskA.fork();
subTaskB.fork();
sum = subTaskA.join() + subTaskB.join();
}
return sum;
}
}
class RecurTaskDemo {
public static void main(String args[]) {
ForkJoinPool fjp = new ForkJoinPool();
double[] nums = new double[5000];
for(int i=0; i < nums.length; i++)
nums[i] = (double) (((i%2) == 0) ? i : -i) ;
Sum task = new Sum(nums, 0, nums.length);
double summation = fjp.invoke(task);
System.out.println("Summation " + summation);
}
}
The new code I would like to get:
public class RecurTaskDemo {
private static double Sum(double[] data, int start, int end) {
double sum = 0;
for (int i = start; i < end; i++) {
sum += data[i];
}
return sum;
}
// ???
public static void main(String args[]) {
double[] nums = new double[4000];
for (int i = 0; i < nums.length; i++)
nums[i] = (double) (((i % 2) == 0) ? i : -i);
double sum = Sum(nums, 0, 4000);
// double sum = ... I would like to calculate 'sum' using 'Sum(...)' + '???'
System.out.println(sum);
}
}
I'm new to java and I have a weighted union find algorithm. When I run this code in eclipse on a scrapbook page, it keeps evaluating forever.
java code
public class weightedUF {
private int[] id;
private int[] sz;
public weightedUF(int N) {
id = new int[N];
sz = new int[N];
for (int i = 0; i < N; i++) {
id[i] = i;
}
for (int i = 0; i < N; i++) {
sz[i] = 1;
}
}
private int root(int i) {
while (i != id[i]) {
i = id[i];
}
return i;
}
public boolean connected(int p, int q) {
return root(p) == root(q);
}
public void union(int p, int q) {
int i = root(p);
int j = root(q);
if (sz[i] < sz[j]) {
id[i] = j;
sz[j] += sz[i];
}
else {
id[j] = i;
sz[i] += sz[j];
}
id[i] = j;
}
}
scrapbook test code
weightedUF union = new weightedUF(10);
union.union(9, 2);
union.union(5, 2);
union.union(1, 8);
union.union(5, 7);
union.union(4, 3);
union.union(0, 7);
union.union(1, 3);
union.union(2, 4);
union.union(8, 6);
union
I think you should remove your last line :
id[i] = j;
it's corrupting your id array.
Sorry if my question is not clear, lets say I have int a = 1234;.
How can I print as follows, for a number of any length?
123
132
213
231
321
312
Thanks in advance.
public class Test {
private static void swap(int[] p, int i, int j) {
int t= p[i];
p[i]= p[j];
p[j]= t;
return;
}
private static boolean nextPerm(int[] p) { // need p.length > 1
int n= p.length;
int i= n;
if (i-- < 1) return false;
for(;;) {
int ii= i--;
if (p[i] < p[ii]) {
int j= n;
while (!(p[i] < p[--j]));
swap(p, i, j);
for (j= n; j > ii; swap(p, --j, ii++));
return true;
}
if (i == 0) {
for (int j= n; j > i; swap(p, --j, i++));
return false;
}
}
}
public static void main(String[] args) {
int x = 123;
String s = "" + x;
int n = s.length();
int[] p = new int[n];
for (int i = 0; i < n; i++){
p[i] = i;
}
do {
for (int i = 0; i < n; i++){
System.out.print(s.charAt(p[i]));
}
System.out.println();
}
while (nextPerm(p));
}
}
finally I found, below is the code,
class ShuffleNumber {
private static int[] a = {1,2,3};
private static void print(int[] a) {
for (int i = 0; i < a.length; i++)
System.out.print(" " + a[i]);
System.out.println();
}
private static void shuffle(){
int[] b = (int[])a.clone();
for (int i = b.length - 1; i > 0; i--) {
int j = (int)Math.floor(Math.random() * (i+1));
int temp = b[j];
b[j] = b[i];
b[i] = temp;
}
print(b);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++)
shuffle();
}
}