Removing duplicates scale up error - java

I am trying to remove duplicates from an array. What I have works on an array size of 10([11]). Then i had to scale it up to 5000([5001]). I thought this would be very simple. It compiles but when I run it it runs an infinite loop. I'm not sure if it's just taking a long time or something doesn't work.
The sort.sorting works.
public class work_on_it5
{
public static void main(String [] args)
{
int array [] = new int [5001];
int LB = 1;//declare the lower bound
int UB = 5000;//declare the upper bound
for(int x = 0; x < 4999; x++)
{
if(array[x]==array[x+1])
{
array[x+1] = (int)(Math.random()*50) + 1;
sort.sorting(array);
x=0;
}
}
sort.sorting(array);
for(int x = 0; x < 4999; x++)
{
System.out.println(array[x]);
}
//median(LB, UB, array);
//mean(array);
}

The reason for infinite loop is because you are setting x=0;
for(int x = 0; x < 4999; x++)
{
if(array[x]==array[x+1])
{
array[x+1] = (int)(Math.random()*50) + 1;
sort.sorting(array);
x=0; //Here you are setting the value of x which is never changed resulting in infinite loop
}
}
in your for loop
So every time when it enters in the for loop the value of the x is equal to 0.
Also the declaration
int array [] = new int [5001];
so all the elements of the array will have the default value as 0 so the condition if(array[x]==array[x+1]) will always be true and then the above scenario that x is always 0 will cause the problem. Change the logic!
On a side note:-
It is better to use array.length instead of hard coding the length of array in for loop.

Why infinite loop happens:
1 You declare an int array as follows:
int array [] = new int [5001];
each element has a defalut value of 0.
2 in the for-loop, if(array[x]==array[x+1]) will always TRUE. and then x = 0
for(int x = 0; x < 4999; x++)
{
if(array[x]==array[x+1])
{
array[x+1] = (int)(Math.random()*50) + 1;
Arrays.sort(array);
x=0;
}
}
As a result, the program always compare the first 2 elements only.
Compare array[0] and array[1], they are equal.
Reset x = 0
Compare array[0] and array[1], they are equal.
Reset x = 0
Compare array[0] and array[1], they are equal.
Reset x = 0
... ...
This causes infinite loop. Make some change and go ahead. :)

Related

How to print only the last element of an array?

I am trying to print the last element of my array. The code can be seen below:
double [] results = new double[21];
double t = 9600;
for(int y = 0; y < 21; y++) {
results[y] = t;
t *= 1.04;
System.out.println(results[results.length - 1]);
}
However, when I attempt to run this, I get this result:
0.0 (printed 20 times in a row)
...
21034.782173120842
I do not know why it is printing out 20 zero's, and then the answer I want (21034.78). I thought that by doing results[results.length - 1], only the last element of the array would be printed. I have a suspicion that this has to do with the loop, but I do not know why or how to fix it.
Any help or advice would be greatly appreciated. Thank you!
You need to put the System.out.println outside the for loop, or else you will always print 0.0 because the last index of the array isn't filled yet.
double [] results = new double[21];
double t = 9600;
for(int y = 0; y < 21; y++) {
results[y] = t;
t *= 1.04;
}
System.out.println(results[results.length - 1]);
Output: 21034.782173120842
put your System.out.println , out of loop.
for(int y = 0; y < 21; y++) {
** YOUR LOGIC **
}
System.out.println(results[results.length - 1]);
You need to move the print statement outside the loop..
double [] results = new double[21]; double t = 9600;
for(int y = 0; y < 21; y++) {
results[y] = t;
t *= 1.04;
}
System.out.println(results[results.length - 1]);
You need to make a slight alteration. Here is one thing that you can do:
double [] results = new double[21];
double t = 9600;
for(int y = 0; y < results.length; y++) {
results[y] = t;
t *= 1.04;
System.out.println(results[y]);
}
You can print the current index [y] each time through the loop. Or else you're always printing index 21 which isn't filled yet and will repeatedly print 0 until it is filled. The current iteration of the loop [y] will always be the last index that actually has a value in it, but the last index won't actually be filled with a value until your last iteration through the loop which explains your error here.

2D array being reset to it's original values

