When the program runs it outputs 10 random numbers and each number stores into LinkedList list, then this list is being displayed there are only 4-5 numbers are shown instead of 10 from the original array. Here's the simple code:
import java.util.LinkedList;
import java.util.Random;
public class randomSum {
private static Random rand = new Random();
private static LinkedList<Integer> arr = new LinkedList<Integer>();
public static void main(String[] args) {
int num = 0;
System.out.println("Original List");
for(int i=0; i < 10; i++) {
num = rand.nextInt(1000);
arr.add(num);
System.out.println(num);
}
System.out.println("\nLinkedList List");
for(int j=0; j < arr.size(); j++)
System.out.println(arr.remove(j));
}
}
The output is like that, which is not exactly what I expected. They both should be the same. Why is that happening?
Original List
693
239
33
999
862
965
994
884
127
977
LinkedList List
693
33
862
994
127
Because on each iteration, you are removing the element you are printing. That will break up the indices. For e.g., when you remove element at index 0, the element at index 1 now moves to index 0, but the loop index moves to index 1 now. So the element just shifted to index 0, was never processed. This will happen to every alternate element, and hence you get that output.
You need to use get(j) instead of remove(j):
for(int j=0; j < arr.size(); j++)
System.out.println(arr.get(j));
or use enhanced for loop:
for (int val: arr) {
System.out.println(val);
}
If you really want to remove items while printing the LinkedList, you should use an Iterator. Removing elements like you're doing causes undefined behavior. Do something like that:
Iterator<Integer> it = arr.iterator();
while(it.hasNext()) {
int element = it.next();
System.out.println(element);
it.remove();
}
In this answer I want to illustrate what actually happens, so that you understand why remove(j) is probably not what you want, like Rohit Jain said.
In the beginning your list looks like this:
693 239 33 999 862 965 994 884 127 977
After the first iteration, in which you call remove(0) it will look like this
239 33 999 862 965 994 884 127 977
so when you call remove(1) in you next iteration you are removing the element 33, which was originally the third element. So each iteration you actually go forward by two elements, with respect to your original list.
You see the regulation the output comes? It's every other number in the original list.
every time you use arr.remove(j) , the list arr will shrink size by 1. so the loop ended while j==5, meantime arr.size()=5. And furthermore, you use arr.remove(j), then the jTH item is removed, and after j++, you skip the original (j+1)th,current jTH item. So comes to the regulation that every other number comes from the original list.
If you replace remove to get that would work as you expected.
And, you can replace remove(j) to remove(0) and change the loop ending condition to j<10, which works fine, too.
Related
I am trying to create a method that produces lottery numbers with a random number generator. There are two groups of numbers. Group one is supposed to have five different numbers that appear in sorted order, with a range of 1-56. Group two consists of a single number with a range of 1-46. When I run the program, group one always begins two consecutive zeros even though I tried to write the code in a way that doesn't allow group one to have zeros or repeating numbers. At first I thought that the problem must have something to do with the random number generator, so I tried debugging the project in NetBeans. As I stepped through the lines of code, I could see the values assigned to n, which is the variable that holds the numbers produced by the random generator. The values of n were 54, 50, 11, 49, and 28. In the program, the values of n are put into a sorted array. So the output for group one should have been 11, 28, 49, 50, 54, but instead it was 0, 0, 11, 28, 49.
Here is my code:
public static void MakeTickets(){
int [] Group1= new int [5];
int Group2;
int n;
Random rand= new Random ();
for (int j=0 ; j<5; j++){
//Here, I try to make sure that the range for n is 1-56
n= rand.nextInt(55)+1;
//Here, I try to make sure that a number isn't put into the group one
//array more than once
while (Arrays.binarySearch(Group1, n)>=0){
n= rand.nextInt(55)+1;
}
Group1[j]=n;
Arrays.sort(Group1);
}
Random r= new Random();
int num= r.nextInt(45)+1;
Group2=num;
System.out.print("Here is your ticket: Group One= ");
for(int number: Group1){
if (number==Group1[4]){
System.out.print(number);
} else {
System.out.print(number+", ");
}
}
System.out.println(" Group Two= "+Group2);
}
Here is the output:
Here is your ticket: Group One= 0, 0, 33, 45, 50 Group Two= 40
I've tried using ThreadLocalRandom instead, but I still had the same problem. Does anyone know what I am doing wrong? Any and all advice is much appreciated.
The Arrays.sort(Group1); is causing the problem.
I believe the Arrays.sort(Group1); should be placed after the first for loop (after generating the Group1 values).
Currently the values are sorted after adding every value.
Initially the values in the array are 0 0 0 0 0
1st Iteration
After generating the first number
n= rand.nextInt(55)+1; //lets assume the generated value is 43
the, array becomes 43 0 0 0 0
After calling the sort ,
Arrays.sort(Group1);
the array becomes 0 0 0 0 43
2nd Iteration.
After generating the second number
n= rand.nextInt(55)+1; //lets assume the generated value is 22
the, array becomes 0 22 0 0 43
After calling the sort ,
Arrays.sort(Group1);
the array becomes 0 0 0 22 43
3rd Iteration
After generating the third number
n= rand.nextInt(55)+1; //lets assume the generated value is 31
the, array becomes 0 0 31 22 43
After calling the sort ,
Arrays.sort(Group1);
the array becomes 0 0 22 31 43
The 4th and 5th iteration do not change the first two values in the array. This way the first 2 number get stuck as 0s, which explains your result.
You can't use Arrays.binarySearch on an unsorted array. In such case result of this operation is unpredictable.
Sort moves all zeros to the beginning of the array. But you are not rewriting them (cause j is being incremented).
Hello thereļ¼As far as I know, there are zero-digit situation, the general is the default allocation of zero is the compiler, that you did not initialize this variable.
I believe the problem is that the int array is being sorted every time. The int array is initialized with values of 0. By sorting the array every time you are changing where the new random number needs to be inserted. So sometimes you are accidentally overwriting one of the randomly generated numbers instead of the 0's.
Perhaps instead of using BinarySearch which requires the sorting just used contains and get rid of the sorting until all of the random numbers are generated. I don't know the exact syntax since I haven't coded in Java for 3 years, but you could do something like Arrays.asList(Group1).contains(n). So...
for (int j = 0; j < 5; j++) {
//Here, I try to make sure that the range for n is 1-56
n= rand.nextInt(55)+1;
while (Arrays.asList(Group1).contains(n)) {
n = rand.nextInt(55)+1;
}
Group1[j] = n;
}
Arrays.sort(Group1);
I'm trying to create a method to randomly shuffle a array of primitives using a Arraylist. I was wondering if the .get(); method was the proper method to use on my Arraylist where on a normal array in a for loop it would just be array[j]; where j is the value in the for loop. Also, I'm not too familiar with Math.random(); and needed some help implementing it in this situation.
public static void selectionShuffle(int[] values) {
ArrayList<Integer> temp=new ArrayList<Integer>(52);
int rando=(int)Math.random()*52+1;
for(int counter=0;counter<temp.size();counter++){
temp.set(rando,(Integer)counter);
}
for(int counter=0;counter<values.length;counter++){
values[counter]=temp.get(counter);
}
}
Collections.shuffle(temp); is what you need
http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle%28java.util.List%29
What you may want to do is after creating the ArrayList, run a for-loop to add 52 values:
for(int i = 0; i < 52; i++){
temp.add(i);
}
Then do this:
Collections.shuffle(temp);
Print out the result to confirm
Your implementation should ensure that every index is set at least once. Your temp.set(rando,(Integer)counter) sets a random index to the value of counter. Also, you must change the value of rando with every iteration of the loop.
Math.random()
returns a double value with a positive sign, greater than or equal to
0.0 and less than 1.0.
as per Oracle, so when you multiply by 52.0 you get a value between 0 and 51.9 inclusive. When cast to an integer it is truncated to the floor of its value, giving you a range of 0 - 51 inclusive, or the size of your array.
I am using this book data structures and algorithms in java to learn about (you guessed it) - data structures and algorithms. This piece of code confuses me. I have tested it and it works but i don't see where in the code we specify to delete 55 exactly?
I see that we search for it in the array and move data elements up the index but don't see where we tell the compiler to delete 55.
searchKey = 55; // delete item with key 55
for(j=0; j<nElems; j++) // look for it
if(arr[j] == searchKey)
break;
for(int k=j; k<nElems-1; k++) // move higher ones down
arr[k] = arr[k+1];
nElems--; // decrement size
To be precise, this code does not delete an array element; it overrides it.
Note how j is declared outside the first loop, and used in the second loop to initialize the value of k. The first loop walks j through the array, until j "points" to the element with the value of 55. When this happens, the code exits the loop through break, so when the second loop reads j, it still points to the location in the array where 55 is stored. Now the second loop copies elements from k+1-st location into k-th, "overriding" the value of 55 on the first iteration, and then moving the rest of the values in the consecutive iterations.
Consider this example:
Index: 0 1 2 3 4 5
Value: 30 40 55 60 70 80
After the first loop j is set to 2. Each iteration of the second loop changes the array as follows:
Index: 0 1 2 3 4 5
Iteration 0: 30 40 55 60 70 80
Iteration 1: 30 40 60 60 70 80
Iteration 2: 30 40 60 70 70 80
Iteration 3: 30 40 60 70 80 80
At this point nElems is decremented, making sure that the last element (i.e. 80) is disregarded if the program runs again.
For the sake of example, suppose:
searchKey = 3
arr = {1,2,3,4,0,0,0}
nElems = 4
This means we have an array with seven slots, but the last three elements of the array are unused by the surrounding data structure.
The first for loop is simply looking for the index, j, that contains searchKey (searchValue would have been a better name, but alas). Once it finds the correct index, it breaks, leaving j set. In our example, j = 2 at the end of the first loop. Nothing has been changed yet, we've just found the index we want to clear.
The second for loop does the actual leg work by shifting everything after our found element down one index (and overwriting the found index in the process), so arr[2] is set to arr[3] and arr[3] is set to arr[4] and so on. At the end of the second loop we have
arr = {1,2,4,4,0,0,0}
Finally, we decrement nElems by one, so that there are now only three elements in the data structure. The last four elements in the array (4,0,0,0) are all now garbage that will get written over if more elements are added.
It is overwritten by the first iteration of the second for loop.
Here's the code for orderedInsertion for an array:
public void orderedInsert(int x){
int i =0;
for(i=0;i<count;i++) if(arr[i]>x) break;
for(int j=count-1;j>=i;j--) arr[j+1] = arr[j];
arr[i]=x;
count++;}
If instead of using a break right after the IF statement, I did implement the second for loop ( the one with j variable immediately as follows:
EDITED CODE:
public void orderedInsert(int x) {
boolean flag = false;
int i =0;
for (i=0; i<count; i++) {
if (arr[i]>x) {
for (int j=count-1; j>=i; j--) {
arr[j+1] = arr[j];
arr[i] = x;
count++;
flag = true;
}
if (flag)
break;
}
}
}
Would both algorithms run in O(N)? This is what makes sense to me, but my instructor said "if you see two nested loops, this means it runs O(N^2).
What makes sense to me is that even in the worst case scenario we will only traverse N times.
This case it seems that these two algorithms is O(n) even though they are not similar. Count is being used differently, it looks like the first one uses count perhaps to show the size of the array that it changed. So if someone put an element in the array, count increments. But the second uses count for something else. Also the same for arr[i] = x;. First one seems to set it once, while the second one continues to set it.
A typical case of nested loop is like the following:
for(int j=count-1;j>=i;j--)
like if count = 100
for(int j=100-1;j>=0;j--) // 100 times it must iterate
//then i turns to 1
for(int j=100-1;j>=1;j--) //must iterate 99 times
etc...
If it was just one loop it will iterate only 100
for(i=0;i<count;i++) //iterate 100 times that is it, its done
but with a nested loop it iterates
when i=0 : it iterates 100 times
when i=1 : it iterates 99 times
when i=2 : it iterates 98 times
So in other words, if there was just one loop here it will only iterate 100 times
But with this nested loop it is looping 100 times + 99 times + 98 times etc. This is most likely especially 'if(arr[i]>x) break;' never happens
Also according to Big Oh notation, if something takes (n(n-1))/2 times to complete, which this does, it is considered O(n^2)
I'm still learning about sorting and Arrays. Came up with this code which does sorting letters or numbers on ascending order but I really don't get the last part where System.out.println(SampleArray[i]);. Why is it SapleArray[i]? can someone enlighten me please.
public class TestClass {
public static void main(String[] args) {
String SampleArray[] = {"B","D","A","R","Z"};
Arrays.sort(SampleArray);
for (int i=0; i < SampleArray.length; i++) {
System.out.println(SampleArray[i]);
}
}
}
SampleArray refers to the whole array - here containing five strings.
SampleArray[0] refers to the first item in the array (here the string "B").
for (int i=0; i < SampleArray.length; i++) {
System.out.println(SampleArray[i]);
}
lets i take the values 0, 1, 2, 3, 4 one after another, so you print out first SampleArray[0]and then SampleArray[1] and so on until all the items have been printed.
You are trying to print an array, which is an ordered collection of items.
SampleArray[i] inside the loop lets you access one element at a time, in order.
More specifically, i takes on the values 0 through 4 in this case.
SampleArray[0] would give you the first element of SampleArray, because Java uses zero-based indexing for arrays.
Going through your code:
first you create a String array with those letters as element, which are saved like this: element 0 of array = B, element 1= D, etc. (in Arrays the counting always begin by 0 and not by 1).
Then it sort it in ascending order.
The for loop is there to print the sorted array, it iterate through the array beginning by element 0, until it is at the last element of the Array and it print these element.
The for loop does something over and over again.
The first part of the for loop, int i = 0 sets up a variable.
The second part i < SampleArray.length is the 'terminating condition' - it's the condition that has to remain true before each iteration of the loop.
The last part i++ is what happens after each iteration - i gets incremented.
So we are printing each element within SampleArray. i goes between 0 and the one less than the number of elements in the array. (e.g. if the array contained 4 elements, i would be 0 to 3, which is what we want).
And in the body of the loop, the [i] bit selects that element from SampleArray, and that is the value that gets printed on each line.
Another way of looking at it: SampleArray supports the [] operator, which when applied, will return an element from the array.