I got this simple code and I want to simplify the comparsion with array in while loop
int[] numbers = new int[7];
Random rand = new Random();
for(int i = 0; i < 7; i++) {
int number = rand.nextInt(46);
while(number == numbers[0] || number == numbers[1] || number == numbers[2] || number == numbers[3] ||
number == numbers[4] || number == numbers[5] || number == numbers[6]) {
number = rand.nextInt();
}
numbers[i] = number;
}
for(int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
I want to find a way to simplify this part:
while(number == numbers[0] || number == numbers[1] || number == numbers[2] || number == numbers[3] ||
number == numbers[4] || number == numbers[5] || number == numbers[6])
How can I do that?
A simple solution to this would be to use Java 8 streams.
With streams it looks like this:
int[] numbers = new Random().ints(1, 46).distinct().limit(6).toArray();
Thanks Elliot, I failed to recognice that the number 0 would not be choosen as all ints are 0 at the beginning.
You could use a IntStream to test if any number from numbers doesn't match, and only increment when it does. Something like,
for (int i = 0; i < 7;) {
final int number = rand.nextInt(46);
if (IntStream.of(numbers).anyMatch(x -> x != number)) {
numbers[i] = number;
i++;
}
}
If your condition is complex just create a separate method which returns true or false, like that
public boolean isNumberInArray(int[] array, int number) {
for (int i = 0; i < array.length; i++) {
if (array[i] == number) {
return true;
}
}
return false;
}
while(isNumberInArray(numbers, number)) {
Now code looks much better
I would suggest you use a Map instead of an Array.
Please view the following code:
public class MyClass {
public static void main(String args[]) {
Map<Integer,Integer> numbers = new HashMap<>();
Random rand = new Random();
for(int i = 0; i < 7; i++) {
int number = rand.nextInt(46);
while(numbers.containsKey(number)) {
number = rand.nextInt(46);
}
// saving the index with the random value - to be used for sorting, etc...
numbers.put(number,i);
}
System.out.println(numbers);
}
}
And the output (Note that the map-key is the random value and the map-value is the index):
{17=2, 19=3, 22=0, 40=6, 42=4, 44=1, 30=5}
HashSet also works quite well (as pointed out by Johannes Kuhn):
public class MyClass {
public static void main(String args[]) {
Set<Integer> numbers = new HashSet<>();
Random rand = new Random();
for(int i = 0; i < 7; i++) {
int number = rand.nextInt(46);
while(numbers.contains(number)) {
number = rand.nextInt(46);
}
numbers.add(number);
}
System.out.println(numbers);
}
}
And the output:
[2, 35, 25, 10, 44, 30, 31]
If it is about just simplifying comparison using loop then you can do:
int[] numbers = new int[7];
Random rand = new Random();
for (int i = 0; i < 7; i++) {
int number;
outer:
while (true) {
number = rand.nextInt(46);
for (int n : numbers) {
if (n == number)
continue outer;
}
break;
}
numbers[i] = number;
}
for (int number : numbers) {
System.out.println(number);
}
But you should use Set or Streams as mentioned in other Answers listed here..
Related
num = Integer.parseInt(tf1.getText());
entered = Integer.parseInt(tf1.getText());
num2 = Integer.parseInt(tf2.getText());
entered2 = Integer.parseInt(tf2.getText());
for (i =(int) num; i<= num2 ; i++){
for (j=0 ; j >= i ; j++) {}
System.out.println(i);
}
do i have to use array list ? ArrayList<Integer> lists = new ArrayList<Integer>();
and if i use it how i can to separate each number in the arraylist,so I found the numbers between two numbers but how I can take each number and do the collatz conjecture java , please i need help quickly
The collatz conjecture is simple n = n/2 if n%2 == 0 and n = 3*n + 1 if n%2 == 1 and you're doing these calculations until n = 1. Based on this, you could write your function like this:
public static List<Integer> calculateConjecture(int number) {
List<Integer> values = new ArrayList<>();
while (number != 1) {
if (number % 2 == 0) {
number = number / 2;
} else {
number = 3 * number + 1;
}
values.add(number);
}
return values;
}
public static void main(String[] args) {
int inferiorLimit = 11;
int superiorLimit = 15;
for (int i = inferiorLimit; i <= superiorLimit; i++) {
System.out.println(calculateConjecture(i));
}
}
The values ArrayList will hold the sequence of numbers for the current number between the [inferiorLimit,superiorLimit]
I was given an assignment that made me create 3 methods that created an array, print an array, and count all the numbers divisible by 10 in a array. The part that is giving me the most trouble is counting the numbers divisible by 10. the is the code I have so far:
public int[] createArray(int size) {
Random rnd = new Random();
int[] array = new int[size];
for (int i = 0; i < array.length; i++) {
array[i] = rnd.nextInt(101);
}
return array;
}
public void printArray() {
Journal5a call = new Journal5a();
int[] myArray = call.createArray(10);
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}
System.out.println("There are " + call.divideByTen(myArray[i]) + " numbers that are divisable by 10");
}
public int divideByTen(int num) {
int count = 0;
if (num % 10 == 0) {
count++;
}
return count;
}
public static void main(String[] args) {
Journal5a call = new Journal5a();
Random rnd = new Random();
call.printArray();
}
Pass an array to the method, and use that for determining the count. Your algorithm looks reasonable. Something like,
public int divideByTen(int[] nums) {
int count = 0;
for (int num : nums) {
if (num % 10 == 0) {
count++;
}
}
return count;
}
or, in Java 8+, use an IntStream and filter like
return (int) IntStream.of(nums).filter(x -> x % 10 == 0).count();
Then you can call it like
System.out.println("There are " + call.divideByTen(myArray)
+ " numbers that are divisible by 10");
or with printf and inline like
System.out.printf("There are %d numbers that are divisible by 10.%n",
IntStream.of(nums).filter(x -> x % 10 == 0).count());
You can do it this way. Pass full array and then check for division by 10. Skipped other part for simplicity.
public void printArray() {
Journal5a call = new Journal5a();
int[] myArray = call.createArray(10);
divideByTen(myArray);
}
public int divideByTen(int[] num) {
int count = 0;
for(i=0;i<num.length;i++)
{
if (num[i] % 10 == 0) {
count++;
}
}
return count;
}
my intend is to use simplest java (array and loops) to generate random numbers without duplicate...but the output turns out to be 10 repeating numbers, and I cannot figure out why.
Here is my code:
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
do {
for (int i=0; i<number.length; i++) {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
}
} while (!repeat);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
How about you use a Set instead? If you also want to keep track of the order of insertion you can use a LinkedHashSet.
Random r = new Random();
Set<Integer> uniqueNumbers = new HashSet<>();
while (uniqueNumbers.size()<10){
uniqueNumbers.add(r.nextInt(21));
}
for (Integer i : uniqueNumbers){
System.out.print(i+" ");
}
A Set in java is like an Array or an ArrayList except it handles duplicates for you. It will only add the Integer to the set if it doesn't already exist in the set. The class Set has similar methods to the Array that you can utilize. For example Set.size() is equivalent to the Array.length and Set.add(Integer) is semi-equivalent to Array[index] = value. Sets do not keep track of insertion order so they do not have an index. It is a very powerful tool in Java once you learn about it. ;)
Hope this helps!
You need to break out of the for loop if either of the conditions are met.
int[] number = new int[10];
int count=0;
int num;
Random r = new Random();
while(count<number.length){
num = r.nextInt(21);
boolean repeat=false;
do{
for(int i=0; i<number.length; i++){
if(num==number[i]){
repeat=true;
break;
}
else if(i==count){
number[count]=num;
count++;
repeat=true;
break;
}
}
}while(!repeat);
}
for(int j=0;j<number.length;j++){
System.out.print(number[j]+" ");
}
This will make YOUR code work but #gonzo proposed a better solution.
Your code will break the while loop under the condition: num == number[i].
This means that if the pseudo-generated number is equal to that positions value (the default int in java is 0), then the code will end execution.
On the second conditional, the expression num != number[i] is always true (otherwise the code would have entered the previous if), but, on the first run, when i == count (or i=0, and count=0) the repeat=true breaks the loop, and nothing else would happen, rendering the output something such as
0 0 0 0 0 0...
Try this:
int[] number = new int[10];
java.util.Random r = new java.util.Random();
for(int i=0; i<number.length; i++){
boolean repeat=false;
do{
repeat=false;
int num = r.nextInt(21);
for(int j=0; j<number.length; j++){
if(number[j]==num){
repeat=true;
}
}
if(!repeat) number[i]=num;
}while(repeat);
}
for (int k = 0; k < number.length; k++) {
System.out.print(number[k] + " ");
}
System.out.println();
Test it here.
I believe the problem is much easier to solve. You could use a List to check if the number has been generated or not (uniqueness). Here is a working block of code.
int count=0;
int num;
Random r = new Random();
List<Integer> numbers = new ArrayList<Integer>();
while (count<10) {
num = r.nextInt(21);
if(!numbers.contains(num) ) {
numbers.add(num);
count++;
}
}
for(int j=0;j<10;j++){
System.out.print(numbers.get(j)+" ");
}
}
Let's start with the most simple approach, putting 10 random - potentially duplicated - numbers into an array:
public class NonUniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
number[count++] = ThreadLocalRandom.current().nextInt(21);
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
So that gets you most of the way there, the only thing you know have to do is pick a number and check your array:
public class UniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
int candidate = ThreadLocalRandom.current().nextInt(21);
// Is candidate in our array already?
boolean exists = false;
for (int i = 0; i < count; i++) {
if (number[i] == candidate) {
exists = true;
break;
}
}
// We didn't find it, so we're good to add it to the array
if (!exists) {
number[count++] = candidate;
}
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
The problem is with your inner 'for' loop. Once the program finds a unique integer, it adds the integer to the array and then increments the count. On the next loop iteration, the new integer will be added again because (num != number[i] && i == count), eventually filling up the array with the same integer. The for loop needs to exit after adding the unique integer the first time.
But if we look at the construction more deeply, we see that the inner for loop is entirely unnecessary.
See the code below.
import java.util.*;
public class RandomDemo {
public static void main( String args[] ){
// create random object
Random r = new Random();
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
int i=0;
do {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
i++;
} while (!repeat && i < number.length);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
}
}
This would be my approach.
import java.util.Random;
public class uniquerandom {
public static void main(String[] args) {
Random rnd = new Random();
int qask[]=new int[10];
int it,i,t=0,in,flag;
for(it=0;;it++)
{
i=rnd.nextInt(11);
flag=0;
for(in=0;in<qask.length;in++)
{
if(i==qask[in])
{
flag=1;
break;
}
}
if(flag!=1)
{
qask[t++]=i;
}
if(t==10)
break;
}
for(it=0;it<qask.length;it++)
System.out.println(qask[it]);
}}
public String pickStringElement(ArrayList list, int... howMany) {
int counter = howMany.length > 0 ? howMany[0] : 1;
String returnString = "";
ArrayList previousVal = new ArrayList()
for (int i = 1; i <= counter; i++) {
Random rand = new Random()
for(int j=1; j <=list.size(); j++){
int newRand = rand.nextInt(list.size())
if (!previousVal.contains(newRand)){
previousVal.add(newRand)
returnString = returnString + (i>1 ? ", " + list.get(newRand) :list.get(newRand))
break
}
}
}
return returnString;
}
Create simple method and call it where you require-
private List<Integer> q_list = new ArrayList<>(); //declare list integer type
private void checkList(int size)
{
position = getRandom(list.size()); //generating random value less than size
if(q_list.contains(position)) { // check if list contains position
checkList(size); /// if it contains call checkList method again
}
else
{
q_list.add(position); // else add the position in the list
playAnimation(tv_questions, 0, list.get(position).getQuestion()); // task you want to perform after getting value
}
}
for getting random value this method is being called-
public static int getRandom(int max){
return (int) (Math.random()*max);
}
I would like to generate 10 random numbers. But before I add a number to the ArrayList, I need to check if my Arraylist already contains a number which is in the range between randomNumber - 50 and randomNumber + 50.
For example, if random number is 120 :
120-50=70
120+50=170
If the ArrayList contains a number between 70 and 170, I will not add it to my ArrayList and run again the cycle...
What is wrong with my code?
package ee.tlu;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Testing {
public Testing() {
List < Integer > numbers = new ArrayList < > ();
Random rand = new Random();
int number = rand.nextInt(5000);
int n = 0;
boolean listis = false;
numbers.add(number);
while (n < 10) {
number = rand.nextInt(5000);
for (int k = number - 50; k < number + 50; k++) {
if (numbers.contains(k)) {
listis = true;
break;
}
}
if (!listis) {
numbers.add(number);
n += 1;
}
}
System.out.println(numbers);
}
public static void main(String[] args) {
new Testing();
}
}
You declare listis before you start the while-loop. It's never reset once it has been set to true. Move it inside the loop.
Also, you never check the number + 50 as you are having < instead of <= in your for-loop.
while (n < 10) {
boolean listis = false;
number = rand.nextInt(5000);
for (int k = number - 50; k <= number + 50; k++) {
if (numbers.contains(k)) {
listis = true;
break;
}
}
if (!listis) {
numbers.add(number);
n += 1;
}
}
I'm not sure if it's the only problem, but you should reset your listis flag in each iteration of the while loop :
while (n < 10) {
listis = false; // added
number = rand.nextInt(5000);
for (int k = number - 50; k < number + 50; k++) {
if (numbers.contains(k)) {
listis = true;
break;
}
}
if (!listis) {
numbers.add(number);
n += 1;
}
}
Otherwise, the first time you find a number that shouldn't be added, you will stop adding any numbers.
I would do this recursively. I haven't tested the below code, just a quick mockup on notepad. But hopefully this will help.
public class Testing {
public List < Integer > numbers = new ArrayList < > ();
public Testing() {
Random rand = new Random();
int number = rand.nextInt(5000);
// initial number in arraylist
numbers.add(number);
// add 9 more numbers to arraylist
addNumbers(9);
System.out.println(numbers);
}
public void addNumber(int amountLeft){
int newNumber = rand.nextInt(5000);
if(isValidNumberToAdd(newNumber))
{
numbers.add(newNumber);
}
if(amountLeft == 0)
{
return;
}
addNumber(amountLeft--);
}
public boolean isValidNumberToAdd(int newNumber)
{
Iterator<int> numbersIterator = numbers.iterator();
while (numbersIterator.hasNext()) {
int number = numbersIterator.next();
if(newNumber > number - 50 && newNumber < number + 50)
{
return false;
}
}
return true;
}
public static void main(String[] args) {
new Testing();
}
}
Simply use Set instead of List. Sets guarantee that:
Adding new element to the set works only if new element is not already present in the set.
I tried to create a simple lottery program. Here is a problem: it still prints same numbers. For example I got 33 21 8 29 21 10 as output. Everytime when random number is generated, code checks if that number is already generated, then it creates a new random number but after that it doesn't check again. I couldn't find a way to do that.
public static void main(String[] args)
{
int[] lottery = new int[6];
int randomNum;
for (int i = 0; i < 6; i++)
{
randomNum = (int) (Math.random() * 50); //Random number created here.
for (int x = 0; x < i; x++)
{
if (lottery[i] == randomNum) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);//If random number is same, another number generated.
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
There are 2 problems with your code:
you check if lottery[i] and randomNum are the same, it should be lottery[x]
when you re-generate a random number, you don't check it against the first numbers in lottery.
Here is a corrected version:
public static void main(String[] args) {
int[] lottery = new int[6];
int randomNum;
for (int i = 0; i < 6; i++) {
randomNum = (int) (Math.random() * 50); // Random number created here.
for (int x = 0; x < i; x++) {
if (lottery[x] == randomNum) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);// If random number is same, another number generated.
x = -1; // restart the loop
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
You are changing the random number while you are checking it. You need to pick one random number and check whether it is present or not.
BTW A shorter approach is to use a shuffle.
// give me all the number 1 to 50
List<Integer> list = IntStream.range(1, 51).boxed().collect(Collectors.toList());
// shuffle them.
Collections.shuffle(list);
// give me the first 6
System.out.println(list.subList(0, 6));
A simple solution, between the first (who could be very abstract for a not Java programmer) and the 2nd (not assuring the unicity of the number list).
Collection<Integer> liste = new ArrayList<Integer>();
for (int i = 0; i < 6; i++)
{
Boolean ap = false;
while (!ap)
{
Integer randomNumber = (int) (Math.random() * 50);
if (! liste.contains(randomNumber)){
liste.add(randomNumber);
ap = true;
}
}
}
for (Integer liste1 : liste) {
System.out.print(liste1+" ");
}
try this one, it creates 12 x (6 out of 45)
public static void main(String[] args) {
SecureRandom random = new SecureRandom();
for (int i = 0; i < 12; i++){
Integer[] tipp = new Integer[6];
int n = 0;
do {
int r = random.nextInt(45) + 1;
if (Arrays.asList(tipp).indexOf(r)<0){
tipp[n]= r;
n++;
}
} while (n<=5);
Arrays.sort(tipp);
System.out.println(Arrays.toString(tipp));
}
}
public static void main(String[] arg) {
int[] lottery = new int[6];
int randomNum;
c1:
for (int i = 0; i < 6; i++) {
randomNum = (int) (Math.random() * 50); // Random number created here.
if(randomNum == 0) {
continue c1;
}
for (int x = 0; x < i; x++) {
if (lottery[x] == randomNum ) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);// If random number is same, another number generated.
x = -1; // restart the loop
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
This is the object class for making a ticket, it will create ONE ticket with ascending values at which whatever parameters you choose. This program won't run until you have a main method that you call. Make sure to import TreeSet.
import java.util.TreeSet;
public class TicketMaker{
private int numbersPerTicket;
private int lowestNumber;
private int highestNumber;
TicketMaker(){
numbersPerTicket=0;
lowestNumber=0;
highestNumber=0;
}
TicketMaker(int numbersPerTicket,int lowestNumber,int highestNumber){
if(numbersPerTicket > 0 && lowestNumber >= 0 && highestNumber >= lowestNumber){
this.numbersPerTicket=numbersPerTicket;
this.lowestNumber=lowestNumber;
this.highestNumber=highestNumber;
}
}
public boolean printTicket(int numbersPerTicket,int lowestNumber,int highestNumber){
if(numbersPerTicket > 0 && lowestNumber >= 0 && highestNumber >= lowestNumber){
if(numbersPerTicket > highestNumber){
System.out.println("Error not in-bounds");
return false;
}
int rand;
int count=0;
System.out.println("[Ticket Printed]");
TreeSet<Integer> set = new TreeSet<>();
do{
rand = (int)(Math.random()*highestNumber)+lowestNumber;
set.add(rand);
count++;
}while(set.size() != numbersPerTicket);
System.out.println(set);
return true;
}
else{
System.out.println("Error not in-bounds");
return false;
}
}
public boolean isValidTicketData(int numbers,int lowest,int highest){
if(lowest != 1){
if(highest == numbers)
return false;
}
if(numbers <= highest){
if(numbers > 0 && lowest >= 0 && highest >= lowest)
return true;
}
return false;
}
}