Java finding the median trouble - java

Having trouble finding the median of from random values. Lets say you enter numbers like 31 62 49 76 56 54 4 7 13 59. The two middle values would be 49 & 54. Since its even, you would take the two values and divide by 2 to come out with the answer 51.5. I am not getting the correct answer and I have tried several different ways.
I feel like to fully understand my program would be way to long to post up here so I created a link to the file here: Click here to view. If you know where I am going wrong with this please let me know.

Acording to Wikipedia:
The median of a finite list of numbers can be found by arranging all the observations from lowest value to highest value and picking the middle one. If there is an even number of observations, then there is no single middle value; the median is then usually defined to be the mean of the two middle values.
So, if you use an array of int's:
public static double median(int[] original) {
int[] array = Arrays.copyOf(original, original.length);
Arrays.sort(array);
int central = array.length / 2;
if (array.length % 2 == 0) {
return (array[central - 1] + array[central]) / 2.0;
}
return array[central];
}

Related

Printing random even value between two values using inheritance

I am trying to print a list of random even numbers (5 times) using a bounds. Example being from 0 to 30 (including both those numbers). This is what I have so far (this is in its own class):
public int nextEven(int h){
int n = rand.nextEven(h) % 2;
return n;
}
This is where it would print from my main method:
System.out.println("Random Even:");
for (int i = 0; i < 5; i++){
System.out.println(rand.nextEven(30));
}
When I run the program it gives me an error and I am not quite sure how to solve this. This is an example of the desired output of even numbers from 0 to 30:
4
26
12
10
20
It isn't clear why taking the remainder of 2 would yield an even number. Instead, generate a number in the range 0 to h / 2 and then multiply the result of that by 2. Like,
public int nextEven(int h){
int n = ThreadLocalRandom.current().nextInt(1 + (h / 2)); // 0 to (h / 2) inclusive
return n * 2; // n * 2 is even (or zero).
}
What exactly is rand? Is it the Random class or an instance of your own class?
Since you want to do something with inheritance I guess you want to overwrite a method, but if rand is an instance of the java Random class this won't work.
The error probably comes from recursively calling nextEven method forever.
If you could clarify what exactly you want to do?
I see at least two solutions.
The first one supposes that random + 1 = random. I mean, that if you add or subtract a random number you still get a valid random number. That's why you can use Random class to generate a value in the desired period and then add or subtract one it the number is odd.
The second approach is just to generate an array of even values for the desired period. Then take a random value from this array.
The mod operator % will give you the remainder of the first value divided by the second.
value % 2
... will return 0 if value is even, or 1 if value is odd.
Since rand is a reference to an instance of the class containing your code, you have an infinite recursion. What you really need is something like:
public int nextEven(int h){
int evenRandomValue;
do {
evenRandomValue = (int)(Math.random() * (h + 1));
} while(evenRandomValue % 2 == 1);
return evenRandomValue;
}
Here is a quite explicit way to achieve this using streams:
List<Integer> myRandomInts = Random.ints(lower, upper + 1)
.filter(i -> i % 2 == 0)
.limit(5).boxed()
.collect(Collectors.toList());
This can be read as 'generate an infinite stream of random numbers between given bounds, filter out odds, take the first 5, turn into Integer objects and then collect into a list.

I want to generate four Different Random Numbers in android But Their total should not be Greater Than the Specified range like 0 to 69

