How to check duplicate values? - java

I Need to Write a Solution That Checks for Duplicate Values (Like Birthdays) in Each Iteration and Return the Number of Iterations That Have a Duplicate value within It. If One Duplicate is Found You Can Stop The Current Iteration And Start the Next.
What Of My Solution Should Be Altered. How Should A Solution Be Written To Solve This Duplicates Problem.
static int runSim(int thePeople, int theCount) {
int count = 0;
// Runs the Sim by Count
for(int i = 1; i <= theCount; i++) {
List<Integer> listOfGenNums = new ArrayList<>();
Random rand = new Random();
rand.setSeed(i);
ppl: for (int j = 0; j <= thePeople; j++) {
int genN = rand.nextInt(365);
// Add Values to Arraylist
listOfGenNums.add(j, genN);
// Converted ArrayList to Array
Object[] array = listOfGenNums.toArray();
// Check Item by Item
for(int h = 0; h <= array.length; h++) {
for(int k = i+1; k <= array.length-2; k++) {
// Checks if Index[i] is Same as Index[j]
if (array[h].equals(array[k])) {
count += 1;
break ppl;
} // End IF
} // End Inner Loop
} // End Loop
} // End People Loop
} // End Simulation Loop
return count;
}

I would use a HashSet. This would allow constant access to see if you have already visited the current number. If it has already been visited you can break and increment count, otherwise add it to the hashset and continue.
Here is your code rewritten to be much more efficient.
static int runSim(int thePeople, int theCount) {
int count = 0;
// Runs the Sim by Count
for(int i = 1; i <= theCount; i++) {
Hash<Integer> setOfGenNums = new HashSet<Integer>();
Random rand = new Random();
rand.setSeed(i);
for (int j = 0; j < thePeople; j++) {
int genN = rand.nextInt(365);
if(setOfGenNums.contains(genN)){
count++; break;
}
listOfGenNums.add(genN);
} // End People Loop
} //End Count Loop
return count;
}

Related

randomly generate 100 unique numbers using Math.random [duplicate]

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);
}

Java for loop needs to pick up where it left off

