I would like to check duplication in the finalChallenges ArrayList. Actually,I'm using while cicle for fill up the finalChallenges Arraylist. If cycle the finalChallenges arrayList contains duplication, then remove it and go forward.
Random random = new Random();
while (finalChallenges.size()<21) {
int index = random.nextInt(listChallenges.size());
finalChallenges.add(listChallenges.get(index));
if(compare(finalChallenges)){
inalChallenges.remove(index);
}
}
compare method:
public boolean compare(ArrayList<Challenges> compArray) {
for (int j=0;j<compArray.size();j++) {
for (int k = j + 1; k < compArray.size(); k++) {
if (k != j && compArray.get(k) == compArray.get(j))
return true;
}
}
return false;
}
Random random = new Random();
final Set<Challenges> challenges = new HashSet<>();
while (challenges.size() < 21) {
challenges.add(listChallenges.get(random.nextInt(listChallenges.size()));
}
finalChallenges = new ArrayList<>(challenges);
Better solution:
List<Integer> indices = new ArrayList<>(listChallenges.size());
List<Challenges> finalChallenges = new ArrayList<>();
for (int i = 0; i < listChallenges.size(); indices.add(i++));
for (int i = 0; i < Math.min(21, listChallenges.size()); ++i) {
int index = indices.remove(random.nextInt(indices.size());
finalChallenges.add(listChallenges.get(index));
}
Random random = new Random();
ArrayList<Challenges> temp = new ArrayList<Challenges>(listChallenges.size());
for (Challenges item : listChallenges) temp.add(item);
while (finalChallenges.size()<21 && temp.size()>0) {
int index = random.nextInt(temp.size());
finalChallenges.add(temp.get(index));
temp.remove(index);
}
Related
I´m trying to solve a question but i can´t find why my code is not working for this problem. I have generated a random vector of 100 elements and im trying to order them into another. Somehow, my new generated vector is filled with the last index value of the random vector.
int[] vetorAleatory = new int[100];
for (int i = 0; i < vetorAleatory.length; i++) {
vetorAleatory[i] = new Random().nextInt(1000);
}
int[] vetorByOrder = new int[100];
int newVetorPosition = 0;
for (int i = 0; i < 100; i++) {
for (int x = 0; x < 100; x++) {
vetorByOrder[newVetorPosition] = 2000;
if (vetorAleatory[i] < vetorByOrder[newVetorPosition]) {
boolean newEntry = true;
for (int y = 0; y < newVetorPosition; y++) {
if (vetorByOrder[y] == vetorByOrder[newVetorPosition]) {
newEntry = false;
break;
}
}
if (newEntry == true) {
vetorByOrder[newVetorPosition] = vetorAleatory[x];
}
}
if (x == 99) {
newVetorPosition++;
}
}
}
for (int i = 0;i<100;i++) {
System.out.print(vetorAleatory[i] + ", " + vetorByOrder[i] + System.lineSeparator());
}
First you do not need 3 loops to sort an array. You need only 2 and in case of quick search, it is even less than that. You can check this example Array sort and search, or you can use built in Arrays.sort method in Java
I have made an quiz app which uses a int[] array to set the position of the answers. The array has to be filled with the numbers 0,1,2 and 3, but they have to be randomly placed ( and only occure once). The only way I managed to do it was like this:
public int[] castRanInt(){
int ran_int[] = new int[4];
Random random = new Random();
boolean state = true;
ran_int[0] = random.nextInt(4);
while (state) {
for (int r = 1; r < 4; r++) {
ran_int[r] = random.nextInt(4);
}
state = false;
for (int a = 0; a < 4; a++) {
for (int b = 0; b < 4; b++) {
if (a == b) {
continue;
}
if (ran_int[a] == ran_int[b]) {
state = true;
}
}
}
}
return ran_int;
}
The only problem is that this often takes up to 100 runs in the while loop just to populate the array. Is there a simpler / faster way to do this?
What I've found so far:
public int[] castRanInt(){
List<Integer> intList = Arrays.asList(new Integer[]{ 0, 1, 2, 3 });
Collections.shuffle(intList);
// Convert List<Integer> to int[]
int[] ret = new int[intList.size()];
for(int i = 0; i < ret.length; i++) {
ret[i] = intList.get(i);
}
return ret;
}
This uses Collections.shuffle unfortunately there's no easy way to convert from an Integer[] to an int[]
Like Arnaud Denoyelle said you need a list initiated with indices so you can shuffle it
public List shuffleArray(int size) {
List<Integer> list = new ArrayList<>();
for(int i = 0; i < size; i++) {
list.add(i);
}
Collections.shuffle(list);
return list;
}
I came across this problem called compress. The objective is to take an array, remove any repeated values and return a new array.
I know this would be very easy with ArrayLists, but I want to do it without them.
So far, I've just written a loop to determine the number of unique values so I can construct a new array of the appropriate length. How can I then get the unique values into the new array?
public static int[] compress(int[] array){
int length = 0;
boolean contains = false;
for (int i = 0; i < array.length; i++){
contains = false;
for (int j = 0; j < i; j++){
if (a[i] == a[j]){
contains = true;
j = i;
} else {
contains = false;
}
}
if (!contains){
length++;
}
}
int[] uniqueArray = new int[length];
}
Not Tested but I think this should do the trick.
public static int[] copyArray(int [] num){
int x = 0;
int numDuplicate = 0;
int[] copy = new int[num.length]; // we use this to copy the non duplicates
HashMap<Integer, Integer> count = new HashMap<>(); //hashmap to check duplicates
for(int i = 0; i < num.length; i++){
if(count.containsKey(num[i])){
count.put(num[i], count.get(num[i])+1);
numDuplicate++; // keep track of duplicates
}else{
count.put(num[i], 1); // first occurence
copy[x] = num[i]; // copy unique values, empty values will be at end
x++;
}
}
// return only what is needed
int newSize = num.length - numDuplicate;
int[] copyNum = new int[newSize];
for(int i = 0; i < copyNum.length; i++){
copyNum[i] = copy[i];
}
return copyNum;
}
public static void main(String[] args) {
// sample elements
int[] nums = new int[20];
for(int i = 0; i < nums.length; i++){
nums[i] = (int)(Math.random() * 20);
}
System.out.println(Arrays.toString(nums));
System.out.println(Arrays.toString(copyArray(nums)));
}
How can I randomize arrayList
so that old index must not be the same as new index for all elements
for example
with a list with 3 items
after arrayList randomize
old index<->new index
1<-->2 <--different
2<-->1 <--different
3<-->3 <--same is not allowed
I want to make sure it will be
1<-->3 <--different
2<-->1 <--different
3<-->2 <--different
Collections.shuffle(List<?> list)
This should work with Lists which don't contain null values:
static <T> void shuffleList(List<T> list) {
List<T> temp = new ArrayList<T>(list);
Random rand = new Random();
for (int i = 0; i < list.size(); i++) {
int newPos = rand.nextInt(list.size());
while (newPos == i||temp.get(newPos)==null) {
newPos = rand.nextInt(list.size());
}
list.set(i, temp.get(newPos));
temp.set(newPos,null);
}
}
For list with null values:
static <T> void shuffleList(List<T> list) {
List<T> temp = new ArrayList<T>(list);
Integer [] indexes=new Integer[list.size()];
for (int i=0;i<list.size();i++){
indexes[i]=i;
}
Random rand = new Random();
for (int i = 0; i < list.size(); i++) {
int newPos = rand.nextInt(list.size());
while (newPos == i||indexes[newPos]==null) {
newPos = rand.nextInt(list.size());
}
list.set(i, temp.get(newPos));
indexes[newPos]=null;
}
}
That's something you have to implement yourself.
The shuffle is probably a series of random swaps (e.g. swap 1 -> 4,
swap 3 -> 2).
Keep track of each element's new position (e.g. 4 3 2
1 5 for a list with 5 elements and the above shuffle operations).
If any element is still at it's old place (5 in that example),
keep on shuffling.
Sounds like fun.
var numExist = [];
while(numExist.length!=array.length){
var randomizer = new Random();
int i =0;
var num = randomizer.nextInt(array.length);
if(!numExist.contains(num)){
array[i]=array[num];
numExist.add(num);
i++;
}
}
The following is a variation of Fisher-Yates which caters to the possibility that at least one item will remain in its original position.
The current Collections.shuffle() does not perform a complete randomization of the list.
public static void shuffle(List<Integer> list) {
Random r = new Random();
int size = list.size();
boolean flag = true;
for (int i = size - 1; i >= 0 && flag; i--) {
int pos = r.nextInt(i + 1);
if (list.get(i) == pos) {
if (i == 0) {
flag = false;
break;
}
// counter the upcoming decrement by incrementing i
i++;
continue;
}
int temp = list.get(i);
list.set(i, list.get(pos));
list.set(pos, temp);
}
// At this juncture, list.get(0) points to itself so choose a random candidate
// and swap them.
if (!flag) {
int pos = r.nextInt(size - 1) + 1;
int temp = list.get(0);
list.set(0, list.get(pos));
list.set(pos, list.get(0));
}
}
There may still be eventual problems but I used the following code to test the
shuffle with no problems detected.
for (int k = 0; k < 100000; k++) {
List<Integer> list =
IntStream.range(0, 52).boxed().collect(Collectors.toList());
System.out.println("Test run #" + k);
// Collections.shuffle(list);
shuffle(list);
for (int i = 0; i < list.size(); i++) {
if (i == list.get(i)) {
System.out.printf("Oops! List.get(%d) == %d%n", list.get(i), i);
}
}
}
I am trying to fill an array with random int values from 0 to 6. To control my code i am printing out the random values I generate. I try to exclude duplicates in the nested if-statement inside the for-loop, but when I run the code I get my seven values, but some of them are still duplicated. Can someone please help me?
Here is my code:
import java.util.Random;
public class TesterArrayer
{
public static void main(String[] args)
{
int size = 7;
Random randomNumber = new Random();
int randomArray[] = new int[size];
for(int x =0; x < size; x++)
{
int randomValue = randomNumber.nextInt(6);
if (randomValue != randomArray[x])
{
randomArray[x] = randomValue;
}
}//End for-loop
for (int y = 0; y < size; y++)
{
System.out.println(randomArray[y]);
}
}
}
public static void main(String[] args) {
int size = 7;
boolean add = true;
int counter = 0;
Random randomNumber = new Random();
int randomArray[] = new int[size];
for(int j = 0; j < size; j++)
{
randomArray[j] = -1;
}
while (counter < size) {
add = true;
int randomValue = randomNumber.nextInt(7);
for (int x = 0; x < size; x++) {
if (randomValue == randomArray[x]) {
add = false;
}
}// End for-loop
if(add)
{
randomArray[counter] = randomValue;
counter++;
}
}
for (int y = 0; y < size; y++) {
System.out.println(randomArray[y]);
}
}
Try something like this. You don't want to add the number unless it's not already in the list. Also for your random you need 7 instead of 6 if you want 0-6.
This code will fill your array with 0-6 not repeating any numbers.
If you only want the numbers 0..length-1 in random order you can do something like this:
int length = 7;
List<Integer> list = new ArrayList<>(length);
for(int i=0; i<length; i++){
list.add(Integer.valueOf(i));
}
//list is now in order, need to randomly shuffle it
Collections.shuffle(list);
//now list is shuffled, convert to array
int array[] = new int[length];
for(int i=0; i<length; i++){
array[i] = list.get(i);
}
Change minLimit, maxLimit and noOfItems to get random Numbers
public class RandomIntegers
{
public static final Random random = new Random();
public static final int maxLimit = 6;
public static final int minLimit = 0;
public static final int noOfItems = 7;
public static void main( String[] args )
{
Set<Integer> uniqueRandomIntegerSet = new HashSet< Integer >();
while(uniqueRandomIntegerSet.size() < noOfItems)
uniqueRandomIntegerSet.add( random.nextInt( maxLimit - minLimit + 1 ) + minLimit );
Integer[] randomUniqueIntegers = uniqueRandomIntegerSet.toArray( new Integer[0] );
}
}
As you should use a more optimal data structure for this approach, as mentioned in the other answer and comments, you can still accomplish this with an array of course. As you have defined the problem you would need to change int randomValue = randomNumber.nextInt(6); to int randomValue = randomNumber.nextInt(7); or else this will loop infinitely as there is no possible way to have no duplicates in a size 7 array with only 6 values.
You can do something like this to modify your code for it to work:
boolean flag = false;
for(int x = 0; x < size; x++)
{
int randomValue = randomNumber.nextInt(7);
for (int i = 0; i < x; i++)
{
if (randomValue == randomArray[i])
{
//randomArray[x] = randomValue;
flag = true;
x--;
}
}
if (!flag)
randomArray[x] = randomValue;
flag = false;
}//End for-loop
This code is simply flagging when it sees a duplicate value in the array already and will skip this value and decrement the x value so that it will create another random value for this spot in the array.
byte[] source = new byte[1024];
Random rand = new Random();
rand.nextBytes(source);