list of prime factors - java

I'm new to programming and Stack-overflow but I'm trying to create a list of prime factors from a number but it is returning more than one list and I don't know why. For example when I enter 10, it returns [2,5] and [2,5,5] instead of just [2,5]. Can someone explain what I'm doing wrong?
public class Solution {
ArrayList<Integer> primelist = new ArrayList<>();
ArrayList<Integer> findPrime(int num) {
for (int i = 2; i <= num; i++) {
if (num % i == 0) {
primelist.add(i);
num = num / i;
if (num == 1) { break;}
findPrime(num);
}
}
System.out.println(primelist);
return primelist;
}
public static void main(String[] args) {
Solution sol = new Solution();
sol.findPrime(30);//[2, 3, 5],[2, 3, 5, 5], [2, 3, 5, 5, 3, 5],[2, 3, 5, 5, 3, 5, 5]
sol.findPrime(10);//[2, 5],[2, 5, 5]
}
}

Im guessing you try to achieve the Sieve of Eratosthenes.
this works:
#Test
public void numbers() {
class Solution {
List<Integer> sieveOfEratosthenes(int n) {
boolean prime[] = new boolean[n + 1];
Arrays.fill(prime, true);
for (int p = 2; p * p <= n; p++) {
if (prime[p]) {
for (int i = p * 2; i <= n; i += p) {
prime[i] = false;
}
}
}
List<Integer> primeNumbers = new LinkedList<>();
for (int i = 2; i <= n; i++) {
if (prime[i]) {
primeNumbers.add(i);
}
}
return primeNumbers;
}
}
//test it..
Solution sol = new Solution();
System.out.println(sol.sieveOfEratosthenes(10));
System.out.println(sol.sieveOfEratosthenes(100));
}
... which yields correct results:
[2, 3, 5, 7]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
i borrowed this code from this article, an detailed explanation of the steps of the algorithm can be found there.

Related

How do I alternate chars from two arrays?

I need help with figuring out how to combine two char arrays and then have the elements alternate in a new array. The given arrays can be different lengths, for example: char1=[B,D] char2 = [c,R,5] the output should be char3= [B,c,D,r,5]
char[] ch3 = new char[ch1.length + ch2.length];
int count = 0;
int count2 = 0;
for(int i = 0; i < ch3.length; i++){
if(i < ch1.length) {
if(i%2 == 0 || count2 == ch2.length) {
ch3[i] = ch1[count];
count++;
}
}
if(i <ch2.length) {
if(i%2 != 0 || count == ch1.length) {
ch3[i] = ch2[count2];
count2++;
}
}
}
return ch3;
Similar solution to answer by oleg.cherednik, but without the need for slow % remainder operator.
public static int[] alternate(int[] a1, int[] a2) {
int[] a3 = new int[a1.length + a2.length];
for (int i1 = 0, i2 = 0, i3 = 0; i3 < a3.length; ) {
if (i1 < a1.length)
a3[i3++] = a1[i1++];
if (i2 < a2.length)
a3[i3++] = a2[i2++];
}
return a3;
}
Tests
System.out.println(Arrays.toString(alternate(
new int[] { 1, 2, 3 },
new int[] { 44, 55, 66, 77, 88 })));
System.out.println(Arrays.toString(alternate(
new int[] { 44, 55, 66, 77, 88 },
new int[] { 1, 2, 3 })));
Output
[1, 44, 2, 55, 3, 66, 77, 88]
[44, 1, 55, 2, 66, 3, 77, 88]
UPDATE
This algorithm can easily be enhanced to merge many arrays:
public static int[] alternate(int[]... arrays) {
int[] result = new int[Stream.of(arrays).mapToInt(a -> a.length).sum()];
int[] ai = new int[arrays.length];
for (int j = 0; j < result.length; )
for (int i = 0; i < arrays.length; i++)
if (ai[i] < arrays[i].length)
result[j++] = arrays[i][ai[i]++];
return result;
}
Test
System.out.println(Arrays.toString(alternate(
new int[] { 1, 2, 3 },
new int[] { 44, 55, 66, 77, 88 },
new int[] { 12, 34 },
new int[] { 5, 6, 7, 8 })));
Output
[1, 44, 12, 5, 2, 55, 34, 6, 3, 66, 7, 77, 8, 88]
UPDATE 2
It can also be done for collections:
#SafeVarargs
public static <T> List<T> alternate(Iterable<? extends T>... inputs) {
List<T> result = new ArrayList<>();
#SuppressWarnings("unchecked")
Iterator<? extends T>[] iter = new Iterator[inputs.length];
for (int i = 0; i < inputs.length; i++)
iter[i] = inputs[i].iterator();
for (int prevSize = -1; prevSize < result.size(); ) {
prevSize = result.size();
for (int i = 0; i < inputs.length; i++)
if (iter[i].hasNext())
result.add(iter[i].next());
}
return result;
}
public static <T> List<T> alternate(Collection<? extends Iterable<? extends T>> inputs) {
#SuppressWarnings("unchecked")
Iterable<? extends T>[] iterables = inputs.toArray(new Iterable[0]);
return alternate(iterables);
}
Tests
System.out.println(alternate(
Arrays.asList(1, 2, 3),
Arrays.asList(44, 55, 66, 77, 88),
Arrays.asList(12, 34),
Arrays.asList(5, 6, 7, 8)));
System.out.println(alternate(Arrays.asList(
Arrays.asList(1, 2, 3),
Arrays.asList(44, 55, 66, 77, 88),
Arrays.asList(12, 34),
Arrays.asList(5, 6, 7, 8))));
Output
[1, 44, 12, 5, 2, 55, 34, 6, 3, 66, 7, 77, 8, 88]
[1, 44, 12, 5, 2, 55, 34, 6, 3, 66, 7, 77, 8, 88]
public static void main(String... args) {
int[] one = { 1, 2, 3 };
int[] two = { 44, 55, 66, 77, 88 };
System.out.println(Arrays.toString(alternate(one, two)));
}
public static int[] alternate(int[] one, int[] two) {
// result array length is sum of lengths of given arrays.
int[] res = new int[one.length + two.length];
// i - result array iterator
// j - one array iterator
// k - two array iterarot
for (int i = 0, j = 0, k = 0; i < res.length; i++) {
// for even position we put next element from one array
if (i % 2 == 0)
// if one array has more elements - add it
// if no more elements in one array, add next element from two array
if (j < one.length)
res[i] = one[j++];
else
res[i] = two[k++];
// for odd position we put next element from two array
else
// if two array has more elements - add it
// if no more elements in two array, add next element from one array
if (k < two.length)
res[i] = two[k++];
else
res[i] = one[j++];
}
return res;
}
Output:
[1, 44, 2, 55, 3, 66, 77, 88]

