Implementing BubbleSort at the end of QuickSort - java

I finally got my bubblesort and quicksort working but am curious as to how to change my code so that when I reach the last 10 elements being sorted in my quicksort I instead change to bubblesort for faster overhead times.
static int num_comps;
public static void main(String[] args)
{
Random rnd = new Random();
// max size of array and number of N sets
int array_size = 32768;
int num_datasets = 10;
// array set to max size
int[] vals = new int[array_size];
// temporary array with allocated array to max size
int[] tvals = new int[array_size];
// array to hold operation counts
int[] op_counts = new int[num_datasets];
int[] op_counts2 = new int[num_datasets];
// array to hold the size of each array
int[] arraySizes = new int[num_datasets];
int i;
int size;
for (i = 0, size = 64; i < num_datasets; i++, size *= 2)
arraySizes[i] = size;
for (int iter = 0; iter < num_datasets; iter++)
{
int curr_size = arraySizes[iter];
// fill array with random values form 0-4999
for (i = 0; i < curr_size; i++)
vals[i] = rnd.nextInt(4999);
//set the temporary array to the actual array
for (i = 0; i < curr_size; i++)
tvals[i] = vals[i];
// run the bubble sort algorithm
num_comps = 0;
bubbleSort(tvals, curr_size);
op_counts[iter] = num_comps;
//System.out.println("Num comps at " + iter + " is " + num_comps);
num_comps = 0;
quickSort(tvals, curr_size);
op_counts2[iter] = num_comps;
}
System.out.println("N Bubble Sort OP Count Quick Sort OP Count");
for (int k = 0; k < num_datasets; k++)
{
System.out.println(arraySizes[k] + "\t\t" + op_counts[k] + "\t\t\t" + op_counts2[k]);
}
}
static void bubbleSort(int vals[], int curr_size)
{
int temp;
for (int i = 0; i < curr_size - 1; i++)
{
for (int j = 0; j < curr_size - i - 1; j++)
{
// swap
num_comps = num_comps + 1;
if (vals[j+1] < vals[j])
{
temp = vals[j];
vals[j] = vals[j+1];
vals[j+1] = temp;
}
}
}
}
static void quickSort(int vals[], int curr_size)
{
quickSort_R(vals, 0, curr_size - 1);
}
static void quickSort_R(int vals[], int l, int r)
{
if (l < r)
{
if ((r-1) == 1) // two elements - trivial sort
{
num_comps = num_comps + 1;
if (vals[l] > vals[r])
swap(vals, l, r);
return;
}
// partition the elements on the pivot s
int s = partition(vals, l, r);
//recurse on the two partitioned values
quickSort_R(vals, l, s-1);
quickSort_R(vals, s+1, r);
}
}
static int partition(int vals[], int l, int r)
{
int mid = (l+r) / 2;
int p = medianOfThree(vals, l, r);
// swap with first element
swap(vals, l, p);
int pivot_val = vals[l];
int i = l;
int j = r+1;
do
{
num_comps = num_comps + 1;
do
{
i = i + 1;
num_comps = num_comps + 1;
} while (vals[i] < pivot_val);
do
{
j = j - 1;
num_comps = num_comps + 1;
} while (vals[j] > pivot_val);
swap(vals, i, j);
} while (i < j);
swap(vals, i, j); // undo last swap
swap(vals, i, j); // put pivot at j, its correct position
return j;
}
static int medianOfThree(int vals[], int first, int last)
{
int mid = (first+last) / 2;
if (vals[first] <= vals[mid] && vals[mid] <= vals[last])
{
num_comps = num_comps + 1;
return mid;
}
else if (vals[mid] <= vals[first] && vals[first] <= vals[last])
{
num_comps = num_comps + 1;
return first;
}
else
return last;
}
static void swap(int vals[], int i, int j)
{
int temp = vals[i];
vals[i] = vals[j];
vals[j] = temp;
}
}

EJP is right, but if you want to, just modify your code like so:
public static void quickSort_R(int vals[], int l, int r) {
if (l < r) {
if((r-l) < 10) {
bubbleSort(vals, r-l); //<--HERE
}
else {
if ((r-1) == 1) { // two elements - trivial sort
num_comps = num_comps + 1;
if (vals[l] > vals[r])
swap(vals, l, r);
return;
}
// partition the elements on the pivot s
int s = partition(vals, l, r);
//recurse on the two partitioned values
quickSort_R(vals, l, s-1);
quickSort_R(vals, s+1, r);
}
}
}