This my Button OnClick() Method on Click of the button All Four random numbers will be Displayed on the Logcat
public void onClick(View v) {
/* the Code for Four Random Numbers*/
final Random random = new Random();
final Set<Integer> mySet = new HashSet<>();
while (mySet.size() < 4) {
mySet.add(random.nextInt(69) + 1);
}
// Now Adding it to the ArrayList
ArrayList<Integer> Elements = new ArrayList<>(mySet);
Log.i("Elements","A:" + Elements.get(0));
Log.i("Elements","B:" + Elements.get(1));
Log.i("Elements","C:" + Elements.get(2));
Log.i("Elements","D:" + Elements.get(3));
}
});
The Output Will be Look Like this (I just give an Example of one case It is Different in every case Whenever I run a App)
A : 11
B : 28
C : 57
D : 1
Now the Problem is :
The sum of all the numbers is greater than the specified range which is 0 to 69
When We Add A,B,C,D values which is equals to 97
Which is greater than the Specified Range 0 to 69
So I Want the Random Numbers in such a way that :
when we Add A,B,C,D the their Sum Should no Exceed the Range that is 69
So My Question is How can i Do That ?
Please Help!! I am Stuck in that part of the Code
and I find no Solution
In addition to what other people have suggested, you might want to read this: find all subsets that sum to a particular value
First, note that this bears some resemblance to the subset sum problem. Given the set of all numbers between 1 and 69, you're looking for a subset of 4 of them that adds up to 69. For any natural number, there are only a finite number of such sets (although it obviously eventually gets computationally infeasible to enumerate all of them). Either way, your answer is guaranteed to be one of these sets regardless of what algorithm you use.
The linked question shows code to find all of the subsets that add up to a particular value. Once you have this, just filter on all the subsets that have length 4 and randomly pick one of them.
There are two ways, depending on how you want to do it:
Rereoll the random numbers until a valid sum is achieved. This will be truly random.
Change the max value for the 2nd, 3rd, 4th, etc random number so that it can't be too big. However this will change it from every number being equally likely to smaller numbers being more likely.
This is a tricky question. These is no mention of a sample space, so one can assume it has to be valid integer of sorts. Generate any number of a number signed 32 bit integer. This would be –2147483648 and 2147483647 until you have four unique ones which sum is between 0 and 69.
Best of luck!
you can use this code :
final Random random = new Random();
final Set<Integer> mySet = new HashSet<>();
int thesum = 0 ;
while (mySet.size() < 4 && thesum< 69) {
int nmbr = random.nextInt(69) + 1 ;
thesum = thesum + nmbr ;
mySet.add(nmbr) ;
}
if( mySet.size() == 3)
{ArrayList<Integer> Elements = new ArrayList<>(mySet);
Log.i("Elements","A:" + Elements.get(0));
Log.i("Elements","B:" + Elements.get(1));
Log.i("Elements","C:" + Elements.get(2));
Log.i("Elements","D:" + Elements.get(3));}

Java - how to divide an integer into 5 random parts

I'm working on an android graphics app, and at some point in the code, I need to divide lets say, a rectangle's width into 5 random sizes.
I have my randomintegerfunction(int min, int max) in my activity, but that can help me divide it into 2 parts.
How do I go about dividing an integer, lets say 100, into 5 random parts, so that the first one or two parts arent always the biggest, then I subdivide for the third, fourth and fifth parts?
Right now, I am know I can try to implememt it using my random integer generator,but the issue, I think is that I'd have to use some forced divisions, like dividing the first 70% of the integer into 2 parts, then dividing the remaining 20% into two parts, to make a total of 5 parts, but such a method would always make the first part be bigger than the fifth part, which I'd like to avoid...to make it truly random.
What I'd like, for example...
the first part to potentially be 7,
second part 25,
third part 5,
fourth part 40,
fifth/last/remaining part 23. To add up to 100 (or any integer).
I am not sure about how to write the logic of such a function...so please if you have any ideas of how to implement a function that randomly divides an integer into 3 or 4 or 5 or 6 truly random sizes/parts, please enlighten me!
Thanks for your time!
You could randomly select from the amount remaining.
int[] nums = new int[5];
int total = 100;
Random rand = new Random();
for (int i = 0; i < nums.length-1; i++) {
nums[i] = rand.nextInt(total);
total -= nums[i];
}
nums[nums.length-1] = total;
Arrays.sort(nums);
This will select a random number and ensure the sum is always the same. The last sort ensures they are in ascending order.
A simple algorithm is to put the numbers 1-99 into a list, shuffle them, and take the first 4 elements as your "split points", i.e. positions at which to divide the number range.
List<Integer> splitPoints =
IntStream.rangeClosed(1, 99)
.boxed().collect(Collectors.toList());
Collections.shuffle(splitPoints);
splitPoints.subList(4, splitPoints.size()).clear();
Collections.sort(splitPoints);
Now, you have 4 randomly-placed split points. The ranges go from:
0 -> splitPoints.get(0)
splitPoints.get(0) -> splitPoints.get(1)
...
splitPoints.get(3) -> 100.
Take four numbers from below range:
4 to n-1
And then divide each number by four .
And fifth number to be n - (sum of other four).
Where n is 100 in the given case..
Again this is one way of implementation and there are hundred of ways to implement it
Hope that helps.
The most efficient way to do this and to keep proper distribution - looks like this.
1) In general cases. You need divide line into N parts.
generate N-1 doubles [0,1], add 0 and 1, and sort them -> x[i] = {0, ..., 1}
N-1 point divide line into N parts -> 0=x[0]..x[1]; x[1]...x[2]; ... x[N]..x[N+1]=1
scale each part to proper size -> len[i] = (x[i+1]-x[i])*total_length
cast to int if needed
2) In case when you need large Objects and small gaps - split you length with desirable proportion, like 70% for objects and 30% for gaps. Or generate it nextDouble(0.2)+0.2 for [0.2,0.4) range for gaps. Then use proposed algorithm twice.

