Generating an array of primes and using it in the program - java

I have generated first 10 million primes using the sieve of eratosthenes in Java. Following is the code for the same:
private static int[] gprime(int max) {
boolean[] isComposite = new boolean[max + 1];
for (int i = 2; i * i <= max; i++) {
if (!isComposite [i]) {
for (int j = i; i * j <= max; j++) {
isComposite [i*j] = true;
}
}
}
int numPrimes = 0;
for (int i = 2; i <= max; i++) {
if (!isComposite [i]) numPrimes++;
}
int [] primes = new int [numPrimes];
int index = 0;
for (int i = 2; i <= max; i++) {
if (!isComposite [i]) primes [index++] = i;
}
return primes;
}
I need to use this array a lot of times in my program after generating this array of primes. If i keep writing
gprime(179424673)[i]
(179,424,673 is the ten millionth prime) whenever I need to access any item from the array, the execution is very inefficient as it would run the method over and over again.
How do I simply get an array to access any prime from that array?
P.S. Why do I have downvotes on this question? Are people who are new to programming simply downvoted and discouraged like this to ask any further questions on stackoverflow? I clearly mentioned what my question is along with the code of what I have done so far.

Store it as a class level constant,
public static final int[] PRIMES = gprime(179424673); // <-- use the biggest value
// you will need here.
Then you can access it (instead of gprime(179424673)[i]) with
PRIMES[i]

Related

Search minimum absolute value difference in java

How can I optimize my algorithm to find the minimum absolute value difference in a given array. Here is my approach which checks each and every element and returning the value.
static int minAbsVal(int[] myArray){
ArrayList<Integer> diffs= new ArrayList(); // all absolute value differences
for (int i = 0; i < myArray.length; i++) {
for (int j = 0; j < myArray.length; j++) {
if (myArray[j]!=myArray[i]){
int absVal =Math.abs( myArray[i]- myArray[j]);
diffs.add(absVal);
}
}
}
int min = diffs.get(0);
for (int i = 1; i < diffs.size(); i++) {
if (min>diffs.get(i)){
min = diffs.get(i);
}
}
return min;
}
Check this solution. If array contains duplicates than it returns 0 if you wanna avoid than you can add conditions also.
static int minAbsVal(int[] myArray){
Arrays.sort(myArray);
ArrayList<Integer> diffs= new ArrayList<Integer>(); // all absolute value differences
for (int i = 0; i < myArray.length-1; i++) {
diffs.add(Math.abs( myArray[i+1] - myArray[i]));
}
Collections.sort(diffs);
return diffs.get(0);
}
Or you can also use :-
static int minAbsVal(int[] myArray){
Arrays.sort(myArray);
int minimum=Math.abs( myArray[1] - myArray[0]);
for (int i = 1; i < myArray.length-1; i++) {
int diff = Math.abs( myArray[i+1] - myArray[i]);
if (diff == 0)
return 0;
else if (minimum > diff)
minimum = diff;
}
return minimum;
}
Check the following solution,
static int minimumAbsoluteDifference(int n, int[] arr) {
int a = Math.abs(arr[1]-arr[0]);
Arrays.sort(arr);
for(int x=0;x<n-1;x++){
if(Math.abs(arr[x]-arr[x+1])<a){
a = Math.abs(arr[x]-arr[x+1]);
if(a==0){
return a;
}
}
}
return a;
}
Dependson the size of your array a good approach would be to divide it in different smaller arrays and look for the minimum of each in pararell and then compare those results .
Anyways you dont need so many iterations, you can just set the baseValue to the first element of the array and when iterating the array compare the baseValue vs the current, if the current is smaller then asign baseValue to current (I would rename baseValue to minValue in that case)

A subset sum algorithm which uses negative and positive integers

The checkNum is the target value. array is the array of integers i am looking at. I am using the matrix to hold True and False value to see my possible sums. The checkPower method is only checking if the index i+1 is = 2^n. I am having trouble writing an algorithm that can solve the subset sum problem using negative integers also. I wrote an algorithm but I cannot use it, because as the input size increases I am running out of memory. I was wondering if anyone came up with an algorithm to solve the problem. I would prefer if it was written java, or it could be a pseudo code.
public static ArrayList<Integer> populateArray(boolean[][]matrix, int []array, int checkNum){
int usedElement = 0;
ArrayList<Integer>resultArray = new ArrayList<>();
for(int i = 0; i < matrix.length; i++){
if(checkPower(i+1)){
matrix[i][usedElement] = true;
usedElement++;
if(array[usedElement-1] == checkNum){
resultArray.add(array[usedElement-1]);
return resultArray;
}
}
else{
int tempSum = 0;
int remainingIndex = (int) (i - Math.pow(2, usedElement-1));
matrix[i][usedElement-1] = true;
tempSum += array[usedElement-1];
for(int k = 0 ; k < matrix[remainingIndex].length; k++){
if(matrix[remainingIndex][k]){
matrix[i][k] = true;
tempSum += array[k];
}
}
if(tempSum == checkNum){
for(int j = 0 ; j < matrix[j].length; j++){
if(matrix[i][j]){
resultArray.add(array[j]);
}
}
return resultArray;
}
}
}
return resultArray;
}

