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);
}
}
}
Related
I need to return -1 if one of this two conditions: biggerThanK(array[i], k), or prim(array[i]) return false. I tried to put an else { smallest = -1; } but if I input values that respect both conditions it still displays -1.
import java.util.Scanner;
public class Main {
public static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int smallest = Integer.MAX_VALUE;
int n = scanner.nextInt();
int k = scanner.nextInt();
int[] array = new int[n];
for (int i = 0; i < array.length; i++) {
array[i] = scanner.nextInt();
}
for (int i = 0; i < array.length; i++) {
if (biggerThanK(array[i], k) && prim(array[i])) {
if (array[i] < smallest) {
smallest = array[i];
}
}
}
System.out.println(smallest);
}
public static boolean biggerThanK(int number, int k) {
if (number >= k) {
return true;
} else {
return false;
}
}
public static boolean prim(int number) {
for (int i = 2; i < number; i++) {
if (number % i == 0) {
return false;
}
} return true;
}
}
You should put this in a function.
If only one of the conditions needs to be false, I would use an architecture like this :
if(condition 1)
if(condition 2)
//update smallest
else
return -1
else
return -1
I have strings scanned from the user. Next step is to sort array by the length of text, I don't know what I'm doing wrong, sometimes it's working.
public static void quickSort(String[] subtitles, int start, int end) {
int i = start;
int j = end;
if (j - i >= 1) {
String pivot = subtitles[i];
while (j > 1) {
while (subtitles[i].compareTo(pivot) <= 0 && i < end && j > i)
i++;
while (subtitles[j].compareTo(pivot) >= 0 && j > start && j >= i)
j--;
if (j > i)
swap(subtitles, i, j);
}
swap(subtitles, start, j);
quickSort(subtitles, start, j - 1);
quickSort(subtitles, j + 1, end);
} else
return;
}
public static void swap(String[] a, int i, int j) {
String tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int amountStrings = 3;
String[] subtitles = new String[amountStrings];
System.out.println("insert ");
for (int i = 0; i < amountStrings; i++) {
subtitles[i] = scan.next();
}
System.out.println("--------");
quickSort(subtitles, 0, subtitles.length - 1);
for (int i = 0; i < subtitles.length; i++) {
System.out.print(subtitles[i] + " ");
}
Incorrect:
In:
asdzxc asd zxc
Out:
asd asdzxc zxc
Correct:
In:
sdf sdfsfwer s
Out:
s sdf sdfsfwer
Ok, I reviewed your code and made two new methods. One sorts the array alphabetically and one sorts by counting the number of letters in each word of the array. It is up to you what methods fits you well.
Tested and working.
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Subtitles {
public static void sortAlfabetical(String x[]) {
int j;
boolean found = true; // will determine when the sort is finished
String temp;
while (found) {
found = false;
for (j = 0; j < x.length - 1; j++) {
if (x[j].compareToIgnoreCase(x[j + 1]) > 0) { // ascending sort
temp = x[j];
x[j] = x[j + 1]; // swap
x[j + 1] = temp;
found = true;
}
}
}
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
}
public static void compare(String[] arrayOne) {
Arrays.sort(arrayOne, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
});
for (String s : arrayOne) {
System.out.print(s + " ");
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int amountStrings = 3;
String[] subtitles = new String[amountStrings];
System.out.println("insert ");
for (int i = 0; i < amountStrings; i++) {
subtitles[i] = scan.next();
}
System.out.println("--------");
System.out.print("Sorting alphabetical: ");
sortAlfabetical(subtitles);
System.out.println();
System.out.println("===========================");
System.out.print("Sorting by word length: ");
compare(subtitles);
}
}
I want to find the number of inversions possible in a 2D array. I have written this program and need ways to speed it up:
import java.io.*;
import java.util.*;
class Solution
{
static long merge(int[] array, int[] left, int[] right)
{
int i = 0, j = 0, count = 0;
while (i < left.length || j < right.length)
{
if (i == left.length)
{
array[i+j] = right[j];
j++;
}
else if (j == right.length)
{
array[i+j] = left[i];
i++;
}
else if (left[i] <= right[j])
{
array[i+j] = left[i];
i++;
}
else
{
array[i+j] = right[j];
count += left.length-i;
j++;
}
}
return count;
}
static long invCount(int[] array)
{
if (array.length < 2)
return 0;
int m = (array.length + 1) / 2;
int left[] = Arrays.copyOfRange(array, 0, m);
int right[] = Arrays.copyOfRange(array, m, array.length);
return invCount(left) + invCount(right) + merge(array, left, right);
}
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
long inversions=0;
int[][] arr2=new int[n][n];
if(n<0)
{
System.out.println("0");
return;
}
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
arr2[i][j]=sc.nextInt();
//arr2[i][j]=arr[i][j];
}
long inv=0;
int counter=0;
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
while(counter<n)
{
for(int z=counter;z<n;z++)
{
//System.out.println("comparing "+arr2[i][counter]+" with "+arr2[j][z]);
if(arr2[i][counter]>arr2[j][z])
inv++;
}
counter++;
//System.out.println("end while---------\n");
}
//System.out.println("Row change#########\n");
counter=0;
}
}
for (int i=0;i<n;i++)
inv=inv+invCount(arr2[i]);
System.out.println(inv);
}
}
Can this program be optimized? Or is this program wrong somewhere?
I got correct output for 2 test cases which are: 4 inversions for 2D array:
9 7
1 2
and 19 inversions for 2D array:
9 7 6
1 2 5
2 3 1
Thanks for help.:)
inversionCount=0;
for(R=0;R<sizeOf2DArray;R++) {
for(C=0;C<sizeOf2DArray;C++) {
firstElem=inputArray[R][C];
for(int j=R;j<sizeOf2DArray;j++) {
for(int i=C;i<sizeOf2DArray;i++) {
secondElem=inputArray[j][i];
if(firstElem>secondElem) {
inversionCount++;
}
}
}
}
}
System.out.println(inversionCount);
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;
}
}
I think I have most of the code figured out, there is just one part that is giving me grief. When I use printList(list) it prints out 1, 2, 3,... up to 9 when it is supposed to be printing the squares of these numbers. If I print out the createSquaresList(10) it is correctly printed. Any help is appreciated :-).
import java.util.*;
public class Lab8a
{
public static void main(String args[])
{
ArrayList<Double> list = createSquaresList(10);
printList(list);
removeElement(list, 4);
printList(list);
swapElements(list, 2, 6);
printList(list);
double max = getMaxValue(list);
double ave = getAverage(list);
System.out.println("Max Value = " + max);
System.out.println("Average = " + ave);
int idx1 = linearSearch(list, 4);
int idx2 = linearSearch(list, 75);
System.out.println("idx 1 = " + idx1);
System.out.println("idx 2 = " + idx2);
}
public static ArrayList<Double> createSquaresList(int n)
{
ArrayList<Double> squares= new ArrayList<>();
double s = 0.0;
for (double i = 0.0; i <= n-1; i++)
{
s = i*i;
squares.add(s);
}
return squares;
}
public static double getMaxValue(ArrayList<Double> list)
{
double largest = list.get(0);
for (int i = 1; i < list.size(); i++)
{
if (list.get(i) > largest)
{
largest = list.get(i);
}
}
return largest;
}
public static double getAverage(ArrayList<Double> list)
{
double avg = 0.0;
double sum = 0.0;
for (int i =0; i < list.size(); i++)
{
sum += list.get(i);
}
avg = sum / list.size();
return avg;
}
public static void removeElement(ArrayList<Double> list, double index)
{
double temp = 0.0;
int lastPos = list.size() - 1;
double last = list.get(lastPos);
index = temp;
temp = last;
last = index;
list.remove(lastPos);
}
public static void swapElements(ArrayList<Double> list, int a, int b)
{
int temp = 0;
a = temp;
temp = b;
b = a;
}
public static int linearSearch(ArrayList<Double> list, double val)
{
int pos = 0;
boolean found = false;
while (pos < list.size() && !found)
{
if (list.get(pos) == val)
{
found = true;
}
else
{
pos++;
}
}
if (found)
{
return pos;
}
else
{
return -1;
}
}
public static void printList(ArrayList<Double> list)
{
for(int i = 0; i < list.size(); i++)
{
System.out.print(i);
if(i < list.size()-1)
{
System.out.print(", ");
}
}
System.out.println("");
}
}
Change
System.out.print(i);
to
System.out.print(list.get(i));
it is because you are print the int not the contents of the list,
try changing the 3 line of the function printList to:
System.out.print(list.get(i));