I have this method that generates random questions, I want to be able to generate each question once and no more than once.
How could I do that?
This is the code so far:
package boss;
import java.util.Random;
import javax.swing.JFrame;
public class Boss {
public static void main(String[] args) {
LoginWindow window = new LoginWindow();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
public String getQuestions() {
String [] question = new String[30];
question[0] = "hello";
question[1] ="yo";
question[2] ="b";
question[3] ="ha";
//Generating random questions
Random r = new Random();
int i=r.nextInt(4);
String quest=question[i];
return quest;
}
}
You're not generating questions in your example - you're picking them from a fixed set stored in an array. It sounds like you just want to shuffle the array, then iterate over part of it until you have seen the required number of questions. So - suggest you shuffle the questions, then just iterate over the shuffled array, or shuffle an array of indexes 0..n and iterate over those in the original list of questions.
There's plenty of approaches to shuffling, perhaps the simplest is a single pass over the input data, swapping each element with some other randomly chosen element.
Use an ArrayList instead of a table. Removes the displayed question from the ArrayList when it has been displayed.
you have to keep a list of the ones you've already used and check against that.
boolean used[] = new boolean[30];
int i;
do {
Random r = new Random();
i=r.nextInt(4);
} while(used[i] == true);
String quest=question[i];
used[i] = true;
A fairly simple solution would be to keep a record of all the questions you have asked and only generate ones that you have not:
private ArrayList<Integer> questionsAsked = new ArrayList<>();
public String getQuestions()
{
String [] question = new String[30];
question[0] = "hello";
question[1] ="yo";
question[2] ="b";
question[3] ="ha";
//Generating random questions
Random r = new Random();
int i = r.nextInt(question.length);
//keep looping until you find a question you have not asked
while(questionsAsked.contains(i))
{
i = r.nextInt(question.length);
}
//add that question to the list of questions already asked
questionsAsked.add(i);
//ask the question
return question[i];
}
You can use Collections.shuffle together with queue remove and lazy question generation, working example:
import java.util.*;
public class Mkt {
private Queue<String> questions = null;
public Mkt() {
for(int i = 0; i < 10; i++) {
System.out.println(getQuestion());
}
}
public String getQuestion() {
if(questions == null || questions.size() == 0) {
questions = generateQuestions();
}
return questions.remove();
}
private Queue<String> generateQuestions() {
List<String> list = Arrays.asList("hello", "yo", "b", "ha");
Collections.shuffle(list);
return new LinkedList<String>(list);
}
public static void main(String[] args) {
new Mkt();
}
}
Sample run:
$ javac Mkt.java && java Mkt
ha
yo
hello
b
b
ha
hello
yo
hello
ha
You could solve this with a "shuffle" algorithm. Basically randomize (shuffle) your array and then just pick the next item from the list.
One of the easiest shuffle algorithms is Knuth's: http://en.wikipedia.org/wiki/Knuth_shuffle
Pseudocode to shuffle your array:
Random rand = new Random();
for (int i=questions.Length-1; i>=0; --i)
{
int nextRand = rand.Next(i);
// Switch the randomly selected 'next' to the current pointer in the array
string temp = questions[nextRand];
questions[nextRand] = i;
questions[i] = temp;
}
Keep track of what you've already picked.
String [] question = new String[30];
boolean[] picked = new boolean[30];
...
if (!picked[i])
{
String quest=question[i];
picked[i] = true;
}
else
// choose another
(Obviously you'll need to restructure your code and also deal with knowing when you've exhaused your question supply and all have been picked)
Related
I am trying to sum N pairs of ints--an Nx2 ArrayList--and return the N summations as an ArrayList. While I understand it is not necessary to set up a class to accomplish this, I would like to do so as practice for future projects.
import java.util.ArrayList;
public class SumsInLoop {
public SumsInLoop(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {}
public ArrayList<Integer> getSums(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {
ArrayList<Integer> pairsOfSums = new ArrayList<Integer>();
for (ArrayList<Integer> Pair : numbersList) {
int x = Pair.get(0);
int y = Pair.get(1);
int sum = x + y;
pairsOfSums.add(sum);
}
System.out.println(pairsOfSums);
return pairsOfSums;
}
The data that I am given is a random assortment of N pairs (numbersOfPairs) of integers, e.g. 612673 108695. I would like to add these pairs of integers to a 2D ArrayList (numbersList) that will be called by getSums.
However, I am having difficulties initializing numbersList. My main function is as follows:
public static void main(String[] args) {
int myNumberOfPairs = 13;
ArrayList[][] myNumbersList = new ArrayList[13][2];
myNumbersList[0][0] = new ArrayList<>();
myNumbersList[0][0].add(612673);
myNumbersList[0][1].add(108695);
myNumbersList[1][0] = new ArrayList<>();
myNumbersList[1][0].add(756875);
myNumbersList[1][1].add(496058);
SumsInLoop mySum = new SumsInLoop(myNumberOfPairs,myNumbersList);
mySum.getSums(myNumberOfPairs, myNumbersList);
The last two lines of code throw errors, asking me to change myNumbersList to type ArrayList<List<Integer>> which throws even more errors, even after changing all 2D ArrayLists to type ArrayList<List<Integer>>.
So, my two questions are as follows:
How can I initialize an NxM ArrayList and populate it correctly?
Is there a faster way of accomplishing this task while still using a class method?
P.S. I'm used to coding in Python and am self-teaching myself Java, so any other information or resources you can provide me with are much appreciated.
You may want to simplify your input by using 2D array of int : int[][] myNumbersList = new int[13][2];
The expected output in that case is a 1D array of int[13] that can be obtained as follows (demonstrated with 2 pairs. See mcve ) :
public class SumsInLoop {
//pairsOfInts should be an [n][2] array
private static int[] sumOfPairs(int[][] pairsOfInts) {
int[] sums = new int[pairsOfInts.length];
for(int pairIndex = 0; pairIndex < pairsOfInts.length; pairIndex++) {
sums[pairIndex]= pairsOfInts[pairIndex][0]+pairsOfInts[pairIndex][1];
}
return sums;
}
public static void main(String[] args) {
int numberOfPairs = 2;
int[][] pairsOfInts = new int[numberOfPairs][2];
pairsOfInts[0] = new int[] {612673,108695 };
pairsOfInts[1] = new int[] {756875,496058 };
int[] sumOfPairs = sumOfPairs(pairsOfInts);
System.out.println(Arrays.toString(sumOfPairs));
}
}
If you want a solution implemented with List you can make use of javafx Pair (or make your own pair class.
The input can be defined as List<Pair<Integer,Integer>> pairsOfInts = new ArrayList<>();
The out put can be an array as above, or a List<Integer>:
import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;
public class SumsInLoop {
private static List<Integer> sumOfPairs(List<Pair<Integer, Integer>> pairsOfInts) {
List<Integer> sums = new ArrayList<>();
for(Pair<Integer,Integer> pair : pairsOfInts) {
sums.add(pair.getKey()+ pair.getValue());
}
return sums;
}
public static void main(String[] args) {
List<Pair<Integer,Integer>> pairsOfInts = new ArrayList<>();
pairsOfInts.add (new Pair<>(612673,108695 ));
pairsOfInts.add (new Pair<>(756875,496058));
List<Integer> sumOfPairs = sumOfPairs(pairsOfInts);
System.out.println(sumOfPairs);
}
}
The (compile) exception you are getting is due to the fact that you expect a ArrayList<ArrayList<Integer>>, but pass an ArrayList[][]. (which is not the same in Java)
In your case you'd need (in the main method):
ArrayList<ArrayList<Integer>> myNumbersList = new ArrayList</* when java > 6 ;)*/>(13);
this only sets the capacity of the (parent) list (..and the underlying/internal backing array)
to initialize the child lists, you'd not come around looping (somehow...even not in python :):
for (int i = 0; i < 13; i++) {
myNumbersList.add(new ArrayList<Integer>(2));
}
Depends on what means "correctly" ...but I assume with "random data", ideally you would again inner loop:
java.util.Random rnd = new Random(/*seed default current timestamp*/);
//...
for (int i = 0; i < 13; i++) {
ArrayList<Integer> innerList = new ArrayList<>(2);
for (int j = 0; j < 2; j++) {
innerList.add(rnd.netxInt(/*bound default Integer.MAX_VALUE*/) /*+/-/% offset*/);
}
myNumberList.add(innerList);
}
Sorry I am not aware of one (faster way), but much depends on the "input format".
Since you already know the amount of values in a pair, an ArrayList is unnecessary. You can create your own, simpler implementation of a pair.
class Pair {
public final int left;
public final int right;
public Pair(int left, int right){
this.left = left;
this.right = right;
}
}
You can then access the values by creating a pair object and accessing its fields.
Pair p = new Pair(10, 7);
System.out.println(p.left); // 10
System.out.println(p.right); // 7
You can then more easily redefine your getSums method.
public static List<Integer> getSums(List<Pair> pairs){
List<Integer> pairsOfSums = new ArrayList<>();
for(Pair pair : pairs){
int sum = pair.left + pair.right;
pairsOfSums.add(sum);
}
return pairsOfSums;
}
Please also notice the function can be static and you don't need to pass the number of pairs. The for-each loop will cycle through all of them regardless.
Initializing the array is then easier than the method you have described in the question.
List<Pair> pairs = new ArrayList<>();
pairs.add(new Pair(7, 10));
pairs.add(new Pair(18, 3));
pairs.add(new Pair(-6, 0));
pairs.add(new Pair(4, 2));
System.out.println(SumsInLoop.getSums(pairs));
So I am relatively new to the programming scene and I am confused as to why my code doesn't work. I am trying to make an arraylist of flowers and then use a random number generator to create a random number of certain flowers, and store them in the array. In my logic, I thought that I created a variable to store the numbers (ex randomRoses) and stored the number in the array so I could easily print out how many of each flower there is by just calling the arraylist and the position. (ex flowerArray[0] would print out 8 Roses) but sadly it does not.
public class Flower
{
private int randomRoses;
private int randomTulips;
private int randomOrchids;
public ArrayList <Integer> flowerArray;
public Flower()
{
r = new Random();
t = new Random();
o = new Random();
int randomRoses = (r.nextInt(10) + 0);
int randomTulips = (t.nextInt(10) + 0);
int randomOrchids = (o.nextInt(10) + 0);
flowerArray = new ArrayList<Integer>
}
public void add2Array ()
{
flowerArray.add(randomRoses); //flowerArray[0] is the # of roses
flowerArray.add(randomTulips); //flowerArray[1] is the # of tulips
flowerArray.add(randomOrchids); //flowerArray[2] is the # of orchids
}
public void printArray()
{
System.out.println(flowerArray[0]);
}
You can use the same random object, no need to create 3 instances of it for the random integer generation,
Random r = new Random();
for (int i = 0; i < 3; i++) {
flowerArray.add(r.nextInt(10));
}
System.out.println(flowerArray);
you can not do flowerArray[0] because you have an arrayList and not an array.
you can instead do: flowerArray.get(0) for getting the integer at pos zero
Here your array list is associated with a class object. When you initialize your array list you need to add your entries to the array list in the constructor itself. So when you say object.printArray() its actually returning you the empty array list, that's why you are getting 0 every time. Try This.
class Flower
{
private int randomRoses;
private int randomTulips;
private int randomOrchids;
public ArrayList<Integer> flowerArray;
public Flower()
{
Random r = new Random();
Random t = new Random();
Random o = new Random();
int randomRoses = (r.nextInt(10));
int randomTulips = (t.nextInt(10));
int randomOrchids = (o.nextInt(10));
System.out.println(randomRoses);
System.out.println(randomTulips);
System.out.println(randomOrchids);
flowerArray = new ArrayList<Integer>();
flowerArray.add(randomRoses); //flowerArray[0] is the # of roses
flowerArray.add(randomTulips); //flowerArray[1] is the # of tulips
flowerArray.add(randomOrchids); //flowerArray[2] is the # of orchids
}
public void printArray()
{
System.out.println(flowerArray.get(0));
}
}
public class Test {
public static void main(String[] args) {
Flower f = new Flower();
f.printArray();
}
}
And in array list you can get elements by using get(index) method.
This will give the output you expect.
public void printArray
{
System.out.println(flowerArray.get(0)+" Roses");
System.out.println(flowerArray.get(1)+" Tulips");
System.out.println(flowerArray.get(2)+" Orchids");
}
Also you missed a semi-colon after the statement defining the arraylist.
Make the correction:
flowerArray=new ArrayList<Integer>;
How did it compile without that semi-colon?
It is not working because your syntax for getting the ith flower is wrong.
You're using a java.util.ArrayList so the correct way to get an object from that ArrayList is by calling the get() method.
System.out.println(flowerArray.get(0));
Hope that helps.
Each method contain a question with multiple choice. When i call the method in the main, i need to shuffle it and make sure there are no repetition.
public static void main(String[] args) {
question_1();
question_2();
question_3();
question_4();
//continue to question 15
question_15();
}
thing that i tried.
int question_A = question_1();
int question_B = question_2();
int question_C = question_3();
int question_D = question_4();
//to question 15
int question_O = question_15();
//then i created an array
int [] question = new int[14];
question[0] = question_A;
question[1] = question_B;
question[2] = question_C;
question[3] = question_D;
//to last array
question[14] = question_O;
//to random it here is the code
Random r = new Random();
for (int counter = 0; counter <10; ++counter){
int swap_Index = r.next Int(15-counter)+counter; //there is an space between next Int, that because i was getting not properly formatted in the edit box
int temp = question[counter];
question[counter] = question[swap_Index];
question[swap__Index] = temp;
int[] question_To_Ask = new int[10];
for (int count = 0; count<10; ++count){
question_To_Ask[count] = question[count];
}
The reason the random does not work is because it starts executing the program at
int question_A = question_1();
for the random, i also tried any way such as Math.random. None of these worked and yeah, please do not use advance technique to solve this problem as i am a beginner.
The easy way to do this is using a list:
List<Question> questions = new ArrayList<Question>();
questions.add(question_1);
questions.add(question_2);
questions.add(question_3);
.....
Collections.shuffle(questions);
See, I dunno what you are doing with all these methods, but let us consider another approach put every question in a database, use a Collection like say hashmap in ur java code access ur database and based on the id of the question u can call whichever question u want to call and for the shuffling part there is a predefined function called shuffle in java, u can use it to shuffle ur question collection. Just a suggestion, try it, i think it is a better approach.
You could do something like this
public static void main(String[] args) {
// declare the variables first
int q1 = 1;
int q2 = 2;
...
int q15 = 15;
int[] questions = new int[] { q1, q2, q3, q4, ... q15 };
System.out.println("Before Shuffle");
for (int i : questions) {
System.out.println(i);
}
shuffle(questions); // here we do the shuffle
System.out.println("After Shuffle");
for (int i : questions) {
System.out.println(i);
}
}
public static void shuffle(int[] questions) {
Random random = new Random();
for (int i = 0; i < questions.length; i++) {
int newIndex = random.nextInt(questions.length - 1);
swap(questions, i, newIndex);
}
}
private static void swap(int[] questions, int oldIndex, int newIndex) {
int temp = questions[oldIndex];
questions[oldIndex] = questions[newIndex];
questions[newIndex] = temp;
}
This question already has answers here:
Generating Unique Random Numbers in Java
(21 answers)
Closed 9 years ago.
I have this assignment:
Print 5 random integer between 1-52 with no duplicate using if/else.
Here's my code so far. It prints some numbers, but it sometimes prints duplicates.
import java.util.Random;
public class RandomCards {
public static void main(String[] args) {
Random randomCards = new Random();
int card;
for (int x = 1; x <= 5; x++) {
card = randomCards.nextInt(52) + 1;
}
if (card != randomCards) // if the value of card is not equal, proceed
{
System.out.print(card + " ");
} else {
return card; // if the value are the same get random integers again
}
}
}
public static void main(String args[]) {
Random randomNumber = new Random();
// Set stores only Unique values
Set<Integer> cards = new HashSet<Integer>();
// Iterate over to generate random numbers
while (cards.size() < 5) {
int r = randomNumber.nextInt(52) + 1;
cards.add(r);
}
for(Integer card : cards) {
System.out.println(card);
}
}
You can use this
Random randomCards = new Random();
int[] card={0,0,0,0,0};
while(card[card.length-1] == 0) {
int temp=randomCards.nextInt(52);
for(int j=0;j< card.length ; j++){
if(card[j] == 0){
card[j] = temp;
break;
}
}
}
for(int j=0;j< card.length ; j++){
System.out.println(card[j]);
}
It's not clear what you're asking, but I note from your code that you don't have any duplicate detection. You need to save each value that you generate and check for duplicates when you create a new one. I suggest creating a Set<Integer> to hold your generated values, calling add() for each new card, and checking contains() to see whether a new value has already been selected. You'd want to change your loop condition to something like cards.size() < 5 as well.
Finally, note that your use of return card is incorrect and will result in a compile-time error. return is used to end a method and send a value back to where it was called from; the main method (which is always void) has no return value, and ending the method wouldn't make sense there anyway. It looks like some code may have been copied and pasted from a version where drawCard() was its own method. Instead, just keep looping until you find 5 unique cards (such as by using the size() method I mentioned earlier).
Maybe this?
Random rand = new Random();
// ArrayList to store non-duplicate cards.
ArrayList<Integer> cards = new ArrayList<Integer>();
// Iterate over to generate random numbers
while (cards.size() < 5)
{
int r = rand.nextInt(52) + 1;
if (!cards.contains(r))
cards.add(r); // Only add if there is no such number in list
}
Hope this helps.
Hope this would be of any help.
It comprises of separate methods for computation, setting the lower and upper bound and printing the list when it has 5integers in it. Using TreeSet solves your problem of duplicates. Here it goes,
package com.project.stackoverflow;
import java.util.Random;
import java.util.Scanner;
import java.util.TreeSet;
public class RandomGenerator {
public TreeSet<Integer> compute() {
TreeSet<Integer> generatedList = new TreeSet<Integer>();
Scanner s = new Scanner(System.in);
System.out.println("Enter the lower bound for checking random numbers:");
long lowBound = s.nextLong();
System.out.println("Enter the upper bound for checking random numbers:");
long topBound = s.nextLong();
Random randomNumbers = new Random();
for (int i = 0; i < topBound; i++) {
if (generatedList.size()==5) {
break;
}
else {
generatorFunc(lowBound, topBound,randomNumbers,generatedList);
}
}
return generatedList;
}
public void generatorFunc(long lowBound,long topBound,Random randomNumbers, TreeSet <Integer> generatedList) {
long limit = topBound - lowBound;
long part = (long)(limit * randomNumbers.nextDouble());
int randomNum = (int) (part + lowBound);
generatedList.add(randomNum);
}
public void printList() {
TreeSet<Integer> testListVals = compute();
System.out.println("New" + testListVals);
}
public static void main(String[] args) {
RandomGenerator obj = new RandomGenerator();
obj.printList();
}
}
If your problem is just about the duplicates, then you can store each random number generated in an array, and for every successive call to nextint(), check if it already exists in the array of stored values, and till it does, call nextint() again for that iteration itself, else store it in the array and go to next iteration.
I am trying to make a poker game through java.
The first thing I wanted to do is distribute 5 cards using arrays. I have done the distribution part, but how can I prevent the same cards being distributed twice. In other words, how can I check if an array already contains an element. I want it to be able to detect if the element already exists in an array, and if it does, I want to be able to change just that card that has been given out twice, help would be much appreciated.
My codes down below,
import java.util.Random;
import java.util.Scanner;
import java.util.Arrays;
public class Poker
{
public final static String[] numbers = {"❤","♠","♦","♣"};
public final static String[] sign = {"1","2","3","4","5","6","7","8","10","J","Q","K","A"};
private String[] hand = {"","","","",""};
private boolean found;
private Random random;
public Poker()
{
found = false;
String hand[] = {"","","","",""};
int tokens = 10;
Scanner in = new Scanner(System.in);
random = new Random();
}
public void handOut()
{
for (int i = 0; i < 5; i++)
{
int numberRandom = random.nextInt(numbers.length);
int signRandom = random.nextInt(sign.length);
String pickedNumber = numbers[numberRandom];
String pickedSign = sign[signRandom];
String combinedSigns = pickedSign + pickedNumber;
hand[i] = combinedSigns;
System.out.print(hand[i] + " ");
}
System.out.println("\n");
}
}
Your choice of terminology is ... err ... interesting :-)
The card value is a "face value", not a sign. And whether it's hearts or diamonds or so on, that's its "suit" rather than its number.
But, on to the question. I believe the best way to do this is to construct an entire 52-card deck out of your facevalue and suit arrays and then use a Fisher Yates shuffle to distribute cards.
This is a nifty way to randomly choose elements from an array without duplicates. The beauty is that the items in the array don't actually need to be shuffled up front. Details on how it works can be found here.
If you can use the collections framework as opposed to an array, create a Stack and populate it with all the 52 cards. then call Collections.shuffle() on it.
finally set hand[i]=(deck name).pop()
Once a card is popped from the stack it will be removed from the deck so it can't be dealt again.
What you want to do is break your code into different methods. You should have a method for generating one card, a method for checking whether or not a card is in the hand, and a method to distribute cards to the hand.
public String generateCard() {
int numberRandom = random.nextInt(numbers.length);
int signRandom = random.nextInt(sign.length);
String pickedNumber = numbers[numberRandom];
String pickedSign = sign[signRandom];
return pickedSign + pickedNumber;
}
public static boolean cardIsInHand(String card) {
for(int i = 0; i < 5; i++) {
if(hand[i] != null && hand[i].contains(card)) {
return true;
}
}
return false;
}
public static void handout() {
for (int i = 0; i < 5; i++) {
String card = generateCard();
while(cardIsInHand(card)) {
card = generateCard();
}
hand[i] = card;
}
}