Java Sorting Even and Odd Numbers - java

I'm in a high school programming class right now and my instructions were to create a program that stores the random numbers in an array that's sorted by even and then odd numbers. Here's my code so far, I have no idea why it's not working. It keeps printing out 0's even though I'm supposed to generate numbers above 1. Help would be greatly appreciated, thanks! :D
Random rnd = new Random();
int randomNumArray[] = new int[10];
int evenArray[] = new int[10];
int oddArray[] = new int[10];
int countEven = 0,countOdd = 0;
for (int i = 0; i < randomNumArray.length; i++)
{
randomNumArray[i] = rnd.nextInt(100) + 1;
System.out.println(randomNumArray[i]);
if (randomNumArray[i] % 2 == 0)
{
evenArray[i] = randomNumArray[i];
countEven++;
}
else if (randomNumArray[i] % 2 == 1)
{
oddArray[i] = randomNumArray[i];
countOdd++;
}
}
for (int i = 0; i < countEven; i++)
{
System.out.println(evenArray[i]);
}
for (int i = 0; i < countOdd; i++)
{
System.out.println(oddArray[i]);
}

The problem is you are storing the values in evenArray and oddArray at index i, which is not necessarily the "next unused space" in the array you're writing to. Let's say the first number (when i = 0) is even and the second (when i = 1) is odd; when the second number is stored by oddArray[i] = randomNumArray[i];, it will be stored at index 1, but it is the first odd number so it should be in oddArray at index 0 instead.
To solve this, you can use countEven and countOdd as the correct indices to write to; for example, when countOdd is 0 then there are no odd numbers yet, so index 0 is the correct place to write the first one. So you can change these two lines:
if (randomNumArray[i] % 2 == 0)
{
// changed here
evenArray[countEven] = randomNumArray[i];
countEven++;
}
else if (randomNumArray[i] % 2 == 1)
{
// changed here
oddArray[countOdd] = randomNumArray[i];
countOdd++;
}

You should change these lines
evenArray[countEven] = randomNumArray[i];
oddArray[countOdd] = randomNumArray[i];
... instead of
evenArray[i] = randomNumArray[i];
oddArray[i] = randomNumArray[i];

Related

How to randomly generate integers between 0 to 3 without making them consecutive in Java?