I am working on a sudoku game and I am using the method of creating a solved puzzle and then "digging holes" to get the puzzle that is displayed to the user. For some reason, the testingPuzzle array is being reset to the numbers array every time it goes through the loop. It is true that the testingPuzzle array should be set to the numbers array originally, but it should be edited one spot at a time every time it goes through the loop and have a bunch of zeroes in it after a few iterations. Here is the loop itself:
do{
x = Math.abs(rand.nextInt() % 9);
y = Math.abs(rand.nextInt() % 9);
takeaway_num = testingPuzzle[x][y];
testingPuzzle[x][y] = 0;
} while (arraysEqual(solvePuzzle(testingPuzzle), numbers));
SolvePuzzle is a method that solves the given puzzle as parameters and returns that solved puzzle. So basically arraysEqual(solvePuzzle(testingPuzzle), numbers)checks to see if testingPuzzle is solvable
I am setting the testingPuzzle array equal to the numbers array before the do while loop. It looks like this:
int[][] testingPuzzle = new int[9][9];
for(int y = 0; y < 9; y++){
for(int x = 0; x < 9; x++){
testingPuzzle[x][y] = numbers[x][y];
}
}
Just so you know numbers is the sodoku answer that was generated in a previous method.
I am using my own method for testing if the arrays are equal, called "arraysEqual because I thought .equals() was the problem originally. Here is the method I am using for this:
private static boolean arraysEqual(int[][] a, int[][] b){
for(int y = 0; y < 9; y++){
for(int x = 0; x < 9; x++){
if(a[x][y] != b[x][y]){
return false;
}
}
}
return true;
}
I'm not really sure why the testingPuzzle Array is being set to the same as the numbers array at the end of each loop. I think it could have something to do with passing the actual array vs. a copy of it to a method that takes in an array but I'm not sure how that works in java.

Arrays and enhanced for loops?

Can someone please explain what is going on in this method?
class test{
public static void main(String args[])
{
int[] x = new int[4];
int[] xy = new int[4];
//System.out.println(xy[0]);
for(int j : x) {
xy[j] += 1;
}
System.out.println(xy[0]); }}
So I thought that the enhanced for loop would be doing this
/**for(int j=0; j < x.length(); j++)
xy[j=0] = 1
xy[j=1]=1
xy[j=2]=1
xy[j=3]=1*/
but from what I've been reading, the enhanced for loop is doing for(int element:array). Still, I don't understand what the for loop in my method is actually doing. I have tried System.out.println() statements to check what was being put into the array xy, but it is either addresses or 0.
Thanks for all the help and apologizes if this is confusing.
For Each loop that you have used in here does assign j a value that is already assigned to array x (which in your case is 0 ).
As according to your case of x and xy array:-
x[0]=0; xy[0]=0
x[1]=0; xy[0]=0
x[2]=0; xy[0]=0
x[3]=0; xy[0]=0
Describing for each loop according to your program case:-
for(j : x)
This implies it will run for 4 times which is the length of your array x.
when running first time the following process will happen
j=x[0] (so j=0 coz x[0] according to your case)
xy[0]=xy[0]+1 (so now xy[0] value becomes 1)
Similarly
for the second run of for each
j=x[1] (so j=0 coz x[0] according to your case)
xy[0]=xy[0]+1 (so now xy[0] value becomes 2 as in previous for each run xy[0]=1)
So all in all finally you will have xy[0]=4 at the end of 4th run of for each loop.
Finally the print statement will print 4.
int[] x = new int[4];
This creates an array of 4 elements. Each element's value is 0.
for(int j : x) {
xy[j] += 1;
}
This iterates through all the values of x. At each iteration, j is the next element in x, but since all elements are initialized to 0, j is always 0. So, the 4 iterations increment xy[0].
Here in the advanced for loop, the int j does not represent the index. Rather it represents the values in the xy[] array. It is not possible to get the index of advanced for loop. If you want index, then you might have to use ordinary for loop.
Ex. If you have
xy[]={5,8,3,4};
for(int j:xy)
{
println(j);
}
then the output would be
5
8
3
4
It should be straight-forward to find out, if you trace through using debugger.
In brief, it is getting each value in x, and use the value as index to increment corresponding value in xy.
It will be more obvious if you initialize both array with meaningful values:
int[] x = {1,1,3,3}
int[] xy = new int[4]; // initialized to 0 by default
after your piece of code, you will find xy containing {0,2,0,2}.
You should understand how enhanced-for-loop is expanded for array:
for (T v : arr) {
// do something
}
is transformed to
for (int i = 0; i < arr.length; ++i) {
T v = arr[i];
// do something
}
Obviously your understanding on how enhanced for loop being expanded is wrong.
In your case you need only for-loop and not enhanced for-loop:
for(int j = 0 ; x.length > j; j ++) {
xy[j] += 1;
}
Problem with your code is that your loop traverse only at index 0 of xy hence you get xy as [4, 0, 0, 0]
int[] x = new int[4];//default values [0, 0, 0, 0]
int[] xy = new int[4]; //default values [0, 0, 0, 0]
for(int j : x) { // j is always 0
xy[j] += 1;// xy[0] += 1
}
You can use the for-loop instead:
for(int i = 0 ; x.length > i; i ++) {
xy[i] += 1;
}
If you want to still use for each then here is the example
a[]={1,2,3,4};
for(int i:a)
{
println(i);
}
Hope it helps!