Related

Measuring and exporting merge sort algorithm execution time into CSV?

My task is to implement the merge-sort algorithm on an array G of large length L (with random values hitting a max value).
The pseudocode is as follows:
DataCollect ()
for n = 1,000 to L (step 1,000)
Copy in array A n first values from array G.
Take current time : Start (timing the sort of array A of length n)
Merge-Sort (A, 0, n-1)
Take current time: End. Or T(n) = End - Start
Store value n and values...(various time complexities) in file F. T(n) is execution time.
This is what I came up with...but I cannot seem to figure out my error. I feel like I sorted it correctly, but the data that results from this program just does not sit right with me. Is there an error in my logic here or am I just over thinking this?
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
System.out.println(collectData());
}
public static long collectData() throws IOException {
int L = 10000;
long start = 0;
long end = 0;
long Tn = 0;
int G[] = RData(L);
int A[];
File file= new File("collectData.csv");
FileWriter filewriter = new FileWriter(file);
filewriter.append("T(n)");
filewriter.append(',');
filewriter.append('n');
filewriter.append(',');
filewriter.append("T(n)/n");
filewriter.append(',');
filewriter.append("T(n)/nlog(n)");
filewriter.append(',');
filewriter.append("T(n)/nsqrt(n)");
filewriter.append("\n");
for (int n = 1000; n <= G.length; n += 1000) {
A = copyVal(G, n);
start = System.currentTimeMillis();
mergeSort(A, 0, A.length - 1);
end = System.currentTimeMillis();
Tn = end - start;
filewriter.write(String.valueOf(Tn));
filewriter.append(',');
filewriter.write(String.valueOf(n));
filewriter.append(',');
filewriter.write(String.valueOf(Tn/(n)));
filewriter.append(',');
filewriter.write(String.valueOf(Tn/(n * Math.log(n))));
filewriter.append(',');
filewriter.write(String.valueOf(Tn/(n * (Math.sqrt(n)))));
filewriter.append(',');
filewriter.write("\n");
}
filewriter.flush();
filewriter.close();
return Tn;
}
public static void mergeSort(int[] Array, int p, int r) {
if(p < r) {
int q = (p + r)/2;
mergeSort(Array, p, q);
mergeSort(Array, q + 1, r);
merge(Array, p, q, r);
}
}
private static void merge(int[] Array, int p, int q, int r) {
// finds the sizes of the two arrays to merge
int n1 = q - p + 1;
int n2 = r - q;
// temporary arrays created
int L[] = new int[n1 + 1];
int R[] = new int[n2 + 1];
// copying the data to the temp arrays
for(int i = 1; i < n1; i++) {
L[i] = Array[p + i - 1];
}
for(int j = 1; j < n2; j++) {
R[j] = Array[q + j];
}
// replace the infinity with 0x0fff ffff value
L[n1] = 268435455;
R[n2] = 268435455;
// initial values
int i = 0, j = 0;
for(int k = p; k <= r; k++) {
if(L[i] <= R[j]) {
Array[k] = L[i];
i = i + 1;
}
else {
Array[k] = R[j];
j = j + 1;
}
}
}
// copies A
public static int[] copyVal(int[] G, int n) {
int[] A = new int[n];
for(int i = 1; i < n; i++) {
A[i] = G[i];
}
return A;
}
public static int[] RData(int n) {
int[] Array = new int[n + 1];
for (int i = 1; i <= n; i++) {
Array[i] = (int) (Math.random() * Integer.MAX_VALUE);
}
return Array;
}
}

Finding the Nth smallest number in an unsorted array using Scanner