Java sorting loop not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
. Basically what the following code does (suppose to) is, create a set of non-repeating random numbers, fill them up to an array which gets converted to a list, and sort them out. The problem is the nested for loops, i managed a work around but not even sure how it works. Secondely, i cant seem to sort it correctly, things repeat and out of bound errors pop up from time to time.
How the code works:
Generate non-repeating random numbers
Fill an array with them
Use nested for loop to find the smallest value
Insert that to a new array
Remove it from the first array
Repeat last 2 steps till the first array is empty and second array
os filled in a sorted order
import org.apache.commons.lang.ArrayUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.*;
import java.lang.*;
import java.io.*;
public class Sorter {
public static void main(String[] args) {
int[] process = fillArray(20,1,25);
sorter(process,20);
}
public static int[] sorter(int array[],int size) {
int[] useArray = array;
Integer[] newArray = ArrayUtils.toObject(useArray);
List<Integer> arrayList = new ArrayList(Arrays.asList(newArray));
//System.out.println((arrayList));
int counter = 1;
int minval = 0;
int diffsize = size - 1;
int actualVal = 0;
int storeArray[] = new int[size];
int removeIndex =0;
Integer[] newStore = ArrayUtils.toObject(storeArray);
List<Integer> storeList = new ArrayList(Arrays.asList(newStore));
System.out.println((arrayList));
// Both loops messed up
for (int i = 0; i < size+diffsize; i++) {
for (int n = 0; n < size-1; n++) {
if (arrayList.get(minval) < arrayList.get(counter)) {
actualVal = arrayList.get(minval);
System.out.println((arrayList.get(minval)) + " Less than " + arrayList.get(counter));
counter = counter + 1;
removeIndex = minval;
} else {
actualVal = arrayList.get(counter);
System.out.println((arrayList.get(counter)) + " Less than " + arrayList.get(minval));
minval = counter;
counter = counter + 1;
removeIndex = counter;
}
}
// System.out.println(actualVal);
storeList.add(actualVal);
arrayList.remove(actualVal); // need to remove the smallest value to repeat the sorting and get the next smallest value, but this is not removing it
size = size - 1;
counter = 1;
minval = 0;
// if (i + size == i) {
// storeList.set(i, arrayList.get(0));
// }
// System.out.println(removeIndex);
// System.out.println(arrayList);
}
// System.out.println(storeList);
int[] ints = new int[storeList.size()];
int d = 0;
for (Integer u : storeList) {
ints[d++] = u;
}
return ints;
}
public static int randomNum(int lower,int upper){
Random rand = new Random();
int randomNum = lower + rand.nextInt((upper- lower) + 1);
return randomNum;
}
public static int[] fillArray(int size,int lowerBound,int upperBound){
int holdArray[] = new int[size];
int rand = 0;
for (int count =0;count < holdArray.length;count++){
holdArray[count] = 0;
}
for (int count =0;count < holdArray.length;count++){
rand = randomNum(lowerBound,upperBound);
if (ArrayUtils.contains(holdArray, rand)) {
while (ArrayUtils.contains(holdArray, rand)) {
rand = randomNum(0, 20);
}
}
holdArray[count] = rand;
}
// System.out.println(Arrays.toString(holdArray));
//return holdArray;
return holdArray;
}
}
Can you give a compelling reason to justify in converting from array to list? why not use only list or only array altogether? I use ArrayList in my answer below;
First of, the fillArray class. You do not need to fill with all zeros. Why even bother to fill it with a value that you will replace anyway?
public static ArrayList<Integer> fillArray(int size,int lowerBound,int upperBound){
ArrayList<Integer> a = new ArrayList<Integer>(size);
for (int count =0;count < size;count++){
Integer rand = new Integer(randomNum(lowerBound,upperBound));
a.add(rand);
}
return a;
}
Second, the sorting class. Your method as you said, searching for lowest value then do magic stuff and what not.
public static ArrayList<Integer> sorter(ArrayList<Integer> unsorted) {
ArrayList<Integer> sortedArray = new ArrayList<Integer>(unsorted.size());
while(!unsorted.isEmpty()) { //repeats until the unsorted list is empty
int minval = unsorted.get(0);
int removeIndex = 0;
for(int i=1;i<unsorted.size();i++)
if (unsorted.get(i)<minval) {
minval = unsorted.get(i);
removeIndex = i;
}
sortedArray.add(minval);
unsorted.remove(removeIndex);
}
return sortedArray;
}
main method to test it
public static void main(String[] args) {
ArrayList<Integer> a = fillArray(20,1,25);
System.out.println("unsorted array");
for (Integer c : a)
System.out.print(c + ";");
ArrayList<Integer> b = sorter(a);
System.out.println("\nnew unsorted array");
for (Integer c : a)
System.out.print(c + ";");
System.out.println("\nsorted array");
for (Integer c : b)
System.out.print(c + ";");
}
this outputs
unsorted array
22;2;23;22;13;12;4;1;7;14;25;18;9;12;3;8;20;3;1;20;
new unsorted array
sorted array
1;1;2;3;3;4;7;8;9;12;12;13;14;18;20;20;22;22;23;25;
Separate out the "find the smallest" and "insertion/deletion" from arrays into two methods and then use them.
This way the code will be more manageable. Below is a sample find_min method.
int find_min(int[] array, int start) {
int min = Integer.MAX_VALUE;
for(int i = start; i < array.length; ++i)
if(array[i] < min)
min = array[i] ;
return min;
}
Now in the sorting routine, use the find_min to find the minimum element and insert it to new array and then delete the minimum element from the original array. However, this method does not return the index of the minimum element. So, I suggest you to modify it to return the index and the element as a pair of int values.
Your sorting routine will look something like this :
new_array := []
while(length(original_array) > 0)
min, min_index := find_min(original_array)
new_array.append(min)
original_array.delete(min_index)
You can use something like this to return an int pair :
class IntPair {
int min;
int index;
public IntPair(int x, int y) { this.min=x; this.index=y; }
public int get_min() { return min; }
public int get_min_index() { return index; }
}
Also, since you will de doing insertion and deletion, use ArrayList instead. It has methods to remove element at a particular index and append elements to it.
Note: Your approach outlined is close to Selection Sort algorithm in which we divide the array into two parts (sorted left part and unsorted right part) and repeatedly pick the smallest element from the right of the array and swap it with the left part's rightmost element.
min := array[0]
for(i := 0; i < array.length; ++i)
for(j := i+1; j < array.length; ++j)
if(array[j] < min)
min = array[j]
break
swap(array[i], array[j])
In this case, you dont need two arrays and you dont need to delete or insert elements into an array either.