I need the second for loop to pick up where it left off. Every time the if statement is true I need a slot to fill in the array used in the first for loop. But I don't want the same key value to keep getting added. I need the second for loop to move to the next key value. (In the code below, arrl is an ArrayList of objects that have a value)
int temp = 0;
int count = 0;
for(int i = 0; i < eeVal.length; i++)
{
count= 0;
for(int j = temp; j < arrl.size(); j++)
{
if(arrl.get(j).getValue() == 1 && count == 0)
{
eeVal[i] = arrl.get(j);
count++;
temp=j;
}
}
}
}
return eeVal;
You need another variable to track where the inside loop has gotten to. Something like the following:
int temp = 0;
for(int i = 0; i < eeVal.length; i++)
{
for(int j = temp; j < arrl.size(); j++)
{
if(arrl.get(j).getValue() == 1)
{
eeVal[i] = arrl.get(j);
}
temp=j;
}
}
}
return eeVal;
This way, once the outside loop runs the second time around, the inside loop will start from 'temp' until the end of the loop.
From your explanation, it sounds like you do not want the inner for loop. The traversal of arrl needs to be manually controlled using a variable, e.g.`cnt', which only gets incremented when your condition for incrementing it is satisfied.
What you probably are looking for is a List.
In your answer, you don't need the first loop. This one has issues though - index i can go out of bounds.
int i = 0;
for(int j = 0; j < arrl.size(); j++) {
if(arrl.get(j).getValue() == 1) {
eeVal[i++] = arrl.get(j);
}
}
return eeVal;
What you need is a dynamic collections such as List.
Using list (I am calling the type as MyType).
List<MyType> vals = new ArrayList<>();
for(MyType item : arrl) {
if(item.getValue() == 1) {
vals.add(arrl.get(j));
}
}
return vals.toArray(new MyType[vals.size()]);
The code was picking up where the last correct value was. I needed to add 1 to j when I wanted progress to know where I left off.
int count2 = 0;
int progress = 0;
for(int i = 0; i < retVal[h].length; i++)
{
count2 = 0;
for(int j = progress; j < arr.size(); j++)
{
if(arr.get(j).getLevel() == h && count2==0)
{
retVal[h][i] = arr.get(j);
count2++;
progress = j+1;
}
}
}
return retVal;

Returning wrong percentage

I am trying to calculate how many times two people in a group have the same birthday when given a size of the group. I am also given how many times the simulation is ran. I am trying to return the correct percentage for how many times we have two people share the same birthday out of the given amount of simulations.
I created an array first and then called a method to put the elements in a hashMap which would then show when there are two of the same values in the hashMap. However, I am not getting the correct percentage when running on Android Studio. In fact I am getting a percentage way off. I also declared a global static match variable of type int above this block.
/**
* sameBday: Create a word count mapping from an array
*/
public void sameBday(int[] valueHolder) {
Map<Integer, Integer> myMap = new HashMap<Integer, Integer>();
for(int number: valueHolder){
if(!myMap.containsKey(number)){
myMap.put(number, 1);
}
else if(myMap.containsKey(number)){
myMap.put(number, myMap.get(number) + 1);
match++;
break;
}
}
}
public double calculate(int size, int count) {
double percentage = 0.0;
int[] myArray = new int[size];
for(int i = 1; i <= count; i++){
Random r = new Random(i);
for(int j = 0; j < size; j++){
myArray[j] = r.nextInt(365) + 1;
}
sameBday(myArray);
if(i == count){
percentage = (match * (100.0/i));
}
}
return percentage;
}
Well your code is full of weird things, but that's OK we all did that. The first thing is Map, you don't need it. You can create just good old for loop and by additional check you will not compare the same person (it is i != j condition), but if you really want to do this by map you need to at the end of adding number (as key) to map check if some value of key is higher than 1, if true it's a match.
How to do something at the end of loop?
if(i == count){
percentage = (match * (100.0/i));
}
No, just do this after loop :)
//At the beginning there is int match = 0;
public void sameDayBirthday(int[] birthdays) {
for(int i = 0; i < birthdays.length; i++) {
for(int j = 0; j < birthdays.length; j++) {
if(birthdays[i] == birthdays[j] && i != j) {
match++;
return;
}
}
}
}
public double calculate(int size, int count) {
int[] birthdays = new int[size];
Random r = new Random();
for(int i = 1; i <= count; i++){ //looping through i counts (or 20 counts in this case
for(int j = 0; j < size; j++){ //looping through j times every i iteration
birthdays[j] = r.nextInt(365) + 1;
}
sameDayBirthday(birthdays);
}
return (match * (100.0/(double) count));
}
This code by calling calculate(23, 1000000) got me 50.7685% chance, for 22 persons 47.48690%
I am sorry if I offend you I didn't mean it. Leave a comment if you have questions.
I would use a HashSet and skip the sameBday function:
public double calculate(int size, int count) {
int match = 0;
Random r = new Random();
for(int i = 1; i <= count; i++){ //looping through i counts (or 20 counts in this case
Set<Integer> birthdays = new HashSet<Integer>(size);
for(int j = 0; j < size; j++){ //looping through j times every i iteration
Integer birthday = r.nextInt(365) + 1;
if (birthdays.contains(birthday)) {
match++;
break;
} else {
birthdays.add(birthday);
}
}
}
return (match * (100.0/count));
}

Creating asterisks with for loop using arrays

I am trying to add asterisks on a line equal to the Int array. This starts at index 0 until the last index of the array. Here is what I have tried to do so far.
int e = 0;
int z = 0;
int[] yValuesInt = new int[yValues.length];
for (z=0; z<yValues.length; z++) {
yValuesInt[z] = (int) yValues[z]; // converted array from double to int
}
System.out.println("" + yValuesInt.length);
for (e = 0; e<yValuesInt.length; e++) { // outside loop to continue until last index
for (int j = 0; j<yValuesInt[z]; j++) { //inside loop to print asterisks
System.out.println(":" + asterisk);
}
}
Just a quick glance at your code at the printing of asterisks there. I didn't check on the loop though.
for (e = 0; e<yValuesInt.length; e++) { // outside loop to continue until last index
System.out.println(":");
for (int j = 0; j<yValuesInt[z]; j++) { //inside loop to print asterisks
System.out.print("*");
}
}
I believe this is what you're looking for as long as your loop count is correct.

2D Array in Java with number manipulation

My goal is to
Create a 5x5 array and fill it with random integers in the range of 1 to 25.
Print this original array
Process the array, counting the number of odds, evens, and summing all of the elements in the array.
Print the total odds, evens, and the sum.
Im not sure how to do it and my teacher is very confused and cannot help me. I was wondering if i could get some guidance.
Here is my code:
public class Processing {
public static void main(String[] args) {
Random Random = new Random();
int[][] Processing = new int[5][5];
for (int x = 0; x < 5; x++) {
int number = Random.nextInt(25);
Processing[x] = number;
}
for (int i = 0; i < 5; i++) {
Processing[i] = new int[10];
}
}
}
Please follow naming conventions for your variables. See here: http://en.wikipedia.org/wiki/Naming_convention_(programming)#Java
Anyways, you have to nest your loops as follows:
for(int i = 0; i < 5; i ++) {
for(int j = 0; j < 5; j++) {
yourArray[i][j] = random.nextInt(25);
}
}
i is the row number and j is the column number, so this would assign values to each element in a row, then move on to the next row.
I'm guessing this is homework so I won't just give away the answer to your other questions, but to set you on the right track, here's how you would print the elements. Again, use two nested loops:
for(int i = 0; i < 5; i ++) {
for(int j = 0; j < 5; j++) {
// print elements in one row in a single line
System.out.print(yourArray[i][j] + " ");
}
System.out.println(); //return to the next line to print next row.
}

Categories