So far I have managed to generate random numbers using Random.
for(int i=0; i<10; i++){
prevnum = num;
num = random.nextInt(4);
num = num==prevnum?ran.nextInt(4):num;
System.out.println("random number: " + num);
}
I do not want consecutive repeats, what should I do?
EDIT/SOLUTION:
I solved the issue using this workaround.
By checking if it was running for the first time to avoid nullpointerexception.
And the just used an ArrayList to remove any chances of repitition by removing the previous randomly generated number from the small pool/range.
public void printRandom(){
for(int i=0; i<10; i++){
if(firstrun){
firstrun=false;
num = random.nextInt(4);
System.out.println(num);
} else{
num = getRandom(num);
System.out.println(num);
}
}
}
int getRandom(int prevNum){
ArrayList choices = new ArrayList(Arrays.asList(0, 1, 2, 3));
choices.remove(prevNum);
return (int) choices.get(random.nextInt(3));
}
You better to get a random number until it would be different with the last number, not just once, in other words repeat this condition:
num = num==prevnum?ran.nextInt(4):num;
like:
do {
num = num==prevnum?ran.nextInt(4):num;
while (num != prevnum);
because your numbers are few, they might be the same, so check it more than once if it is needed.
Try this
Random ran = new Random();
int cur, pre = ran.nextInt(4);
for (int i = 0; i < 10; i++) {
cur = ran.nextInt(4);
while (cur == pre) {
cur = ran.nextInt(4);
}
pre = cur;
System.out.println(cur);
}
If you do not want a consecutive repeat, then you always want the gap between two consecutive numbers to be non-zero. That you suggests you pick your first number normally, and from that point on you pick a random, but non-zero, gap. Add the gap to the previous number to get the next number, which will always be different.
Some pseudocode:
// First random number.
currentNum <- random(4);
print(currentNum);
// The rest of the random numbers.
repeat
gap <- 1 + random(3);
currentNum <- (currentNum + gap) MOD 4;
print(currentNum);
until enough numbers;

Shuffle a specific number of strings in a String Array in Java

I have a long textfile and I need to shuffle all the words which are longer than 4 letters but the other words need to remain in the same place. This without using the Collections module.
I can manage to shuffle all the strings in the array, but I cant figure out for the life of me how to shuffle only a part.
public static String[] getScramble(String text) {
Random rgen=new Random();
String[] textArray=text.split(" ");
for(int i=0;i<textArray.length;i++){
int randPos=rgen.nextInt(textArray.length);
String temp=textArray[i];
if (textArray[i].length()>4){
textArray[i]=textArray[randPos];
textArray[randPos]=temp;
}else{
textArray[i]=textArray[i];
}
}
return textArray;
Thanks!
You only swap two words if both are larger than 4 characters, otherwise you keep them in the original position:
for(int i = 0; i < textArray.length; i++) {
int randPos = rgen.nextInt(textArray.length);
if (textArray[i].length() > 4 && textArray[randPos].length() > 4){
String temp = textArray[i];
textArray[i]=textArray[randPos];
textArray[randPos]=temp;
}
}
EDIT: if the number of long words is very small compared to the number of short words, this loop may behave badly (since it will fail to swap most of the long words), so you can improve it as follows:
for(int i=0;i<textArray.length;i++){
if (textArray[i].length() > 4) {
// find a long word to swap textArray[i] with
int randPos=rgen.nextInt(textArray.length);
while (textArray[randPos].length() <= 4){
randPos=rgen.nextInt(textArray.length);
}
// swap the two long words
String temp=textArray[i];
textArray[i]=textArray[randPos];
textArray[randPos]=temp;
}
}
When generating the random position for a word that is longer than 4 characters, you check to see if the new position also has a word with more than 4 characters. If not, you keep generating a new random position until you find one that works.
public static String[] getScramble(String text) {
Random rgen = new Random();
String[] textArray = text.split(" ");
for (int i = 0; i < textArray.length; i++) {
if( textArray[i].length() > 4) {
String temp = textArray[i];
int randPos = rgen.nextInt(textArray.length);
while( textArray[randPos].length() <= 4 ){
randPos = rgen.nextInt(textArray.length);
}
textArray[i] = textArray[randPos];
textArray[randPos] = temp;
}
}
return textArray;
}
A situation that might arise is if you have only one word with more than 4 characters, which means it's pointless to even try to randomize them, and you might waste a lot of time generating random positions to no avail. To optimize this, you can first check if you have less than 2 long words, and if so you don't need to do anything.
int longWordCount = 0;
for (int i = 0; i < textArray.length; i++) {
if( textArray[i].length() > 4 )
longWordCount++;
if( longWordCount == 2 )
break;
}
if( longWordCount > 1 ) {
for (int i = 0; i < textArray.length; i++) {
if (textArray[i].length() > 4) {
String temp = textArray[i];
int randPos = rgen.nextInt(textArray.length);
while (textArray[randPos].length() <= 4) {
randPos = rgen.nextInt(textArray.length);
}
textArray[i] = textArray[randPos];
textArray[randPos] = temp;
}
}
}
Here's a version that adapts Durstenfeld's algorithm. Note that ThreadLocalRandom is preferable to Random.
public static String[] getScramble(String text) {
ThreadLocalRandom rgen = ThreadLocalRandom.current();
String[] textArray = text.split(" ");
int[] indices = IntStream.range(0, textArray.length)
.filter(i -> textArray[i].length() > 4)
.toArray();
for (int i = indices.length; i > 1; --i) {
int j = indices[rgen.nextInt(i)];
int k = indices[i - 1];
if (j != k) {
String tmp = textArray[j];
textArray[j] = textArray[k];
textArray[k] = tmp;
}
}
return textArray;
}
The OP didn't say that Streams couldn't be used, only Collections. If that's a problem, one can replace the initialization of indices with a simple loop to initialize an array of int of the same size as textArray, using the variable i to keep track of the number of indices entered (so it would be declared and initialized before the main for loop).

Calculate the largest best combination of denominations for a number

Problem Statement:
I need to get the best combination of denomination for a given number.
Example: I have three denominations {50,25,10} and given number is 30 then list should return <10,10,10>. for number 80 it should return <50,10,10,10> as remaining 30 is not completely divide by 25.
For 35 it should return <25,10>
for 75 <50,25>
for 65 <50,10>
This is somewhat similar to coin problem but I am not able to get the values of denominations.
Refence StackOverFlow Coin change DP solution to keep track of coins
Here is what I have tried so far :
public static int[] minChange(int[] denom, int changeAmount) {
int n = denom.length;
int[] count = new int[changeAmount + 1];
int[] from = new int[changeAmount + 1];
count[0] = 1;
for (int i = 0; i < changeAmount; i++ )
if (count[i] > 0)
for (int j = 0; j < n; j++ ) {
int p = i + denom[j];
if (p <= changeAmount) {
if (count[p] == 0 || count[p] > count[i] + 1) {
count[p] = count[i] + 1;
from[p] = j;
}
}
}
// No solutions:
if (count[changeAmount] == 0)
return null;
// Build answer.
int[] result = new int[count[changeAmount] - 1];
int k = changeAmount;
while (k > 0) {
result[count[k] - 2] = denom[from[k]];
k = k - denom[from[k]];
}
return result;
}
This works well if value are completely divisible by one of denomination other wise i doesn't work at all.
Once you have the solution in the 2D array for the dynamic programming solution, you can find out what denominations were optimal by backtracking through your array from the end (arr[n][n]).

Generate random numbers without duplicates using arrays only

I want to fill an array of size X with random integers from 0 to X with no duplicates. The catch is I must only use arrays to store the collections of int, no ArrayLists. How do I go about implementing this?
I don't understand why I can't seem to get this. But this is my most recent bit of code that fills the list but allows for duplicates.
System.out.print("Zero up to but excluding ");
int limit = scanner.nextInt();
// create index the size of the limit
int [] index = new int[limit];
for(int fill=0;fill<limit;fill+=1){
index[fill] = (limit);
}
int randomNumber = 0;
Random rand = new Random();
int [] randoms = new int[limit];
boolean flag = true;
// CODE TO NOT PRINT DOUBLES
for (int z=0;z<limit;z+=1){
randomNumber = rand.nextInt(limit);
int i=0;
while (i<limit){
if (index[i] == randomNumber){
flag = true;
}
else {
flag = false;
break;
}
i+=1;
}
if (flag == false){
randoms[z] = randomNumber;
index[z] = randomNumber;
}
}
System.out.println("Randoms: "+java.util.Arrays.toString(randoms));
Here's one way to do it:
Create an array of length N
Fill it from 0 to N-1
Run a for loop and swap randomly 2 indices
Code:
// Step 1
int N = 10;
int[] array = new int[N];
// Step 2
for(int i=0; i < N; i++)
array[i] = i;
// Step 3
for(int i=0; i < N; i++) {
int randIndex = (int) (Math.random() * N);
int tmp = array[i];
array[i] = array[randIndex];
array[randIndex] = tmp;
}
Why not rephrase the problem to shuffling an array of integers. First fill the array monotonically with the numbers 0 to X. Then use the Random() function to select one of the X numbers to exchange with the number in position 0. Repeat as many times as you may like. Done.
Here is your bug:
while (i<limit){
if (index[i] == randomNumber){
flag = true;
}
else {flag = false;break;} <--- rest of the array is skipped
i+=1;
}
after you generated a new number, you start to check for equality , however once you find that randomNumber!=index[i] (else statement) you break out of the while. look this: actual array is 3,4,5,1 your new number is 5, you compare it to 3 just to find out that they different so flag is set to false and break out happens.
Consider using another array filled with elements in order from 0 to X. Then, with this array, shuffle the elements around. How do you go about this? Use a loop to traverse through every single element of the array, and for each iteration, choose a random number from 0 to array.length - 1 and switch the elements at the index you're currently on and the random index. This is how it would look like,
In your main, you would have an array initialized by doing this,
int[] arr = new int[10];//10 can be interchangeable with any other number
for(int i = 0; i < arr.length; i++){
arr[i] = i;
}
shuffleArray(arr);
And the shuffle method would look like this,
public int[] shuffleArray(int[] arr){
Random rand = new Random();
for(int i = 0; i < arr.length; i++){
int r = rand.nextInt(arr.length);//generate a random number from 0 to X
int k = arr[i];
arr[i] = arr[r];
arr[r] = k;
}
}

Java lotto simulation

I am writing a program simulating a lotto draw of six numbers between 1 and 45, a sample output is 3 7 12 27 43 28. But what I am trying to do is count the number of times adjacent numbers appear, for example 1 4 5 29 26 41 is a positive answer because 5 comes after 4.
What is the best way of doing that?
I have tried examples such as :
int adjacent=0;
for(int i =0; i<6; i++)
{
int t = test[i]+1;
test[i]=(int)(45*Math.random())+1;
if(test[i]==t)
adjacent++;
System.out.print(test[i]+" ");
}
This does not work.
What am I doing wrong?
I think you just have an order of operations problem
int adjacent=0;
for(int i =0; i<6; i++)
{
//test[i] hasn't been set yet
int t = test[i]+1;
test[i]=(int)(45*Math.random())+1;
//this comparison doesn't make a whole lot of sense
if(test[i]==t)
adjacent++;
System.out.print(test[i]+" ");
}
Change it around to something like this:
int adjacent=0;
for(int i =0; i<6; i++)
{
test[i]=(int)(45*Math.random())+1;
int t = -1;
//Make sure this comparison only happens after the second iteration
//to avoid index out of bounds
if ( i != 0 )
{
//Set t to the last number + 1 instead of trying to predict the future
t = test[i-1] + 1;
}
//Now this comparison makes a little more sense
//The first iteration will compare to -1 which will always be false
if(test[i]==t)
adjacent++;
System.out.print(test[i]+" ");
}
This can be further simplified to just this:
int adjacent=0;
for(int i =0; i<6; i++)
{
test[i]=(int)(45*Math.random())+1;
if(i != 0 && test[i]==(test[i-1]+1))
adjacent++;
System.out.print(test[i]+" ");
}
After you generate your 6 numbers and put them into an array. Use Arrays.sort(). You can then compare adjacent array entries.
You should also avoid using Random to generate you 6 numbers, because it can generate duplicates. This may or may not accurately simulate your lotto draw. Quoi's answer has a good suggestion for this.
I think you should shuffle it and take any five. Collections#Shuffle would help you, It permutes the specified list using a default source of randomness. All permutations occur with approximately equal likelihood.
List<Integer> list = ArrayList<Integer>();
list.add(1);
list.add(2);
Collections.shuffle(list);
Random rnd = new Random();
Integer[] result = new Integer[5];
result[0] = list.get(rnd.getNextInt(45));
result[1] = list.get(rnd.getNextInt(45));
result[2] = list.get(rnd.getNextInt(45));
result[3] = list.get(rnd.getNextInt(45));
result[4] = list.get(rnd.getNextInt(45));
It always gives you random values, then you should sort it to arrange it in order, say ascending.
Arrays.sort(result);
now you can write a loop to find out adjacent number.
int adjacent = 0;
for(int i=1; i<result.length;i++){
int prev = result[i-1];
int now = result[i];
if(prev+1 == now)
adjacent++;
}
You need to separate the generation of unique (hence the HashSet below to insure identity) random selections, sorting them, and then determining adjacency:
import java.util.HashSet;
import java.util.Arrays;
public class Lotto
{
public Lotto()
{
}
/**
* #param args
*/
public static void main(String[] args)
{
Lotto lotto = new Lotto();
lotto.randomizeSelections(5);
}
private void randomizeSelections(int numOfArrays)
{
for(int i = 0; i < numOfArrays; i++)
{
int[] selArry = new int[6];
//to insure that each random selection is unique
HashSet<Integer> idntySet = new HashSet<Integer>();
for(int j = 0; j < 6;)
{
int rndm = (int)(45 * Math.random()) + 1;
//add selection to the array only if it has not been randomized before
if(!idntySet.contains(rndm))
{
selArry[j] = rndm;
j++;
}
}
//sort the array for determing adjacency
Arrays.sort(selArry);
for(int j = 0; j < 6; j++)
{
int sel = selArry[j];
boolean isAdjcnt = (j > 0 && (sel == selArry[j - 1] + 1)) ? true : false;
System.out.println(i + "." + j + ".random = " + sel);
if(isAdjcnt) System.out.println("\tAdjacent");
}
}
}
}

Categories