Array Duplicate Efficiency Riddle

Recently in AP Computer Science A, our class recently learned about arrays. Our teacher posed to us a riddle.
Say you have 20 numbers, 10 through 100 inclusive, right? (these numbers are gathered from another file using Scanners)
As each number is read, we must print the number if and only if it is not a duplicate of a number already read. Now, here's the catch. We must use the smallest array possible to solve the problem.
That's the real problem I'm having. All of my solutions require a pretty big array that has 20 slots in it.
I am required to use an array. What would be the smallest array that we could use to solve the problem efficiently?
If anyone could explain the method with pseudocode (or in words) that would be awesome.
In the worst case we have to use an array of length 19.
Why 19? Each unique number has to be remembered in order to sort out duplicates from the following numbers. Since you know that there are 20 numbers incoming, but not more, you don't have to store the last number. Either the 20th number already appeared (then don't do anything), or the 20th number is unique (then print it and exit – no need to save it).
By the way: I wouldn't call an array of length 20 big :)
If your numbers are integers: You have a range from 10 to 100. So you need 91 Bits to store which values have already been read. A Java Long has 64 Bits. So you will need an array of two Longs. Let every Bit (except for the superfluous ones) stand for a number from 10 to 100. Initialize both longs with 0. When a number is read, check if the corresponding bit mapped to the read value is set to 1. If yes, the read number is a duplicate, if no set the bit to 1.
This is the idea behind the BitSet class.
Agree with Socowi. If number of numbers is known and it is equal to N , it is always possible to use N-1 array to store duplicates. Once the last element from the input is received and it is already known that this is the last element, it is not really needed to store this last value in the duplicates array.
Another idea. If your numbers are small and really located in [10:100] diapason, you can use 1 Long number for storing at least 2 small Integers and extract them from Long number using binary AND to extract small integers values back. In this case it is possible to use N/2 array. But it will make searching in this array more complicated and does not save much memory, only number of items in the array will be decreased.
You technically don't need an array, since the input size is fixed, you can just declare 20 variables. But let's say it wasn't fixed.
As other answer says, worst case is indeed 19 slots in the array. But, assuming we are talking about integers here, there is a better case scenario where some numbers form a contiguous interval. In that case, you only have to remember the highest and lowest number, since anything in between is also a duplicate. You can use an array of intervals.
With the range of 10 to 100, the numbers can be spaced apart and you still need an array of 19 intervals, in the worst case. But let's say, that the best case occurs, and all numbers form a contiguous interval, then you only need 1 array slot.
The problem you'd still have to solve is to create an abstraction over an array, that expands itself by 1 when an element is added, so it will use the minimal size necessary. (Similar to ArrayList, but it doubles in size when capacity is reached).
Since an array cannot change size at run time You need a companion variable to count the numbers that are not duplicates and fill the array partially with only those numbers.
Here is a simple code that use companion variable currentsize and fill the array partially.
Alternative you can use arrayList which change size during run time
final int LENGTH = 20;
double[] numbers = new double[LENGTH];
int currentSize = 0;
Scanner in = new Scanner(System.in);
while (in.hasNextDouble()){
if (currentSize < numbers.length){
numbers[currentSize] = in.nextDouble();
currentSize++;
}
}
Edit
Now the currentSize contains those actual numbers that are not duplicates and you did not fill all 20 elements in case you had some duplicates. Of course you need some code to determine whither a numbers is duplicate or not.
My last answer misunderstood what you were needing, but I turned this thing up that does it an int array of 5 elements using bit shifting. Since we know the max number is 100 we can store (Quite messily) four numbers into each index.
Random rand = new Random();
int[] numbers = new int[5];
int curNum;
for (int i = 0; i < 20; i++) {
curNum = rand.nextInt(100);
System.out.println(curNum);
boolean print = true;
for (int x = 0; x < i; x++) {
byte numberToCheck = ((byte) (numbers[(x - (x % 4)) / 4] >>> ((x%4) * 8)));
if (numberToCheck == curNum) {
print = false;
}
}
if (print) {
System.out.println("No Match: " + curNum);
}
int index = ((i - (i % 4)) / 4);
numbers[index] = numbers[index] | (curNum << (((i % 4)) * 8));
}
I use rand to get my ints but you could easily change this to a scanner.