Trying to swap the maximum and the minimum numbers in an array

I'm trying to swap the maximum and minimum values in an array in my program.
Here is the code:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int myArray[] = new int[25];
for (int i = 0; i < myArray.length; i++) {
System.out.println("Enter a number: ");
myArray[i] = in.nextInt();
}
int maximum = maxNumber(myArray);
int minimum = minNumber(myArray);
System.out.println(Arrays.toString(myArray));
}
public static int maxNumber(int[] arr) {
int maximumValue = arr[0];
//finds the maximum value in an array
for (int a = 1; a < arr.length; a++) {
if (arr[a] > maximumValue) {
maximumValue = arr[a];
}
}
return maximumValue;
}
public static int minNumber(int[] arr) {
int minimumValue = arr[0];
//finds the minimum value in an array
for (int a = 1; a < arr.length; a++) {
if (arr[a] < minimumValue) {
minimumValue = arr[a];
}
}
return minimumValue;
}
I have two separate functions to find the Maximum and Minimum values, but I'm stuck on the actual swapping of the values. The two functions work as I've used them for another program, but I'm not sure if they would work for this program.
At first I was thinking of finding them by setting them equal to each other in some way, but that led to nothing.
Any help would be appreciated.
public static void main(String... args) {
Scanner scan = new Scanner(System.in);
int[] arr = new int[25];
System.out.format("Enter array int numbers (%d in total): ", arr.length);
for (int i = 0; i < arr.length; i++)
arr[i] = scan.nextInt();
System.out.println(Arrays.toString(arr));
swamMinMax(arr);
System.out.println(Arrays.toString(arr));
}
private static void swamMinMax(int[] arr) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
min = Math.min(min, arr[i]);
max = Math.max(max, arr[i]);
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] == min)
arr[i] = max;
else if (arr[i] == max)
arr[i] = min;
}
}
Output:
Enter array int numbers (25 in total): 1 2 3 4 5 6 7 8 9 10 -1 -1 -1 14 15 16 17 18 19 20 21 22 23 66 66
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, 1, 1, 1, 17, 18, 19, 20, 21, 22, 23, 66, 66]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 66, 66, 66, 1, 1, 1, 17, 18, 19, 20, 21, 22, 23, -1, -1]
You were real close. I copied some of the code and commented where the changes need to be made. You can still use your existing code to populate the array from the console.
Also, kudos for assigning the first element in the array to min or max and starting your loop at 1. A lot of folks don't think about doing that.
int myArray[] = {1,10,-5,99,48,-22,43, 44,100,2};
System.out.println(Arrays.toString(myArray)); // print original array
int maxIdx = maxNumber(myArray); // get index of max
int minIdx = minNumber(myArray); // get index of min
// now swap max and min using the returned indices.
int save = myArray[maxIdx];
myArray[maxIdx] = myArray[minIdx];
myArray[minIdx] = save;
System.out.println(Arrays.toString(myArray)); // print the altered array
public static int maxNumber(int[] arr) {
int maximumValue = arr[0];
// finds the maximum value in an array
int idx = 0; //idx = 0 to start
for (int a = 1; a < arr.length; a++) {
if (arr[a] > maximumValue) {
idx = a; //save index of current max
maximumValue = arr[a];
}
}
return idx; // return index of max
}
public static int minNumber(int[] arr) {
int minimumValue = arr[0];
// finds the minimum value in an array
int idx = 0; // idx = 0 to start
for (int a = 1; a < arr.length; a++) {
if (arr[a] < minimumValue) {
idx = a; // save index of current min
minimumValue = arr[a];
}
}
return idx; // return index of min
}
This would print
[1, 10, -5, 99, 48, -22, 43, 44, 100, 2]
[1, 10, -5, 99, 48, 100, 43, 44, -22, 2]
You can use IntStream to find indexes of the maximum and minimum elements and then swap their values:
int[] arr = {1, 3, 5, 6, 4, 2, 8, 7, 9, -1, -3};
// indexes of the maximum and minimum elements
int max = IntStream.range(0, arr.length)
.boxed().max(Comparator.comparing(i -> arr[i])).orElse(-1);
int min = IntStream.range(0, arr.length)
.boxed().min(Comparator.comparing(i -> arr[i])).orElse(-1);
// swap the values
int temp = arr[max];
arr[max] = arr[min];
arr[min] = temp;
System.out.println(Arrays.toString(arr));
// [1, 3, 5, 6, 4, 2, 8, 7, -3, -1, 9]