I've scoured the forums and can't find an example of how to find the Nth smallest number in an array in combination with scannner, so I'm sorry if this has been answered here before. Also, is there any way to display the number of comparisons that was made by the program to find an element within the array? I've attached an image of the assignment instructions if it will help. assignment instructions
public static void main(String[] args) {
System.out.println("IDS201 HW3:\n");
System.out.println("1. Generate " + RANDOM_NUMBER_COUNT + " random integer unsorted list.\n");
int[] randomNumbers = generateRandomNUmbers();
System.out.print("\n2. Search value? ");
Scanner stdin = new Scanner(System.in);
int x = stdin.nextInt();
int count = search(randomNumbers, x);
if (count == 0) {
System.out.println(x + " is not in the list");
}
System.out.println("\n3. Sort the list:");
sort(randomNumbers);
System.out.print("Now the Array after Sorting is :\n\n");
display(randomNumbers);
}
private static final int RANDOM_NUMBER_COUNT = 50;
private static void display(int[] randomNumbers) {
int count = 0;
for (int i = 0; i < RANDOM_NUMBER_COUNT; i++) {
System.out.print(randomNumbers[i] + ",");
count++;
if (count == 10) {
System.out.println();
count = 0;
}
}
}
private static int[] generateRandomNUmbers() {
int[] randomNumbers = new int[RANDOM_NUMBER_COUNT];
for (int index = 0; index < RANDOM_NUMBER_COUNT; index++) {
randomNumbers[index] = (int) (Math.random() * 100);
}
display(randomNumbers);
return randomNumbers;
}
private static int search(int[] randomNumbers, int x) {
int i;
int count = 0;
for (i = 0; i < randomNumbers.length; i++) {
if (randomNumbers[i] == x) {
System.out.println("\nFound " + x + " in array [" + i + "]");
count++;
}
}
return count;
}
private static int[] sort(int[] randomNumbers) {
int size = randomNumbers.length;
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
if (randomNumbers[i] > randomNumbers[j]) {
int temp = randomNumbers[i];
randomNumbers[i] = randomNumbers[j];
randomNumbers[j] = temp;
}
}
}
return randomNumbers;
}
}
You can find the order statistics algorithm to find the k-th smallest element in O(n) time here. For the Scanner part, you don't need anything other than reading k from the command line and passing it into the algorithm. Nothing really different from the original algorithm, both takes a parameter k and in this case, you read the parameter k from the command line.
Note: There are other approaches to the k-th smallest element problem, but they are slower. For example, you can sort your array and then find the k-th element from the last index. You can also find other approaches from previous entries on the given link.
here you go:
import java.util.Scanner;
public class Main
{
public static void main (String[]args)
{
System.out.println ("IDS201 HW3:\n");
System.out.println ("1. Generate " + RANDOM_NUMBER_COUNT +
" random integer unsorted list.\n");
int[] randomNumbers = generateRandomNUmbers ();
System.out.print ("\n2. Search value? ");
Scanner stdin = new Scanner (System.in);
int x = stdin.nextInt ();
int count = search (randomNumbers, x);
if (count == 0)
{
System.out.println (x + " is not in the list");
}
else
{
System.out.println ("compared " + count + " times to search");
}
System.out.print ("\n2. Nth Smallest value? ");
int nth_value = stdin.nextInt ();
System.out.print ("K'th smallest element is " +
nth_search (randomNumbers, 0, RANDOM_NUMBER_COUNT-1,nth_value));
System.out.println ("\n3. Sort the list:");
sort (randomNumbers);
System.out.print ("Now the Array after Sorting is :\n\n");
display (randomNumbers);
}
private static final int RANDOM_NUMBER_COUNT = 50;
private static int partition (int[]randomNumbers, int l, int r)
{
int x = randomNumbers[r], i = l;
for (int j = l; j <= r - 1; j++)
{
if (randomNumbers[j] <= x)
{
int temp = randomNumbers[i];
randomNumbers[i] = randomNumbers[j];
randomNumbers[j] = temp;
i++;
}
}
int temp = randomNumbers[i];
randomNumbers[i] = randomNumbers[r];
randomNumbers[r] = temp;
return i;
}
private static void display (int[]randomNumbers)
{
int count = 0;
for (int i = 0; i < RANDOM_NUMBER_COUNT; i++)
{
System.out.print (randomNumbers[i] + ",");
count++;
if (count == 10)
{
System.out.println ();
count = 0;
}
}
}
private static int[] generateRandomNUmbers ()
{
int[] randomNumbers = new int[RANDOM_NUMBER_COUNT];
for (int index = 0; index < RANDOM_NUMBER_COUNT; index++)
{
randomNumbers[index] = (int) (Math.random () * 100);
}
display (randomNumbers);
return randomNumbers;
}
private static int search (int[]randomNumbers, int x)
{
int i;
int count = 0;
for (i = 0; i < randomNumbers.length; i++)
{
if (randomNumbers[i] == x)
{
System.out.println ("\nFound " + x + " in array [" + i + "]");
count++;
}
}
return count;
}
private static int nth_search (int[]randomNumbers, int l, int r, int k)
{
if (k > 0 && k <= r - l +1)
{
int pos = partition (randomNumbers, l, r);
if (pos - l == k - 1)
return randomNumbers[pos];
if (pos - l > k - 1)
return nth_search (randomNumbers, l, pos - 1, k);
return nth_search (randomNumbers, pos + 1, r, k - pos + l - 1);
}
return -1;
}
private static int[] sort (int[]randomNumbers)
{
int size = randomNumbers.length;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (randomNumbers[i] > randomNumbers[j])
{
int temp = randomNumbers[i];
randomNumbers[i] = randomNumbers[j];
randomNumbers[j] = temp;
}
}
}
return randomNumbers;
}
}
nth smallest term function
private static int nth_search (int[]randomNumbers, int l, int r, int k)
{
if (k > 0 && k <= r - l +1)
{
int pos = partition (randomNumbers, l, r);
if (pos - l == k - 1)
return randomNumbers[pos];
if (pos - l > k - 1)
return nth_search (randomNumbers, l, pos - 1, k);
return nth_search (randomNumbers, pos + 1, r, k - pos + l - 1);
}
return -1;
}
and 2nd function
private static int partition (int[]randomNumbers, int l, int r)
{
int x = randomNumbers[r], i = l;
for (int j = l; j <= r - 1; j++)
{
if (randomNumbers[j] <= x)
{
int temp = randomNumbers[i];
randomNumbers[i] = randomNumbers[j];
randomNumbers[j] = temp;
i++;
}
}
int temp = randomNumbers[i];
randomNumbers[i] = randomNumbers[r];
randomNumbers[r] = temp;
return i;
}

