I'm rather new to Java, and I'm trying to figure out a way to copy all primes inside of an array and copy those to another array.
To do so, I've implemented a separate isPrime() method to check whether the element is a prime, and another method that counts the number of primes in that array countPrimes(), such that I can determine the new array's size.
Here is where I'm kind of stuck:
public static int[] primesIn(int[] arr) {
int primeHolder = countPrimes(arr);
int[] copyArr = new int[primeHolder];
for (int i = 0; i < arr.length; i++) {
if (isPrime(arr[i]) == true) {
copyArr[>Needs to start from 0<] = arr[i];
}
}
return copyArr;
}
int[] arrayMan = {3,5,10,15,13};
At copyArr the position should be 0, followed by +1 everytime it finds a prime. If I were to give it i position, as in copyArr[i] = arr[i], then say the prime is at position 5, it would try to save the prime onto position 5of copyArr, which doesn't exist if there are only three primes in the original array, which would've given copyArr a length of only three.
Something tells me a different for loop, or maybe even an additional one would help, but I can't see how I should implement it. Help is greatly appreciated!
Have a second index variable int primeCount, and increment it whenever you find a prime. No need for a 2nd loop.
In modern days of abundant memory, things are usually not done like this. If you don't have some extra hard requirements, you could just use a resizable ArrayList<Integer>, and add() stuff in there. (and convert it back to int[] at the end if needed). This is also better in this case, because typically your countPrimes call will run much slower than ArrayList reallocations.
Read your words carefully:
At copyArr the position should be 0, followed by +1 everytime it
finds a prime.
That means that index in a new array does not depend on its position in the old array. Create a counter. And each time you place a prime number into a new array, increment it by 1. Thus you can always know where to put a new number.
Related
I have a pseudo code that I have translated into java code but anytime I run the code, I get an empty arraylist as a result but it is supposed to give me a random list of integers.
Here is the pseudo code:
Algorithm 1. RandPerm(N)
Input: Number of cities N
1) Let P = list of length N, (|P|=N) where pi=i
2) Let T = an empty list
3) While |P| > 0
4) Let i = UI(1,|P|)
5) Add pi to the end of T
6) Delete the ith element (pi) from P
7) End While
Output: Random tour T
Here is the java code:
public static ArrayList<Integer> RandPerm(int n)
{
ArrayList<Integer> P = new ArrayList<>(n);
ArrayList<Integer> T = new ArrayList<>();
int i;
while(P.size() > 0)
{
i = CS2004.UI(1, P.size());// generate random numbers between 1 and the size of P
T.add(P.get(i));
P.remove(P.get(i));
}
return T;
}
I don't know what I am doing wrong.
ArrayList<Integer> p = new ArrayList<>(n);
... creates an empty list with an initial capacity of n.
All this does is tell the ArrayList what size array to initialise as backing store - most of the time you achieve nothing useful by specifying this.
So your while(p.size() > 0) runs zero times, because p.size() is zero at the start.
In the pseudocode "where pi=i" suggests to me that you want to initialise the list like this:
for(int i=0;i<n;i++) {
p.add(i)
}
(I have lowercased your variable name - in Java the convention is for variables to startWithALowerCaseLetter -- only class names StartWithUpperCase. It's also the Java convention to give variables descriptive names, so cityIdentifiers perhaps)
You may want to know that, even if you fix the problem that P is always empty, there are 2 more issues with your implementation.
One is that P.remove(P.get(i)) does not necessarily remove the ith item if the list has equal value items. It scans from the beginning and removes the first occurrence of the item. See ArrayList.remove(Object obj). You should use P.remove(i) instead for the correct results.
Then the performance is O(n^2). The reason is that ArrayList remove an item by shifting all the subsequent items one slot to the left, which is an O(n) operation. To get a much better performance, you can implement your own "remove" operation by swapping the item to the end. When you generate the next random index, generate it within the range [0, beginning index of the removed items at the end). Swapping is O(1) and the overall performance is O(n). This is called Knuth Shuffle by the way.
I'm trying to teach myself coding, and I stumbled on an example I don't understand. Could someone give me an overview of what this code is supposed to do? I'm a bit confused about int a[] and what is later int a[i]. I know what an array is, but could someone please explain how this is being used in this context? Thank you in advance.
public class all {
public int select(int a[],int n,int x)
{
int i=0;
while(i<n && a[i]<x)
{
if(a[i]<0)
a[i]=-a[i];
i++;
}
return(a[i-1]);
}
}
This
if(a[i]<0)
a[i]=-a[i];
i++;
is he same like this
if(a[i]<0) {
a[i]=-a[i];
}
i++;
a[i] -> value at the position i, into the Array
if(a[i]<0) { -> if the value at position i is smaller than 0, also negative number
a[i]=-a[i]; -> replace the value with a reverse sign.
i++ -> increment loop Counter
Also what is done here: negative numbers convert to positive numbers.
while(i<n && a[i]<x) -> i = loop counter; if i smaller n and the value at position i in the array is smaller than x, then go into the loop.
return(a[i-1]); -> return the last value, that has been checked into the while loop
the method gets an array and two int args n and x (as a side note, I must say the names leave a lot to be desired...)
anyway, lets see what are the args for. they both are used in the while loop. the condition i<n tells us that n serves as upper limit to the iteration, while the condition a[i]<x tells us that x is used as upper limit to the values in the array.
so far, we can say:
select method receives an array, int arg specifying iteration-upper-limit and int arg specifying cell-value-upper-limit.
iterate over the array until you reach position specified by iteration-upper-limit or you reach a cell value that exceeds cell-value-upper-limit (which ever comes first)
can you continue to say what's being done inside the loop? it's fairly straightforward.
1.) a[] is the declaration of array.size is not defined.
2.)In a[i], i is the index number of the array...that means indicating the position of the element in array.
a[] is an array and we do not know its length. n must be lower than the length of a[] or it will throw an exception. It it traverses from the first element toward the last untill it one element is larger than x. it returns these element's absolute value which were traversed
I have done some searching for this, however I haven't found anything specific to what I'm working on.
I'm trying to do addition with two arrays of integers. This alone isn't difficult, however, I'm having difficulty with a specific aspect.
The array size and array elements are determined by user input. Each digit must be greater than or equal to 0 and less than or equal to 9. The problem lies in the fact that if I initialize an array in my method, I must determine the size of the array when I initialize it. But if the user enters a series of numbers, such as 8, 0, 0, 0 for the first array, and 3, 0, 0, 0 for the second array, that would result in the sum[] being one integer bigger than either of the arrays initialized by the user. I don't want to do
int[] sum = new int[x.length+1]
because in the case of it not needing an extra element, I will get an ugly 0 where I don't want to see that. I'm not necessarily asking for a direct answer with code, but perhaps a bit of wisdom that will push me in the right direction. Thanks.
public static int[] addArrays(int[] x, int[] y){
int[] sum = new int[?];
int carryOver = 0;
int singleDigit = 0;
Just make the array originally the same size as the original (int[] sum = new int[x.length];. Then, if you need to expand the size of your array, set sum =Arrays.copyOf(sum, sum.length+1);, which will expand the size of your array to the necessary size.
The traditional way to iterate over an (integer, in this example) array of elements is the following:
int[] array = {5, 10, 15};
for(int i = 0; i < array.length; i++) [
//do something with array[i]
}
However, does this mean that after each iteration 'array.length' is re-evaluated? Would it not be more efficient to do this? :
int[] array = {5, 10, 15};
int noOfElements = array.length;
for(int i = 0; i < noOfElements; i++) {
//do something with array[i]
}
In this way, (to my understanding) the program only has to calculate it once and then look up the value of 'noOfElements' variable.
Note: I am aware of the enhanced for-loop, but it cannot be used when you want to use the variable that is being incremented ('i' in this example) to achieve other things within the for-loop.
I'm suspecting that this is actually a question of whether the Java compiler has the capability of realising that 'array.length' doesn't change and actually reusing that value after calculating it once.
So my question is: Is there a difference in runtime efficiency of the first block of code I wrote and the second one?
What I gather from the replies below, is that when an array is instantiated (is that the right word?) an instance variable called length is created and it is equal to the number of elements in the array.
What this means is that the statement array.length has nothing to do with calculation; it is only referencing the instance variable.
Thanks for the input guys!
See JLS- 10.7. Array Members:
The members of an array type are all of the following:
The public final field length, which contains the number of components
of the array. length may be positive or zero.
Calling array.length is O(1) (constant time operation - it's final member of the array).
Also note that as mentioned in the comments, "traditional" way is not necessarily the way you proposed. You can use for-each loop:
for(int i : array) {
...
}
length is a field, therefore is not calculated when examining the for loop condition.
Your second block of code introduces a field to represent the length, thus increases memory usage (slightly, but still an important factor).
Yet further, if the array were to be re-created/re-assigned at some point, with a different set of values, your field would not be updated, but the array's length field would.
length is a field of an array that is not being calculated if you call myArray.length, instead it is being set when you create the array. So no, it's not more efficient to save it to a variable before starting the for() loop.
I have created a method to randomize the list:
public <T> List<T> randomize(List<T> list) {
LinkedList<T> randomizedList = new LinkedList<>();
Random random = new Random(list.size());
for (int i = random.nextInt(); i < list.size(); i++) {
randomizedList.add(list.get(i));
}
return randomizedList;
}
The list that I am passing to this method contains for e.g. five elements. When I am creating Random random = new Random(list.size()); I expect so when I call random.nextInt() what it will return me the random integer which will be an index of the list element.
But when I call random.nextInt(); instead of returning the number from the interval [0, 4] (which I expect to be returned) it returns me the value of for e.g.: -349120689. Which gives me an java.lang.IndexOutOfBoundsException: Index: -349120689, Size: 5.
Why is this happening and how to solve this?
new Random(list.size()); this sets the seed of the Random number generator to list.size(); I suggest changing to new Random() (which will give you a seed based on the current time of the system). Preferably though, you'd want to reuse the same Random object at all times.
random.nextInt(); here is where you'd want to put random.nextInt(list.size()); which will give you a number from 0 to list.size() - 1.
Even with the above changes, your code would just give you a sublist of the list starting at a random index and going until the end. Use Collections.shuffle(list) instead.
To do a real shuffling, you would need to "remember" which elements
you have inserted or not. In pseudo-code, you could do the
following:
Copy the original list to a new one, let's call it "orig"
Create a new, empty, list, let's call it "result"
As long as the orig list has elements, get an element at random index and add it to the result list. Remove the chosen element from orig list.
Return result list.
I expect so when I call random.nextInt() what it will return me the random integer which will be an index of the list element.
You've misunderstood the purpose of the Random(long) constructor. The purpose of that constructor is to specify a seed for the list. You don't want to do this - it would mean that every collection of size 5 is always shuffled the same way.
You specify the range on each call to nextInt. So if you want a random number between 0 (inclusive) and max (exclusive) you just use:
int value = random.nextInt(max);
However, it would be much better just to use Collections.shuffle instead of writing your own code to do this - assuming you really want a shuffle (which isn't what your current approach would give you anyway - even after fixing the nextInt call, you'd end up
with basically a sublist, because nextInt() is only called once. So if the first call to nextInt() returns 2 (in a list of 5) you'd end up returning a new list containing the final 3 elements. I strongly suspect that's not what you were trying to do.
As a side-note, when you want to know why an API isn't behaving the way you expect it to, read the documentation. The documentation of the Random(long) constructor and Random.nextInt() are pretty clearly not the behaviour you were expecting.
use this
public <T> List<T> randomize(List<T> list) {
LinkedList<T> randomizedList = new LinkedList<>();
Random random = new Random();
for (int i = random.nextInt(list.size()); i < list.size(); i++) {
randomizedList.add(list.get(i));
}
return randomizedList;
}
The argument to the Random constructor is a random seed, not the maximum of what it returns.
Pass the maximum number to nextInt() instead.
You're confusing the argument to nextInt(n) (upper bound for the randomization) with the argument to the constructor (random seed). You shoudl use nextInt(list.size), and probably, initialize the Random object using new Random().