Arraylist: method won't print last element in array

The method does not print the last odd value in the array. I tried array.size() - 1, but to no avail. What am I doing wrong?
import java.util.ArrayList;
public class Odds
{
public static void main(String[] args)
{
ArrayList<Integer> odds = new ArrayList<Integer>();
for(int index = 1; index <101; index++)
{
odds.add(index);
removeEvens(odds);
}
//call removeEvens on the array above!
}
public static void removeEvens(ArrayList<Integer> array)
{
for(int i = 0; i < array.size(); i++)
{
if (array.get(i)%2 == 0)
{
array.remove(i);
i--;
System.out.println(array.get(i));
}
if(i==array.size())
{
System.out.println(array.size() - 1);
}
}
}
}
You should address the following things in your code:
Do not call removeEvens(odds) inside the loop. Call it after the list is initialized.
Do not decrement the value of i explicitly.
You should do it as follows:
import java.util.ArrayList;
public class Odds {
public static void main(String[] args) {
ArrayList<Integer> odds = new ArrayList<Integer>();
for (int index = 1; index < 101; index++) {
odds.add(index);
}
removeEvens(odds);
System.out.println(odds);
}
public static void removeEvens(ArrayList<Integer> array) {
for (int i = 0; i < array.size(); i++) {
if (array.get(i) % 2 == 0) {
array.remove(i);
}
}
}
}
Output:
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
I tend to prefer using explicit iterators when doing this kind of modification.
List<Integer> odds = new ArrayList<>(List.of(1,2,3,4,5,6,7));
Iterator<Integer> it = odds.iterator();
while(it.hasNext()) {
if (it.next() % 2 == 0) {
it.remove();
}
}
And then there is the Streams version which passes the odds on down the stream for collection.
odds = odds.stream().filter(a->a%2 == 1).collect(Collectors.toList());
Both results are
[1, 3, 5, 7]

Using advanced for loop instead of for loop