Java Heap Sort and Counting Sort returns false

I have an assignment where I have to implement heap sort, quick sort, and counting sort into my program. Currently I have no errors but my output is returning as false for my heap and counting sort. What mistakes am I making? How can they be fixed? Please help any feedback will be appreciated.
package sorting;
import java.util.*;
public class Sort2
{
public static int left (int i)
{
return 2 * i + 1;
}
public static int right (int i)
{
return 2 * i + 2;
}
public static int parent (int i)
{
return ((i-1)/2);
}
public static void max_heapify (int[] array, int heap_size, int i)
{
int largest = i;
int l = left(i);
int r = right(i);
if (l < heap_size && array[l] > array[i])
{
largest = l;
}
else
{
largest = i;
}
if (r < heap_size && array[r] > array[largest])
{
largest = r;
}
if (largest != i)
{
int exchange = array[i];
array[i] = array[largest];
array[largest] = exchange;
max_heapify(array, array.length, largest);
}
}
public static int[] build_heap (int[] array)
{
int heap_size = array.length;
for (int i = array.length/2; i >= 1;i--)
{
max_heapify(array, heap_size, i);
}
return array;
}
public static int[] heap_sort (int[] array)
{
build_heap(array);
int heap_size = array.length;
for (int i = array.length;i >= 2;i--)
{
heap_size--;
int exchange = array[0];
array[0] = array[heap_size];
array[heap_size] = exchange;
max_heapify(array, array.length, 1);
}
return array;
}
public static void quick_sort (int[] array, int p, int r)
{
if (p < r)
{
int q = partition(array, p, r);
quick_sort(array, p,q-1);
quick_sort(array, q + 1,r);
}
}
public static int partition (int[] array, int p, int r)
{
int x = array[r];
int i = p - 1;
for (int j = p;j< r;j++)
{
if (array[j] <= x)
{
i++;
int exchange = array[i];
array[i] = array[j];
array[j] = exchange;
}
}
int exchange = array[i+1];
array[i+1] = array[r];
array[r] = exchange;
return i + 1;
}
public static int[] counting_sort (int[] A, int k)
{
int [] C = new int[k+1];
int [] B = new int [A.length];
for(int i = 0;i <= k; i++)
{
C[i] = 0;
}
for(int j = 0; j < A.length; j++)
{
C[A[j]] = C[A[j]] + 1;
}
for (int i = 1; i <= k; i++)
{
C[i] = C[i]+C[i-1];
}
for (int j = A.length - 1;j > 1; j--)
{
B[C[A[j]]- 1]=A[j];
C[A[j]]=C[A[j]] - 1;
}
return B;
}
public static int[] generate_random_array (int n, int k) {
List<Integer> list;
int[] array;
Random rnd;
rnd = new Random(System.currentTimeMillis());
list = new ArrayList<Integer> ();
for (int i = 1; i <= n; i++)
list.add(new Integer(rnd.nextInt(k+1)));
Collections.shuffle(list, rnd);
array = new int[n];
for (int i = 0; i < n; i++)
array[i] = list.get(i).intValue();
return array;
}
public static int[] generate_random_array (int n) {
List<Integer> list;
int[] array;
list = new ArrayList<Integer> ();
for (int i = 1; i <= n; i++)
list.add(new Integer(i));
Collections.shuffle(list, new Random(System.currentTimeMillis()));
array = new int[n];
for (int i = 0; i < n; i++)
array[i] = list.get(i).intValue();
return array;
}
/*
* Input: an integer array
* Output: true if the array is acsendingly sorted, otherwise return false
*/
public static boolean check_sorted (int[] array) {
for (int i = 1; i < array.length; i++) {
if (array[i-1] > array[i])
return false;
}
return true;
}
public static void print_array (int[] array) {
for (int i = 0; i < array.length; i++)
System.out.print(array[i] + ", ");
System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 10000;
System.out.println("Heap sort starts ------------------");
for (int n = 100000; n <= 1000000; n=n+100000) {
int[] array = Sort2.generate_random_array(n);
long t1 = System.currentTimeMillis();
array = Sort2.heap_sort(array);
long t2 = System.currentTimeMillis();
long t = t2 - t1;
boolean flag = Sort2.check_sorted(array);
System.out.println(n + "," + t + "," + flag);
}
System.out.println("Heap sort ends ------------------");
//Currently works
System.out.println("Quick sort starts ------------------");
for (int n = 100000; n <= 1000000; n=n+100000)
{
int[] array = Sort2.generate_random_array(n);
long t1 = System.currentTimeMillis();
Sort2.quick_sort(array, 0, n-1);
long t2 = System.currentTimeMillis();
long t = t2 - t1;
boolean flag = Sort2.check_sorted(array);
System.out.println(n + "," + t + "," + flag);
}
System.out.println("Quick sort ends ------------------");
int[] array2 = Sort2.generate_random_array(10, 10);
array2 = Sort2.counting_sort(array2,10);
boolean flag = Sort2.check_sorted(array2);
System.out.println(flag);
System.out.println("Counting sort starts ------------------");
for (int n = 100000; n <= 1000000; n=n+100000) {
int[] array = Sort2.generate_random_array(n, k);
long t1 = System.currentTimeMillis();
array = Sort2.counting_sort(array, n);
long t2 = System.currentTimeMillis();
long t = t2 - t1;
flag = Sort2.check_sorted(array);
System.out.println(n + "," + t + "," + flag);
}
System.out.println("Counting sort ends ------------------");
}
}
EDIT I modified your check method to print out the offending array elements:
public static boolean check_sorted( int[] array ) {
for( int i = 1; i < array.length; i++ ) {
if( array[i-1] > array[i] ) {
System.err.println( "Reversed array elements: " + (i-1) + "="
+ array[i-1] + ", " + i + "=" + array[i] );
return false;
}
return true;
}
It looks like the heap sort does not sort the first element of the array:
Heap sort starts ------------------
100000,5,false
Reversed array elements: 0=100000, 1=99999
And ten more like that.
For this homework assignment I would have suggested doing a google search on the specific sorts you were told to complete.
https://www.geeksforgeeks.org/counting-sort/
This will show you the code you just need to modify it for your variables. One thing I noticed right away is you are not building the count array correctly and that is affecting the build of the output array.
https://www.geeksforgeeks.org/heap-sort/
Here is the same instruction and explanation for your heap sort. I did not really look deeply into this as I do not have the time right now. Please use these resources to modify your code and hopefully complete the project.

How would I go about combining these two programs?

I'm pretty new to java and I'm having some trouble with this project for my class.
Basically I have to write "A Java program to find the value 45.3 from this list ={-3,10,5,24,45.3,10.5} using the binary search method."
And my code for that is here:
public class BinarySearch
{
public static final int NOT_FOUND = -1;
public static int binarySearch(Integer[] a, int x)
{
int low=0;
int high = a.length - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
if (a[mid].compareTo(x)<0)
low = mid + 1;
else if (a[mid].compareTo(x) > 0)
high = mid - 1;
else
return mid;
}
return NOT_FOUND;
}
public static void main(String[] args)
{
int x = (453/10);
int y = (105/10);
int SIZE = 6;
Integer [] a = {-3, 10, 5, 24, x, y};
System.out.println("45.3 found at " +binarySearch(a, x));
}
}
However I realized that it wasn't sorted so I used a simple BubbleSort that I already had and plugged the numbers in here:
class BubbleSort
{
public static void main(String args[])
{
int x = (453/10);
int y = (105/10);
int a[] = {-3, 10, 5, 24, x, y};
int b = a.length;
int c, d, e;
System.out.print("Original Order : ");
for (c = 0; c < b; c++)
{
System.out.print(" " + a[c]);
}
System.out.println("\n");
System.out.print("Ascending Order : ");
for (d=1; d < b; d++)
{
for (c=0; c < b-d; c++)
{
if (a[c] > a[c+1])
{
int f = a[c];
a[c] = a[c+1];
a[c+1] = f;
}
}
}
for(c = 0; c < b; c++)
{
System.out.print(" " + a[c]);
}
}
}
But at the point I'm at in this class I have no idea how to either make the class files work together in someway or put it all into a single .java or .class file.
Any tips?
Thanks!
public class Search {
public final static int NOT_FOUND = -1;
public static double[] bubbleSort(double[] a) {
int length = a.length;
System.out.print("Original Order : ");
for (int i = 0; i < length; i++) {
System.out.print(" " + a[i]);
}
System.out.println("\n");
System.out.print("Ascending Order : ");
for (int i = 1; i < length; i++) {
for (int j = 0; j < length - j; j++) {
if (a[j] > a[j + 1]) {
double f = a[j];
a[j] = a[j + 1];
a[j + 1] = f;
}
}
}
for (int i = 0; i < length; i++) {
System.out.print(" " + a[i]);
}
System.out.println();
return a;
}
public static int binarySearch(double[] a, double x) {
int low = 0;
int high = a.length - 1;
int mid;
while (low <= high) {
mid = (low + high) / 2;
if (a[mid] - x < 0)
low = mid + 1;
else if (a[mid] - x > 0)
high = mid - 1;
else {
return mid;
}
}
return NOT_FOUND;
}
public static void main(String[] args) {
double[] array = { -3, 10, 5.0, 24, 45.3, 10.5 };
double[] sortedArray = bubbleSort(array);
System.out.println(binarySearch(sortedArray, 45.3));
}
}
Start with just copy & pasting the program to merge. Fortunately there wern't any variable collisions.
public class BubbleSortAndBinarySearch
{
public static final int NOT_FOUND = -1;
public static int binarySearch(Integer[] a, int x)
{
int low=0;
int high = a.length - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
if (a[mid].compareTo(x)<0)
low = mid + 1;
else if (a[mid].compareTo(x) > 0)
high = mid - 1;
else
return mid;
}
return NOT_FOUND;
}
public static void main(String[] args)
{
int x = (453/10);
int y = (105/10);
int SIZE = 6;
Integer [] a = {-3, 10, 5, 24, x, y};
int b = a.length;
int c, d, e;
System.out.print("Original Order : ");
for (c = 0; c < b; c++)
{
System.out.print(" " + a[c]);
}
System.out.println("\n");
System.out.print("Ascending Order : ");
for (d=1; d < b; d++)
{
for (c=0; c < b-d; c++)
{
if (a[c] > a[c+1])
{
int f = a[c];
a[c] = a[c+1];
a[c+1] = f;
}
}
}
for(c = 0; c < b; c++)
{
System.out.print(" " + a[c]);
}
System.out.println(); // inserting this will make the result better to read
System.out.println("45.3 found at " +binarySearch(a, x));
}
}
Then, modify the program to handle non-integer values such as 45.3 and 10.5 correctly. Currently this code only works with integers and the value 45.3 is not used except for in the string.

