randomized select not give steady solution - java

EDIT
try run in the main:
int[] arr = {646 ,94 ,366 ,754 ,948 ,678 ,121 ,320 ,528 ,36};
for(int i=0;i<10;i++){
System.out.println(randomizedSelect(arr,0,arr.length-1,5));
printArr(arr);
}
and see that i got diffrent outpot in each loop..
Got a little problem that I would like some help with, if anyone knows how.
I need to find the kth smallest value in an array by randomized partition.
I've got two problems:
I get array out of bounds with -1 and can't find a way to fix it.
Most of the time it works but sometimes it gives me wrong k place.
For example for array with length of 10, it tells me that 20 is in the 5th place but actually it should be in the 2nd place and it prints the array where not all the values on the left are smaller than 20 and not smaller than the 5th place.
Here is an example array:
{646 ,94 ,366 ,754 ,948 ,678 ,121 ,320 ,528 ,36}
The array input is done by a random number generator.
This is my code:
import java.util.Random;
import java.util.Scanner;
public class Main {
static Scanner scan = new Scanner(System.in);
static Random rand = new Random();
public static void main(String[] args) {
int nSize = askSizeN();
int kSize = askSizeK(nSize);
int[] arr = new int[nSize];
chose(arr);
int[] arrCopy = new int[nSize];
for (int i = 0; i < arrCopy.length; i++) {
arrCopy[i] = arr[i];
}
printArr(arrCopy);
System.out.println(randomizedSelect(arrCopy, 0, arr.length - 1, kSize));
printArr(arrCopy);
}
private static int partition(int[] arr, int p, int r) {
int x = arr[r];
int i = p - 1;
for (int j = p; j < r; j++) {
if (arr[j] <= x) {
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[r];
arr[r] = temp;
return i + 1;
}
private static int randomizedPartition(int[] arr, int p, int r) {
int i = rand.nextInt(r - p);
int temp = arr[r];
arr[r] = arr[i];
arr[i] = temp;
return partition(arr, p, r);
}
private static int randomizedSelect(int[] arr, int p, int r, int i) {
if (p == r) {
return arr[p];
}
int q = randomizedPartition(arr, p, r);
int k = q - p + 1;
if (i == k) {
return arr[q];
}
else if (i < k) {
return randomizedSelect(arr, p, q - 1, i);
}
else {
return randomizedSelect(arr, q + 1, r, i - k);
}
}
private static int askSizeN() {
System.out.println("Please chose the size of the heap: \n" + "(the size of n)");
return scan.nextInt();
}
private static int askSizeK(int nSize) {
System.out.println(
"Please chose how much small values you want to see: \n" + "(the size of k)");
int kSize = scan.nextInt();
if (kSize > nSize) {
System.out.println("cant print more number then the size of the Heap..");
System.out.println("Please enter a number less then " + (nSize + 1));
askSizeK(nSize);
}
return kSize;
}
private static int[] chose(int[] a) {
System.out.println("Chose the option you want: \n" + "\t1. enter your own values."
+ "\n\t2. let me generate random values");
int chose = scan.nextInt();
if (chose == 1) {
for (int i = 0; i < a.length; i++) {
System.out.println("Enter value number " + (i + 1));
a[i] = scan.nextInt();
}
}
else if (chose == 2) {
System.out.println("Generate random numbers.");
for (int i = 0; i < a.length; i++) {
a[i] = rand.nextInt(1000);
}
}
else {
chose(a);
}
return a;
}
private static void printArr(int[] a){
for(int i=0;i<a.length;i++){
System.out.print(a[i] + " ");
}
System.out.println();
}
}

I've solved the problem.
Method randmizedPartition() was generating wrong random pivot for partition.
I solved it by changing the random line to:
int i = rand.nextInt((r - p) + 1) + p;

Related

Java finding the smallest integer in a speciofic position in a sets of integer

Algorithm:
Procedure SELECT( k,S)
{ if ISI =1 then return the single element in S
else { choose an element a randomly from S;
let S1,S2,and S3 be he sequences of elements in S
less than, equal to, and greater than m, respectively;
if IS1I >=k then return SELECT(k,S1)
else
if (IS1I + IS2I >=k then return m
else return SELECT(k-IS1I-IS2I , S3);
}
}
The question is to implement the first algorithm for finding the kth smallest integer in a set of integers and test your program for different sets of integers generated by a random number generator.
Below is my solution.
import java.util.Random;
import java.util.Scanner;
public class main {
private static Random rand = new Random();
private static Scanner keyboard = new Scanner(System.in);
public static int firstAlgorithm(int k, int[] S) {
int m = S[rand.nextInt(S.length)];
int[] S1 = new int[S.length];
int[] S2 = new int[S.length];
int[] S3 = new int[S.length];
int p = 0;
int q = 0;
int r = 0;
if (S.length == 1)
return S[0];
for (int i = 0; i < S.length; i++) {
if (S[i] < m) {
S1[p] = S[i];
p++;
} else if (S[i] == m) {
S2[q] = S[i];
q++;
} else {
S3[r] = S[i];
r++;
}
}
S1 = trimToSize(S1, p);
S2 = trimToSize(S2, q);
S3 = trimToSize(S3, r);
if (S1.length >= k)
return firstAlgorithm(k, S1);
else if (S1.length + S2.length >= k)
return m;
else
return firstAlgorithm(k - S1.length - S2.length, S3);
}
private static int[] trimToSize(int[] arr, int size) {
int[] temp = new int[size];
for (int i = 0; i < size; i++) {
temp[i] = arr[i];
}
return temp;
}
public static void printArray(int[] S) {
for (int i = 0; i < S.length; i++) {
System.out.print(S[i] + "\t");
if (i % 10 == 9)
System.out.println();
}
}
// start main method
public static void main(String[] args) {
System.out.print("Enter the size of an array: ");
int size = keyboard.nextInt();
while (size < 1) {
System.out.println("Size of the array should be greater than 0.");
System.out.print("Enter the size of an array: ");
size = keyboard.nextInt();
}
System.out.print("Enter the value of k: ");
int k = keyboard.nextInt();
while (k < 1 || k > size) {
System.out.println("Value of k should be in the range 1-" + size + ".");
System.out.print("Enter the value of k: ");
k = keyboard.nextInt();
}
int[] S = new int[size];
for (int i = 0; i < size; i++) {
S[i] = 100 + rand.nextInt(900);
}
System.out.println("\nRandom values generated in the array:");
printArray(S);
System.out.println();
System.out.println(k + "th smallest value in the array using Algorithm #1: " + firstAlgorithm(k, S));
}
}
But I need to implement the above algorithm without using a temporary array for partitioning. How can I do it?
The algorithm is Dijkstra's 3-way partition.
You will have to modify the original S.
Untested (pseudo) code ahead
public static int partition(int left, int right, int[] S) {
int m = rand.nextInt(right-left); // protect against malicious data
swap(S[left+m], S[right]);
int equal = left;
while (left < right) {
if (a[left] < a[n])
swap(S, left++, equal++)
else if (a[left] == a[n])
swap(S, left, --right);
else
left++;
}
return left, equal;
}
public static int firstAlgorithm(int k, int left, int right, int[] S) {
if (left == right)
return S[left];
int p, e = partition(left, right, S); // returns 2 values. S1=[0,p), S2=[p,e), S3=[e, n)
if (p >= k)
return firstAlgorithm(k, left, p, S);
else if (e >= k) // p < k
return S[p]; // p is the first equal, e is first larger than equal
else // e < k
return firstAlgorithm(k, e, right, S);
}
// test
S = {1, 4, 2, 6, 2};
k = 2;
int result = firstAlgorithm(2, 0, S.length-1, S);
assert(result == 2);
Warning syntax and off-by-one errors guarantied.
See here multiple ways to return 2 values in java.

Method to add the even/odd numbers

I have an array with several numbers:
int[] tab = {1,2,3,4};
I have to create two methods the first is the sum() method and the second is numberOdd().
It's Ok for this step !
int length = tab.length;
length = numberOdd(tab,length);
int sum_odd = sum(tab, length);
System.out.println(" 1) - Calculate the sum of the odds numbers : => " + sum_odd);
public static int sum(int[] tab, int length){
int total = 0;
for(int i=0;i<length;i++){
total += tab[i];
}
return total;
}
public static int numberOdd(int[] tab, int length){
int n = 0;
for(int i=0;i<length;i++){
if(tab[i] % 2 != 0){
tab[n++] = tab[i];
}
}
return n;
}
Now, I have to add the even numbers with the numberEven() method and I get the value "0".
I don't understand why I retrieve the value => 0 ???????
Here is my code:
int[] tab = {1,2,3,4};
int length = tab.length;
length = numberOdd(tab,length);
int sum_odd = sum(tab, length);
length = numberEven(tab,length);
int sum_even = sum(tab, length);
System.out.println(" 1) - Calculate the sum of the odds numbers : => " + sum_odd);
System.out.println(" 2) - Calculate the sum of the evens numbers : => " + sum_even);
}
public static int numberEven(int[] tab, int length){
int n = 0;
for(int i=0;i<length;i++){
if(tab[i] % 2 == 0){
tab[n++] = tab[i];
}
}
return n;
}
For information: I share the code here => https://repl.it/repls/CriminalAdolescentKilobyte
Thank you for your help.
You need to add tab[i] to n
Having length as a parameter to numberEven does not cause any harm but you don't need it.
Given below is the working example:
public class Main {
public static void main(String[] args) {
int[] tab = { 1, 2, 3, 4 };
System.out.println(numberEven(tab));
}
public static int numberEven(int[] tab) {
int n = 0;
for (int i = 0; i < tab.length; i++) {
if (tab[i] % 2 == 0) {
n += tab[i];
}
}
return n;
}
}
Output:
6
you have changed the array in your numberOdd() method.
try replacing tab[n++] = tab[i]; with n++;
public static int sumEven(int[] tab){
int sumEven = 0;
for(int i=0;i<tab.length;i++){
if(tab[i] % 2 == 0){
sumEven = sumEven + tab[i];
}
}
return sumEven;
}
This should work.

Trouble outputting names in a backpack problem

I was trying to solve a problem based on value and weight. In the task i had to pick out the elements by their value and weight, and find the highest efficiency solution. I receive an answer, however i am having trouble outputting the elements that were used in order to get an answer.
I've tried creating a string in which i place the values, however it gives out an outofbounds error.
public static void main(String[] args) {
String z[] = new String[]{"a","b","c","d","e","f","g","h","l","m"};
int w[] = new int[]{10,2,4,6,8,1,7,11,4,5};
int c[] = new int[]{20,3,5,7,4,1,8,15,8,6};
int maxW = 50;
int n = c.length;
System.out.println("");
int a = Find(w,c,maxW,n,z);
System.out.println("max value is " + a);
}
static int max(int a, int b)
{
if(a>b)
{
return a;
}
return b;
}
public static int Find(int w[],int c[], int maxW,int n, String[]z)
{
int K[][] = new int[n + 1][maxW + 1];
String s = "";
// Build table K[][] in bottom up manner
for (int i = 0; i<= n; i++)
{
for(int j = 0; j<= maxW; j++)
{
if (i == 0 || j == 0)
{
K[i][j] = 0;
}
else if (w[i - 1]<= j)
{
K[i][j] = max(c[i - 1] + K[i - 1][j - w[i - 1]], K[i - 1][j]);
}
else
{
K[i][j] = K[i - 1][j];
}
}
}
return K[n][maxW];
}
}
i want to output the same index element in string z, as the index element that is used to find the efficiancy.
The ideal result would be something like this in a string:
a a a b c d e m
(Just an example)
Thank you in advance.

Coding Heapsort Algorithm but am getting a Stack Overflow error and cannot figure out why

Below is my code, I keep getting a Stack Overflow error from the last statement in my code which is the recursive call for heapify (the max heapify) method. Please help.
Class 1 code
package hw3javasorttest;
import java.util.*;
public class HW3JavaSortTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Unsorted array");
System.out.print("[");
int[] arr = new int[30];
for(int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random() * 100);
System.out.print(arr[i] + " ");
}
System.out.println("]");
Scanner in = new Scanner(System.in);
System.out.println("Please enter one of the corresponding numbers to choose the sorting method: ");
System.out.print("1.Heap Sort\n2.Quick Sort");
int Sorting = in.nextInt();
int x;
int q;
x = arr[0];
q = arr[29];
switch (Sorting) {
case 1: System.out.println("Heap Sort:");
HW3JavaSort.HeapSort(arr);
System.out.println(Arrays.toString(arr));
break;
case 2: System.out.println("Quick Sort:");
System.out.println();
// HW3JavaSort.quickSort(arr, x, q);
// System.out.println(Arrays.toString(a));
break;
default: System.out.println("invalid entry");
break;
}
}
}
Class 2 code
package hw3javasorttest;
public class HW3JavaSort {
public static void printArr(int[] arr) { //Method that displays arr
System.out.print("[");
for(int i= 0; i<arr.length; i++){
if(i==arr.length-1) {
System.out.printf("%d]\n", arr[i]);
}
else {
System.out.printf("%d,", arr[i]);
}
}
}
public static void HeapSort(int[] arr) {
int Length = arr.length;
int placeholder;
BuildMaxHeap(arr, Length);
for(int i = arr.length-1; i>0; i--) {
placeholder = arr[0];
arr[0] = arr[i];
arr[i] = placeholder;
heapify(arr, 1, i);
}
}
public static void BuildMaxHeap(int[] arr, int n){ //Organizes max heap
if(arr == null) {
throw new NullPointerException("null");
}
if(arr.length <=0 || n <= 0) {
throw new IllegalArgumentException("illegal");
}
if(n > arr.length) {
n = arr.length;
}
for(int i = n/2; i>= 0; i--) {
heapify(arr, i, n);
}
}
public static void heapify(int [] arr, int i, int n) { //Makes max heap
int largest;
int lc = 2*i;
int rc = 2*i + 1;
int temp = 0;
if(lc<=n && arr[lc-1] > arr[i-1]) {
largest = lc;
} else {
largest = i;
}
if(rc<=n && arr[rc-1] > arr[largest-1]) {
largest = rc;
}
if(largest!=i) {
temp = arr[i-1];
arr[i-1] = arr[largest - 1];
arr[largest - 1] = temp;
heapify(arr, largest, n); //HERE IS WHERE THE COMPILER SAYS I AM //GETTING THE ERROR, SAYS STACK OVERFLOW THEN THE HEAPIFY METHOD THEN THIS LINE //# AND DISPLAYS THE ERROR HUNDREDS OF TIMES
}
}
}
Incorrect formatting caused the algorithm to work differently than expected... fixed by formatting like Java (not Python).
Please take a look at this: https://blog.takipi.com/tabs-vs-spaces-how-they-write-java-in-google-twitter-mozilla-and-pied-piper/