I am a bit confused and I would need some clarification. Not too sure if I'm on the right track, hence this thread.
Here is my code that I want to decipher into advanced foreach loop.
int[] arrayA = {3, 35, 2, 1, 45, 92, 83, 114};
int[] arrayB = {4, 83, 5, 9, 114, 3, 7, 1};
int n = arrayA.length;
int m = arrayB.length;
int[] arrayC = new int[n + m];
int k = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(arrayB[j] == arrayA[i])
{
arrayC[k++] = arrayA[i];
}
}
}
for(int i=0; i<l;i++)
System.out.print(arrayC[i] + " ");
System.out.println();
So far this is the point where I am stuck at:
int[] a = {3, 8, 2, 4, 5, 1, 6};
int[] b = {4, 7, 9, 8, 2};
int[] c = new int[a.length + b.length];
int k = 0;
for(int i : a)
{
for(int j : b)
{
if(a[i] == b[j])
{
c[k++] = a[i];
}
}
//System.out.println(c[i]);
}
for(int i=0; i<c.length;i++)
System.out.print(c[i] + " ");
System.out.println();
}
You are almost there
for(int i : a)
{
for(int j : b)
{
if(i == j)
{
c[k++] = i;
}
}
}
With for(int i : a) access the elements in the array a using i.
If a is {3, 8, 2, 4, 5, 1, 6}, then i would be 3,8,2,.. on each iteration and you shouldn't use that to index into the original array. If you do, you would get either a wrong number or a ArrayIndexOutOfBoundsException
Since you want to pick the numbers that are present in both the arrays, the length of array c can be max(a.length, b.length). So, int[] c = new int[Math.max(a.length, b.length)]; will suffice.
If you want to truncate the 0s at the end, you can do
c = Arrays.copyOf(c, k);
This will return a new array containing only the first k elements of c.
I would use a List and retainAll. And in Java 8+ you can make an int[] into a List<Integer> with something like,
int[] arrayA = { 3, 35, 2, 1, 45, 92, 83, 114 };
int[] arrayB = { 4, 83, 5, 9, 114, 3, 7, 1 };
List<Integer> al = Arrays.stream(arrayA).boxed().collect(Collectors.toList());
al.retainAll(Arrays.stream(arrayB).boxed().collect(Collectors.toList()));
System.out.println(al.stream().map(String::valueOf).collect(Collectors.joining(" ")));
Outputs
3 1 83 114
Alternatively, if you don't actually need the values besides displaying them, and you want to use the for-each loop (and less efficiently) like
int[] arrayA = { 3, 35, 2, 1, 45, 92, 83, 114 };
int[] arrayB = { 4, 83, 5, 9, 114, 3, 7, 1 };
for (int i : arrayA) {
for (int j : arrayB) {
if (i == j) {
System.out.print(i + " ");
}
}
}
System.out.println();
Temporary variables aren't indices in an array in foreach Loop. So in 0th iteration, i contains the 0th element of a, j contains the 0th element in b. Your attempt should be like this:
int[] a = {3, 8, 2, 4, 5, 1, 6};
int[] b = {4, 7, 9, 8, 2};
int[] c = new int[a.length + b.length];
int k = 0;
for(int i : a) {
for(int j : b) {
if(i == j) {
c[k++] = i;
}
} //System.out.println(c[i]);
}
Please note your c[] array will contain the order maintained in a[].

how to get more than one minumum value from an int array?

I am trying to get at least 5 minimum values from an array of int's. My code attached works but it skips few values!
public static void main(String[] args) {
int array[] = {0, 1, 2, 1, 4, 5, 1, 7, 8, 1, 10, 11, 12, 13, 1, 15, 16, 17, 18, 19, 20, 2, 22, 23};
int min = 0;
int index = 0;
String output = "";
for (int x = 0; x < 5; x++){
min = array[x];
index++;
for(int i = index, limit = array.length; i < limit; ++i){
if(array[i] <= min){
min = array[i];
index = i + 1;
break;
}
}
output += index + "\t";
}
System.out.println(output);
}
Arrays.sort(array);
return Arrays.copyOfRange(array, 0, 5);
If you don't want to mutate the array passed in (ie you want to leave it unsorted), add this line first:
int[] array = Arrays.copyOf(array);
Perhaps you could sort the array using Arrays.sort() and then take the first five values:
Arrays.sort(array);
Now array[0] to array[4] contain the lowest 5 values.
If you only want to get 5 minimum values, I agree with Bohemian's Answer.
If you want to show the position of the array,such as 1,2,4,7,10, your demo is skips 2,
try my test...
public static void main(String[] args) {
int getNum = 5;
int step = 0;
String output = "";
int array[] = {0, 1, 2, 1, 4, 5, 1, 7, 8, 1, 10, 11, 12, 13, 1, 15, 16, 17, 18, 19, 20, 2, 22, 23};
int arrayClone[] = array.clone();
Arrays.sort(array);
int arrayResult[] = Arrays.copyOfRange(array, 0, getNum); //the arrayResult is what you want minimum values
ploop:for (int i:arrayResult) {
int index = 1;
for (int j :arrayClone) {
if(j==i){
step++;
output += index + "\t";
if (step>=getNum) {
break ploop;
}
}
index++;
}
}
System.out.println(output);
}

Categories