Comparing adjacement array elements

I'm trying to work out the difference in adjacent pairs of array elements, and then add the differences together, this is the method I'm using to do this.
I'm trying to split the original array into two smaller arrays and then subtract elements of the smaller arrays which will indirectly workout the difference of my initial array. the diffrences get stored on a last array which adds my differences together....
public static int changeinx(int array1[],int sum) {
int n = array1.length;
int y[];
int u[];
int c[];
c = new int [n/2];
y = new int [n/2]; // no. of arrays equal to 1/2 of array1, since two elements subtracted.
u = new int [n/2];
for(int i = 0 ; i < n ; i += 2 ) {
y[i] = array1[i];
}
for(int i = 1 ; i < n ; i += 2) {
u[i] = array1[i];
}
for(int i = 0 ; i < n/2 ; i++ ) {
c[i] = Math.abs( u[i] - y[i] ) ;
}
for(int r = 0 ; r < c.length ; r++ ) {
sum = sum + c[r]; //adding all the differences up, since abs has been taken
}
return sum ;
}
Why is this not working? :(
I find a major flaw in this loop:
for(int i = 0 ; i < n ; i++) {
int x = array1[i] - array1[i+1] ;
Let me give an example to illustrate this further, say we have an array
array1 = 25 15 55 12
the above loop at first iteration would do 25-15
in the 2nd iteration do 15-55
and 3rd iteration do 55-12
So now running this loop on an array of 4 elements would yield an array with 3 elements not at all conforming to your n/2 formula.
From my understanding of your problem I think your intention is to do 25-15 in the first loop
55-12 in the 2nd loop and end it, as to how you would go about doing it I leave it to you to figure out
This loop never ends:
for(int p = 0 ; p < n ; i++ ) {
y[p] = Math.abs(x); //trying to the difference as x, and asign to array y[]
}
Since p and n never change during the loop, if p < n is not true when the loop starts, it will never be true, and the loop will never end.
I'm trying to work out the difference in adjacent pairs of array elements, and then add the differences together, this is the method I'm using to do this.
If I understood the problem description correctly, this can be implemented much simpler:
public static int changeinx(int[] arr) {
int sumOfDiffs = 0;
for (int i = 0; i < arr.length - 1; i++) {
sumOfDiffs += Math.abs(arr[i] - arr[i + 1]);
}
return sumOfDiffs;
}

Where does this program get its numbers from, and why is this caused by increasing 1 array size? (Java)

This program simply is supposed to eliminate duplicates from an array. However, the second for loop in the eliminate method was throwing an out of bounds exception. I was looking and couldnt see how that could be, so I figured I would increase the array size by 1 so that I would get it to work with the only downside being an extra 0 tacked onto the end.
To my surprise, when I increased tracker[]'s size from 10 to 11, the program prints out every number from 0 to 9 even if I dont imput most of those numbers. Where do those numbers come from, and why am I having this problem?
import java.util.*;
class nodupes
{
public static void main(String[] args)
{
int[] dataset = new int[10];
//getting the numbers
for (int i = 0; i <= 9 ; i++)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter a one digit number");
dataset[i] = input.nextInt();
}
int[] answer = (eliminateduplicates(dataset));
System.out.println(Arrays.toString(answer));
}
public static int[] eliminateduplicates(int[] numbers)
{
boolean[] tracker = new boolean[11];
int arraysize = 1;
for(int k = 0; k <= 9; k++)
{
if(tracker[numbers[k]] == false)
{
arraysize++;
tracker[numbers[k]] = true;
}
}
int[] singles = new int[arraysize];
for(int l = 0; l <= arraysize; l++)
{
if(tracker[l] == true)
{
singles[l] = l;
}
}
return singles;
}
}
The exception was occuring at this part
if(tracker[l] == true)
but only when trackers size was 10. At 11 it just prints [0,1,2,3,4,5,6,7,8,9]
EDIT: The arraysize = 1 was a hold over from debugging, originally it was at 0
EDIT: Fixed it up, but now there is a 0 at the end, even though the array should be getting completely filled.
public static int[] eliminateduplicates(int[] numbers)
{
boolean[] tracker = new boolean[10];
int arraysize = 0;
for(int k = 0; k < numbers.length; k++)
{
if(tracker[numbers[k]] == false)
{
arraysize++;
tracker[numbers[k]] = true;
}
}
int[] singles = new int[arraysize];
int counter = 0;
for(int l = 0; l < arraysize; l++)
{
if(tracker[l] == true)
{
singles[counter] = l;
counter++;
}
}
return singles;
}
Since arrays start at 0, your arraysize will be one larger than the number of unique numbers, so your final loop goes through one too many times. In other words "l" (letter l -- try using a different variable name) will get to 11 if you have 10 unique numbers and tracker only has item 0-10, thus an out of bounds exception. Try changing the declaration to
int arraysize = 0;
Once again defeated by <=
for(int l = 0; l <= arraysize; l++)
An array size of 10 means 0-9, this loop will go 0-10
For where the numbers are coming from,
singles[l] = l;
is assigning the count values into singles fields, so singles[1] is assigned 1, etc.
Edit like 20 because I should really be asleep. Realizing I probably just did your homework for you so I removed the code.
arraySize should start at 0, because you start with no numbers and begin to add to this size as you find duplicates. Assuming there was only 1 number repeated ten times, you would've created an array of size 2 to store 1 number. int arraysize = 0;
Your first for loop should loop through numbers, so it makes sense to use the length of numbers in the loop constraint. for( int i = 0; i < numbers.length; i ++)
For the second for loop: you need to traverse the entire tracker array, so might as well use the length for that (tracker.length). Fewer magic numbers is always a good thing. You also need another variables to keep track of your place in the singles array. If numbers was an array of 10 9s, then only tracker[9] would be true, but this should be placed in singles[0]. Again, bad job from me of explaining but it's hard without diagrams.
Derp derp, I feel like being nice/going to bed, so voila, the code I used (it worked the one time I tried to test it):
public static int[] eliminateduplicates(int[] numbers)
{
boolean[] tracker = new boolean[10];
int arraysize = 0;
for(int k = 0; k < numbers.length; k++)
{
if(tracker[numbers[k]] == false)
{
arraysize++;
tracker[numbers[k]] = true;
}
}
int[] singles = new int[arraysize];
for(int l = 0, count = 0; l < tracker.length; l++)
{
if(tracker[l] == true)
{
singles[count++] = l;
}
}
return singles;
}
I feel you are doing too much of processing for getting a no duplicate, if you dont have the restriction of not using Collections then you can try this
public class NoDupes {
public static void main(String[] args) {
Integer[] dataset = new Integer[10];
for (int i = 0; i < 10; i++) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a one digit number");
dataset[i] = input.nextInt();
}
Integer[] arr = eliminateduplicates(dataset);
for (Integer integer : arr) {
System.out.println(integer);
}
}
public static Integer[] eliminateduplicates(Integer[] numbers) {
return new HashSet<Integer>(Arrays.asList(numbers)).toArray(new Integer[]{});
}
}
To answer your question your final loop is going one index more than the size.
The range of valid indexes in an array in Java is [0, SIZE), ie. from 0 up to arraysize-1.
The reason you're getting the exception is because in your loop you're iterating from 0 to arraysize inclusively, 1 index too far:
for(int l = 0; l <= arraysize; l++)
Therefore when you get to if(tracker[l] == true) in the last iteration, l will equal arraysize and tracker[l] will be outside the bounds of the array. You can easily fix this by changing <= to < in your for loop condition.
The reason that the problem goes away when the size of your array is changed from 10 to 11 has to do with arraysize being incremented up to 10 in the for loop above the one causing the problems. This time, singles[10] is a valid element in the array since the range of indexes in your array is now [0, 11).
EDIT: Actually arraysize has the potential to be incremented to 11, I thought it was initialised to 0 in which case it would only get to 10. Either way the above is still valid; the last index you try and access in your array must be 1 less than the length of your array in order to avoid the exception you're getting, since arrays are zero-based. So yeah, long story short, <= should be <.

Categories