array with non repeating numbers from a range in ascending order, java

Im trying to generate an array with 1000 integers of non-repeating numbers in ascending order from 0 to 10,000
So far what I have is:
public static void InitArray(int[] arr) { // InitArray method
int i, a_num; // int declared
Random my_rand_obj = new Random(); // random numbers
for (i = 0; i <= arr.length-1; i++) // for loop
{
a_num = my_rand_obj.nextInt(10000); // acquiring random numbers from 0 - 10000
arr[i] = a_num; // numbers being put into array (previoulsy declared of size 1000)
}
}
public static void ShowArray(int[] arr) { // ShowArray method
int i; // int declared
for (i = 0; i <= arr.length-1; i++) { // for loop
System.out.print(arr[i] + " "); // show current array content
}
System.out.println(); // empty line
}
public static void Sort(int[] arr) { // SortArray method
int i, min, j; // int decalred
for (i = 0; i < arr.length-1; i++) { // for loop
min = i; // min is i
for (j = i + 1; j < arr.length; j++) { // nested for loop
if (arr[j] < arr[min]) { // if statement
min = j; // j is the new minimum
}
}
int swap = arr[min]; // swap "method"
arr[min] = arr[i];
arr[i] = swap;
}
}
Is there any way to check the numbers are not repeating? Is there a function besides the random generator that will let me generate numbers without repeating? Thanks for any help
You can declare array of size 10,000
and init the array in away that each cell in the array will holds the value of it's index:
int [] arr= new int[10000];
for (int i=0 i < arr.length; i++){
arr[i] = i
}
Now you can shuffle the array using java Collections.
and take the first 1000 items from the array and sort then using java sort.
This will do I believe..
HashSet hs = new HashSet();
for(int i=0;i< arr.length;i++)
hs.add(arr[i]);
List<Integer> integers=new ArrayList<>(hs);
Collections.sort(integers);
A very simple solution is to generate the numbers cleverly. I have a solution. Though it may not have an even distribution, it's as simple as it can get. So, here goes:
public static int[] randomSortedArray (int minLimit, int maxLimit, int size) {
int range = (maxLimit - minLimit) / size;
int[] array = new int[size];
Random rand = new Random();
for (int i = 0; i < array.length; i++ ) {
array[i] = minLimit + rand.nextInt(range) + range * i;
}
return array;
}
So, in your case, call the method as:
int randomSortedArray = randomSortedArray(0, 10_000, 1_000);
It's very simple and doesn't require any sorting algorithm. It simply runs a single loop which makes it run in linear time (i.e. it is of time complexity = O(1)).
As a result, you get a randomly generated, "pre-sorted" int[] (int array) in unbelievable time!
Post a comment if you need an explanation of the algorithm (though it's fairly simple).

Need explanation on differences of permutation algorithms

I'm currently working on a problem that asks me to find the millionth lexicographic permutation of 0,1,2,3,4,5,6,7,8,9. I thought of a very crude solution at first glance that had a complexity of around O(n^3)
public static String permute(char[] a){
ArrayList<String> array = new ArrayList<String>();
int counter = 1;
for (int i = 0; i < a.length; i++){
array[counter] += a[i];
for (int j = 0; j < i; j++){
array[counter] += a[j];
for(int k = a.length; k > i; k--){
array[counter] += a[k];}counter++;}
}
}
The code may not be perfect but the idea is that a single digit is selected and then moves to the end of an array. The second array creates the numbers behind the selected digit and the third array creates numbers after it. This seems like a terrible algorithm and i remembered a past algorithm that's like this.
public static HashSet<String> Permute(String toPermute) {
HashSet<String> set = new HashSet<String>();
if (toPermute.length() <= 1 )
set.add(toPermute);
else {
for (int i = 0; i < toPermute.length(); i++ )
for (String s: Permute(toPermute.substring(0,i)+ toPermute.substring(i+1)))
{
set.add(toPermute.substring(i,i+1)+s);}
}
return set;
}
}
The problem is that this algorithm uses unordered sets and I have no idea about how it can become ordered enough for me to find the millionth permutation. I also do not know the complexity other than the fact it could be O(n^2) because it calls itself n times and then unstacks.
A couple of things in general about your code above:
You should implement to interfaces and not concrete classes I.e. List<String> array = .... Similarly with your Set.
Array's start at index 0, you are starting your counter at index 1.
Finally to answer your question there is a brute force way and a more elegant way that uses some principles in math. Have a look at this site which explains the approaches.
It seems to me (1) which permutation is the millionth depends absolutely on the order you use, and (2) permutations of this sort are ripe problems for recursion. I would write this as a recursive program and increment the count for each iteration. [was that your question? I didn't really see a question...]
Here is a solution that is more efficient:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class P24 {
static final int digits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static List<Integer> remainedDigits = new ArrayList(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
static final int factorials[] = new int[digits.length + 1];
static final int N = 1000_000;
static int low = -1;
static int lowIndex = -1;
static int highIndex = -1;
public static void main(String args[]) {
populateFactorials(digits.length);
validateN(N);
identifyMargins();
int n = N; // it will be changed
int fixedDigits = digits.length - highIndex;
String result = "";
for (int i = 0; i < fixedDigits; i++) {
result += remainedDigits.get(0);
remainedDigits.remove(0);
}
for (int i = fixedDigits; i < digits.length; i++) {
int pos = 0;
int firstDigit = remainedDigits.get(pos);
low = factorials[lowIndex];
while (n - low > 0) {
pos++;
n -= low;
}
lowIndex--;
result += remainedDigits.get(pos);
remainedDigits.remove(pos);
}
System.out.println(result);
}
private static void validateN(int n) {
if (n < 0 || n > factorials[factorials.length - 1]) {
System.out.println("The input number is not valid");
System.exit(0);
}
}
private static void identifyMargins() {
for (int i = 0; i < factorials.length - 1; i++) {
if (factorials[i] <= N && N < factorials[i + 1]) {
lowIndex = i;
highIndex = i + 1;
}
}
}
private static void populateFactorials(int max) {
for (int i = 0; i <= max; i++) {
factorials[i] = fact(i);
}
}
private static int fact(int x) {
if (x == 0 || x == 1) {
return 1;
}
int p = 1;
for (int i = 2; i <= x; i++) {
p *= i;
}
return p;
}
}
Time: 305 microseconds.
Explanation:
Because the total number of permutations for {a1, ..., an} is n!, I decided that I need a factorials array. I stored in it: {0!, ..., 10!}.
I identified where is the number placed in this sequence, and for our case (N = 1000000) it is between 9! and 10!. If it was lower than 9! I add a padding of fixedDigits digits taken from the remainedDigits array.
Because the number is bigger than 9!, I count how many times I can extract 9! from the number and the result helps me to obtain the first digit. Then, I have a similar approach for 8!, 7!, etc.
The above explanation is based on the following simple observation. If we have a set {a1,...,ai,...,an} and we fix a1, ..., ai, we can obtain (n-i)! different strings.
Notice that if you use:
static List<Integer> remainedDigits = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
you cannot remove elements from the list.
`

Categories

Resources