StackOverflowError eratosthenes sieve implementation - java

I have tried to implement Eratosthenes sieve in Java, but I have a StackOverflowError like this:
Exception in thread "main" java.lang.StackOverflowError
at com.company.era2.sieve(era2.java:24)
at com.company.era2.sieve(era2.java:24)
at com.company.era2.sieve(era2.java:24)
Seems like its infinite recursion, but algo works fine and fast with n <= 90000
What could I do wrong?
Code:
public class era2 {
public static void print(Object x) {
System.out.println(x);
}
public static List<Integer> sieve(List<Integer> array, int index, int last_crossed){
if (index >= array.size() - 1){
print("Last crossed number : " + last_crossed);
return array;
} else {
for (int i = index + 1; i <= array.size() - 1; i++){
int num = array.get(i);
if (num % array.get(index) == 0) {
array.remove(i);
i--;
last_crossed = num;
}
}
return (sieve(array,index + 1, last_crossed));
}
}
public static void main(String[] args) {
int n = 1000000;
List<Integer> arr = new ArrayList<>();
for (int i = 2; i <= n; i++){
arr.add(i);
}
arr = sieve(arr, 0, 0);
for (int x : arr){
print(x);
}
}
}

If you don't necessarily need to use recursion here is a solution inspired by this wikipedia article
public static List<Integer> sieve(int limit) {
boolean[] array = new boolean[limit - 2];
Arrays.fill(array, true);
int end = (int)Math.sqrt(limit);
for (int i = 2; i <= end; i++) {
if (array[i - 2]) {
int j = i * i;
int k = 0;
while (j < limit) {
array[j - 2] = false;
j = i * i + i * ++k;
}
}
}
List<Integer> result = new ArrayList<>();
for (int l = 2; l < limit; l++) {
if (array[l - 2]) {
result.add(l);
}
}
return result;
}

Related

java.lang.StackOverflowError on factorial function being called by another recursive function

I have a factorial function on my program that works fine until i try to execute the function deleteRepeated(), the console is telling me that the error is in the return of the factorial function, maybe it's being called by a single function too many times in a short period of time? I've been stuck for hours.
import java.util.Scanner;
public class ex9 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
int[] newArr = new int[n - repeated(arr)];
int[] finalArr = deleteRepeated(arr, newArr);
for (int a : finalArr) {
System.out.println(a);
}
}
public static long factorial(int n) {
if (n == 0)
return 1;
return (n * factorial(n - 1));
}
public static int repeated(int arr[]) {
int n = arr.length;
int mix = (int) (factorial(n) / (2 * factorial(n - 2)));
int i = 0;
int k = 0;
int rep = 0;
int a = -100;
while (i < mix) {
for (int j = k + 1; j < n; j++) {
if (arr[k] == arr[j] && a != j) {
a = j;
rep += 1;
}
i++;
}
k++;
}
return rep;
}
public static int[] deleteRepeated(int arr[], int newArr[]) {
int n = arr.length;
int rep = repeated(arr);
int i = 0;
int k = 0;
int a = -100;
while (i < newArr.length) {
for (int j = k + 1; j < n; j++) {
if (arr[k] == arr[j] && a != arr[k]) {
a = arr[j];
newArr[k] = arr[k];
}
i++;
}
k++;
}
rep = repeated(newArr);
if (rep > 0) {
int[] newArr2 = new int[newArr.length - rep];
deleteRepeated(newArr, newArr2);
}
return newArr;
}
}
Only thing i could do to avoid the error was stopping the function from executing :/, maybe it has to do with how i'm re-calling it at the end of each execution...? is what i did allowed?
So, deleteRepeated is all messed up. The issue is deleteRepeated does not actually remove duplicate elements, so the check for the base case of recursion always fails. I'm not sure why you're using recursion here anyway; if the while loop worked properly, it could remove all duplicates without need for recursion.
It appears that you copy-pasted the implementation of repeated into deleteRepeated, and you replaced the logic for handling repeated elements with logic that handles non-repeated elements.
Here is how I would implement the method:
public static int deleteRepeated(int arr[], int newArr[]) {
int n = 0;
for(int i = 0; i < arr.length; i++) {
boolean unique = true;
for(int j = 0; j < n; j++)
unique = unique && newArr[j] != arr[i];
if(unique)
newArr[n++] = arr[i];
if(n >= newArr.length) break;
}
return n;
}