Sorting by least significant digit

I am trying to write a program that accepts an array of five four digit numbers and sorts the array based off the least significant digit. For example if the numbers were 1234, 5432, 4567, and 8978, the array would be sorted first by the last digit so the nest sort would be 5432, 1224, 4597, 8978. Then after it would be 1224, 5432, 8978, 4597. And so on until it is fully sorted.
I have wrote the code for displaying the array and part of it for sorting. I am not sure how to write the equations I need to compare each digit. This is my code for sorting by each digit so far:
public static void sortByDigit(int[] array, int size)
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
}
for(i = 0; i < size; i++)
{
System.out.println(array[i]);
}
}
}
I am not sure what to put in the nested for loop. I think I need to use the modulus.
I just wrote this to separate the digits but I don't know how to swap the numbers or compare them.
int first = array[i]%10;
int second = (array[i]%100)/10;
int third = (array[i]%1000)/10;
int fourth = (array[i]%10000)/10;
Would this would go in the for loop?
It seems like your problem is mainly just getting the value of a digit at a certain index. Once you can do that, you should be able to formulate a solution.
Your hunch that you need modulus is absolutely correct. The modulo operator (%) returns the remainder on a given division operation. This means that saying 10 % 2 would equal 0, as there is no remainder. 10 % 3, however, would yield 1, as the remainder is one.
Given that quick background on modulus, we just need to figure out how to make a method that can grab a digit. Let's start with a general signature:
public int getValueAtIdx(int value, int idx){
}
So, if we call getValueAtIdx(145, 2), it should return 1 (assuming that the index starts at the least significant digit). If we call getValueAtIdx(562354, 3), it should return 2. You get the idea.
Alright, so let's start by using figuring out how to do this on a simple case. Let's say we call getValueAtIdx(27, 0). Using modulus, we should be able to grab that 7. Our equation is 27 % x = 7, and we just need to determine x. So 27 divided by what will give us a remainder of 7? 10, of course! That makes our equation 27 % 10 = 7.
Now that's all find and dandy, but how does 10 relate to 0? Well, let's try and grab the value at index 1 this time (2), and see if we can't figure it out. With what we did last time, we should have something like 27 % x = 27 (WARNING: There is a rabbit-hole here where you could think x should be 5, but upon further examination it can be found that only works in this case). What if we take the 10 we used earlier, but square it (index+1)? That would give us 27 % 100 = 27. Then all we have to do is divide by 10 and we're good.
So what would that look like in the function we are making?
public int getValueAtIdx(int value, int idx){
int modDivisor = (int) Math.pow(10, (idx+1));
int remainder = value % modDivisor;
int digit = remainder / (modDivisor / 10);
return digit;
}
Ok, so let's to back to the more complicated example: getValueAtIdx(562354, 3).
In the first step, modDivisor becomes 10^4, which equals 10000.
In the second step, remainder is set to 562354 % 10000, which equals 2354.
In the third and final step, digit is set to remainder / (10000 / 10). Breaking that down, we get remainder / 1000, which (using integer division) is equal to 2.
Our final step is return the digit we have acquired.
EDIT: As for the sort logic itself, you may want to look here for a good idea.
The general process is to compare the two digits, and if they are equal move on to their next digit. If they are not equal, put them in the bucket and move on.

Categories