Quicksort. Exception in thread "main" java.lang.StackOverflowError

Good day! I have here a Java program that does the quicksort. It reads a file then sorts the first 10,000 words in it. I followed the pseudocode of Thomas Cormen in his Introduction to Algorithms, Second Ed.
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static int partition(String[] A, int p, int r) {
String x = A[r];
int i = p-1;
for (int j=p; j < r-1; j++) {
int comparison = A[j].compareTo(x);
if (comparison<=0) {
i=i+1;
A[i] = A[j];
}
}
A[i+1] = A[r];
return i+1;
}
public static void quickSort(String[] a, int p, int r) {
if (p < r) {
int q = partition(a, p, r);
quickSort(a, p, q-1);
quickSort(a, q+1, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 10000;
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();
quickSort(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);
}
}
}
However, when I run the code, the console says
Exception in thread "main" java.lang.StackOverflowError
at SortingAnalysis.partition and quickSort
I thought that the error was just because of the large size (ie, 10000) so I decreased it to 100 instead. However, it still doesn't sort the first 100 words from a file, rather, it displays the 100th word 100 times.
Please help me fix the code. I'm new in Java and I need help from you guys. Thank you very much!
EDIT: I now edited my code. It doesn't have an error now even when the NO_OF_WORDS reaches 10000. The problem is it halts the wrong sequence.
You have two problems:
the loop in partition() should run to j <= r - 1, you are jumping out early.
You are not swapping elements. Try the following code:
public static int partition(String[] A, int p, int r) {
String x = A[r];
int i = p - 1;
for (int j = p; j <= r - 1; j++) {
int comparison = A[j].compareTo(x);
if (comparison <= 0) {
i = i + 1;
swap(A, i, j);
}
}
swap(A, i + 1, r);
return i + 1;
}
public static void swap(String[] a, int i, int j) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
Looking at the Quicksort algo of wikipedia, the partition algo is the following :
// left is the index of the leftmost element of the array
// right is the index of the rightmost element of the array (inclusive)
// number of elements in subarray = right-left+1
function partition(array, 'left', 'right', 'pivotIndex')
'pivotValue' := array['pivotIndex']
swap array['pivotIndex'] and array['right'] // Move pivot to end
'storeIndex' := 'left'
for 'i' from 'left' to 'right' - 1 // left ≤ i < right
if array['i'] < 'pivotValue'
swap array['i'] and array['storeIndex']
'storeIndex' := 'storeIndex' + 1
swap array['storeIndex'] and array['right'] // Move pivot to its final place
return 'storeIndex'
In your method you don't use the pivotIndex value, you base your pivotValue on the right index. You need to add this parameter to your method.
Following the wiki algo it should be like this :
public static int partition(String[] A, int p, int r, int pivotIdx) {
String x = A[pivotIdx];
String tmp = A[pivotIdx];
A[pivotIdx] = A[r];
A[r]=tmp;
int i = p;
for (int j=p; j < r; j++) {
int comparison = A[j].compareTo(x);
if (comparison<=0) {
tmp=A[i];
A[i] = A[j];
A[j]=tmp;
i++;
}
}
tmp=A[i];
A[i] = A[r];
A[r]=tmp;
return i;
}

Categories