Counting number of duplicates in a given array

Input: 1,4,2,6,7,5,1,2
Output:2
Counting the number of duplicated numbers in a given array for java. I first sorted the array and then counted duplicates. It's showing me error that variable c is not used and that this method should return value of int.
public class Duplicates
public static void main(String[] args) {
int[]list;
int[]c;
int[] c = new int[list.length];
int temp;
for (int i = 0; i < list.length - 1; i++) {
for (int j = i + 1; j < list; j++) {
if (list[I] > list[j]) {
temp = list[i];
list[i] = list[j];
list[j] = temp;
c = list;
}
}
}
int n = 0;
int counter = 0;
int a = -1;
for (int i = 0; i < c.length; ++i) {
if (c[i] == a) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(c[i]);
} else {
System.out.print("," + c[i]);
}
}
} else {
a = c[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array:" + counter);
}
}
It's showing me error that variable c is not used
This should be a warning. So the code should still run correctly even with this is showing.
this method should return value of int
This is a compilation error and since you are not returning any int array at the end of the method, your method's return type should be void. You should change your method signature as below,
public static void c(int[] list)
Otherwise you will need to return an int array at the end of your method.
After fixing your code,
public class Duplicates {
public static void main(String[] args) {
int[] list = new int[]{1, 4, 2, 6, 7, 5, 1, 2};
int temp;
for (int i = 0; i < list.length; ++i) {
for (int j = 1; j < (list.length - i); ++j) {
if (list[j - 1] > list[j]) {
temp = list[j - 1];
list[j - 1] = list[j];
list[j] = temp;
}
}
}
int n = 0, counter = 0;
int previous = -1;
for (int i = 0; i < list.length; ++i) {
if (list[i] == previous) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(list[i]);
} else {
System.out.print(", " + list[i]);
}
}
} else {
previous = list[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array: " + counter);
}
}

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.

Java heapsort program error during runtime