Searching for a sum in an array

I have a method which counts how many sums of 3 elements,which are equal to 0, does the array contains. I need help finding the way to stop counting the same triplets in the loop. For instance, 1 + 3 - 4 = 0, but also 3 - 4 +1 = 0.Here is the method:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if(binarySearch(A,sum))
{
count++;
}
}
}
return count;
edit: I have to use the Binary Search (the array is sorted).
Here is the binarySearch code:
private static boolean binarySearch(int A[],int y)
{
y=-y;
int max = A.length-1;
int min = 0;
int mid;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
return true;
}
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
return false;
You can avoid counting different triplets by making one assumption that we need to look for the triplets (x,y,z) with x < y < z and A[x] + A[y] + A[z] == 0.
So what you need to do is to modify the binarySearch function to return the number of index that greater than y and has A[z] == -(A[x] + A[y])
private static int binarySearch(int A[],int y, int index)
{
y=-y;
int max = A.length-1;
int min = index + 1;
int mid;
int start = A.length;
int end = 0;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
start = Math.min(start, mid);
max = mid - 1;
} else
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
int max = A.length - 1;
int min = index + 1;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
end = Math.max(end, mid);
min= mid + 1;
} else if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
if(start <= end)
return end - start + 1;
return 0;
}
So the new function binarySearch will return the total number of index that greater than index and has value equals to y.
So the rest of the job is to count the answer
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
count += binarySearch(A,sum, j);
}
}
return count;
}
Notice how I used two binary search to find the starting and the ending index of all values greater than y!
private static int counter(int A[]) {
int e = A.length;
int count = 0;
for (int i = 0; i < e; i++) {
for (int j = 1; (j < e - 1) && (i != j); j++) {
for (int k = 2; (k < e - 2) && (j != k); k++) {
if (A[i] + A[j] + A[k] == 0) {
count++;
}
}
}
}
return count;
}
private static int counter(int ints[]) {
int count = 0;
for (int i = 0; i < ints.length; i++) {
for (int j = 0; j < ints.length; j++) {
if (i == j) {
// cannot sum with itself.
continue;
}
for (int k = 0; k < ints.length; k++) {
if (k == j) {
// cannot sum with itself.
continue;
}
if ((ints[i] + ints[j] + ints[k]) == 0) {
count++;
}
}
}
}
return count;
}
To solve problem with binary search
Your code was almost correct. all you needed to do was just to replace
if (sum == binarySearch(A,sum)) {
with this
if (binarySearch(A,sum)) {
I am assuming that your binarySearch(A, sum) method will return true if it will found sum in A array else false
private static int counter(int A[]) {
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++) {
for (int j=i+1; j<e; j++) {
sum=A[i]+A[j];
if (binarySearch(A,sum)) {
count++;
}
}
}
return count;
}
Here is my solution assuming the array is sorted and there are no repeated elements, I used the binary search function you provided. Could the input array contain repeated elements? Could you provide some test cases?
In order to not counting the same triplets in the loop, we should have a way of inspecting repeated elements, the main idea that I used here is to have a list of int[] arrays saving the sorted integers of {A[i],A[j],-sum}.Then in each iteration I compare new A[i] and A[j] to the records in the list, thus eliminating repeated ones.
private static int counter(int A[]){
int sum;
int e = A.length;
int count = 0;
List<int[]> elements = new ArrayList<>();
boolean mark = false;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if (-sum == binarySearch(A,sum)){
int[] sort = {A[i],A[j],-sum};
if(-sum == A[i] || -sum == A[j]){
continue;
}else{
Arrays.sort(sort);
//System.out.println("sort" + sort[0] + " " + sort[1]+ " " + sort[2]);
for (int[] element : elements) {
if((element[0] == sort[0] && element[1] == sort[1]) && element[2] == sort[2])
mark = true;
}
if(mark){
mark = false;
continue;
}else{
count++;
elements.add(sort);
//System.out.println("Else sort" + sort[0] + " " + sort[1]);
}
}
}
}
}
return count;
}
you can use a assisted Array,stored the flag that indicate if the element is used;
Here is the code:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
// assisted flag array
List<Boolean> flagList = new ArrayList<Boolean>(e);
for (int k = 0; k < e; k++) {
flagList.add(k, false);// initialization
}
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
// if element used, no count
if(binarySearch(A,sum)&& !flagList.get(i)&& !flagList.get(j))
{
count++;
flagList.set(i, true);
flagList.set(j, true);
}
}
}
return count;

Categories

Resources