My code is working during compilation but the runtime error points to an if condition in my MaxHeapify function. I marked it out. Any help would be simply lovely, and would make me stop banging my head against the wall.
public class HeapSort {
public static void main(String[] args) {
int A[] = {-100, 1, 2, 5, 7, 2, 9};
Heapsort(A);
//System.out.println(A.length);
for (int x = 1; x < A.length; x++) {
System.out.println(A[x] + " ");
}
}
public static void Build_MAX_heap(int A[]) {
int n = A.length;
for (int i = n / 2; i >= 1; i--) {
MAX_heapify(A, i);
}
}
public static void MAX_heapify(int A[], int i) {
int heapsize = A.length;
int l = 2 * i;
int r = 2 * i + 1;
//find the largest of A[i].A[l],A[r]
int largest = i;
if (A[l] > A[largest]) {
largest = l;
if (A[l] > A[largest] && l <= heapsize) {
largest = l;
}
if (A[r] > A[largest] && r <= heapsize) { //runtime error here
largest = r;
}
if (largest != i) {
int temp = A[i];
A[i] = A[largest];
A[largest] = temp;
MAX_heapify(A, largest);
}
}
}
public static void Heapsort(int A[]) {
Build_MAX_heap(A);
int heapsize = A.length;
for (int last = heapsize; last >= 2; last--) {
int temp = A[1];
A[1] = A[last];
A[last] = temp;
heapsize--;
MAX_heapify(A,1);
}
}
}
You're doing you bounds checking for r (and l, too, in the previous statement) after checking the element at index r. If r is out of bounds, the first half of the expression will throw an exception, and never make it to the bounds check.
Your if statements should be structured
if (r < heapsize && A[r] > A[largest]) ...
so that you know you're in bounds before you start trying to access your array. In addition, since arrays are zero-indexed, the index of heapsize isn't valid, so r needs to be less than, not less than or equal to.
Your problem is that your are checking A[r] before checking if r is out of range
so i would try to modify the code this way
public class HeapSort {
public static void main(String[] args) {
int A[] = {-100, 1, 2, 5, 7, 2, 9};
Heapsort(A);
//System.out.println(A.length);
for (int x = 1; x < A.length; x++) {
System.out.println(A[x] + " ");
}
}
public static void Build_MAX_heap(int A[]) {
int n = A.length;
for (int i = n / 2; i >= 1; i--) {
MAX_heapify(A, i);
}
}
public static void MAX_heapify(int A[], int i) {
int heapsize = A.length;
int l = 2 * i;
int r = 2 * i + 1;
//find the largest of A[i].A[l],A[r]
int largest = i;
if (A[l] > A[largest]) {
largest = l;
if (A[l] > A[largest] && l <= heapsize) {
largest = l;
}
if (r<=heapsize && A[r] > A[largest]) { //modification here
largest = r;
}
if (largest != i) {
int temp = A[i];
A[i] = A[largest];
A[largest] = temp;
MAX_heapify(A, largest);
}
}
}
public static void Heapsort(int A[]) {
Build_MAX_heap(A);
int heapsize = A.length;
for (int last = heapsize; last >= 2; last--) {
int temp = A[1];
A[1] = A[last];
A[last] = temp;
heapsize--;
MAX_heapify(A,1);
}
}
}
Variable r is set to:
int r = 2 * i + 1;
In first case of loop:
for (int i = n / 2; i >= 1; i--) {
MAX_heapify(A, i);
}
i is n/2
so to function is passed:
MAX_heapify(A,n/2);
and r is 2 * (n/2) + 1 which is n+1
when you want to do this line
if (A[r] > A[largest] && r <= heapsize) {
then A[r] is A[n+1]=A[A.length+1] - this causes IndexOutOfBoundsException

Java permutations

I am trying to run my code so it prints cyclic permutations, though I can only get it to do the first one at the moment. It runs correctly up to the point which I have marked but I can't see what is going wrong. I think it has no break in the while loop, but I'm not sure. Really could do with some help here.
package permutation;
public class Permutation {
static int DEFAULT = 100;
public static void main(String[] args) {
int n = DEFAULT;
if (args.length > 0)
n = Integer.parseInt(args[0]);
int[] OA = new int[n];
for (int i = 0; i < n; i++)
OA[i] = i + 1;
System.out.println("The original array is:");
for (int i = 0; i < OA.length; i++)
System.out.print(OA[i] + " ");
System.out.println();
System.out.println("A permutation of the original array is:");
OA = generateRandomPermutation(n);
printArray(OA);
printPemutation(OA);
}
static int[] generateRandomPermutation(int n)// (a)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
int swap = A[r];
A[r] = A[i];
A[i] = swap;
}
return A;
}
static void printArray(int A[]) {
for (int i = 0; i < A.length; i++)
System.out.print(A[i] + " ");
System.out.println();
}
static void printPemutation(int p[])// (b)
{
System.out
.println("The permutation is represented by the cyclic notation:");
int[] B = new int[p.length];
int m = 0;
while (m < p.length)// this is the point at which my code screws up
{
if (!check(B, m)) {
B = parenthesis(p, m);
printParenthesis(B);
m++;
} else
m++;
}// if not there are then repeat
}
static int[] parenthesis(int p[], int i) {
int[] B = new int[p.length];
for (int a = p[i], j = 0; a != B[0]; a = p[a - 1], j++) {
B[j] = a;
}
return B;
}
static void printParenthesis(int B[]) {
System.out.print("( ");
for (int i = 0; i < B.length && B[i] != 0; i++)
System.out.print(B[i] + " ");
System.out.print(")");
}
static boolean check(int B[], int m) {
int i = 0;
boolean a = false;
while (i < B.length || !a) {
if ((ispresent(m, B, i))){
a = true;
break;
}
else
i++;
}
return a;
}
static boolean ispresent(int m, int B[], int i) {
return m == B[i] && m < B.length;
}
}
Among others you should check p[m] in check(B, p[m]) instead of m:
in static void printPemutation(int p[]):
while (m < p.length){
if (!check(B, p[m])) {
B = parenthesis(p, m);
printParenthesis(B);
}
m++;
}
then
static boolean check(int B[], int m) {
int i = 0;
while (i < B.length) {
if (m == B[i]) {
return true;
}
i++;
}
return false;
}
this does somehow more what you want, but not always i fear...

Categories

Resources