IndexOutOfBoundsException when working with arrayList - java

The task is described here Creating combination of numbers or here Permutations of integer array algorithm.
I decided to solve this problem in this way:
From first number to the last check the possibility of permutation:
Create arraLists of the first permutation and of the difference
del1 and rem0
Bool is an object with two parametrs: st - start and end
It`s new permutation
I create new Bool, that at the start have the same start and end, like it is one number. So, we cant use this number anymore before starting new permutation with another start number. And we remove it from the list of numbers rem . And start create permutation with checking.
for (int index = 0; index < arr.length; index++) {
List<Integer> del1 = new ArrayList<Integer>();
List<Integer> rem0 = new ArrayList<Integer>();
for (int i = 0; i < del.length; i++) {
del1.add(del[i]);
}
for (int i = 0; i < arr.length; i++) {
rem0.add(arr[i]);
}
Bool start = new Bool(arr[index], arr[index]);
rem0.remove(index);
check(start, del1, rem0);
}
Checking:
ucet - number of "good" permutations, if the difference of new permutation is the same, as the first, it is "good".
So, I for the ending number I add difference number and if it = number in the list of possible numbers - I add this number to the end of permutation, remove it from the list of possible and remove difference prom the list of differences(by creating new lists).
And then continue creating.
private static void check(Bool start, List<Integer> del2, List<Integer> rem) {
if (del2.isEmpty()) {
ucet++;
}
for (int index = 0; index<rem.size(); index++) {
for (int i = 0; i<del2.size(); i++) {
if(start.end+del2.get(i)==rem.get(index)){
List<Integer> del3 = new ArrayList<Integer>();
List<Integer> rem2 = new ArrayList<Integer>();
del3=del2;rem2=rem;
Bool con=new Bool(start.st,rem.get(index));
rem2.remove(index);
del3.remove(i);
check(con,del3,rem2);
}
}
}
}
But I have one bug, that I cant understand. Its IndexOutOfBoundsException. In the string if(start.end+del2.get(i)==rem.get(index)){ .
And it causes del2.get(i).
But the problem is, that i<del2.size().
Can you help me to deal with it? Thanks

You are removing entities from the list as you are looping through it, not good. You could try using while loop in conjunction with iterable.hasNext() or instead of rem0.remove(index) do rem0.set(index, null).

Related

How to create an array with unique integers as elements [duplicate]

This question already has answers here:
Java Array of unique randomly generated integers
(10 answers)
Closed 5 years ago.
i want to create an array of 10000 unique random elements. Till now i only figure out how to create random integers and fill an array and finding the doubles and deleted them. But this decrease the size of the array which i dont want it.
So the question is how i can fill an array with unique integers as elements without decreasing the size of the array.
You could use this code. Usage of Set will eliminate duplicates and you are fetching random numbers until you get 10000 different random integers.
Set<Integer> numbers = new HashSet<>();
Random r = new Random();
while (numbers.size() < 10000) {
numbers.add(r.nextInt(100000));
}
Integer[] a = new Integer[numbers.size()];
a = numbers.toArray(a);
I found this great solution:
This solution doesn't need any Collection class.
public static int[] createRandomNumbers(int howMany) {
int n = howMany + 1;
int a[] = new int[n];
for (int i = 0; i < n; i++) {
a[i] = i;
}
int [] result = new int[n];
int x = n;
SecureRandom rd = new SecureRandom();
for (int i = 0; i < n; i++) {
int k = rd.nextInt(x);
result[i] = a[k];
a[k] = a[x-1];
x--;
}
return result;
}
System.out.println(Arrays.toString(createRandomNumbers(10000)));
Reference: Best way to create a list of unique random numbers in Java
Hope it helps
Try this logic:
USE AN ARRAYLIST ENTIRELY, THEN CONVERT TO AN ARRAY AT THE END OF THE ENTIRE OPERATION.
Declare an arraylist
For every random number generated, check if the number already exists in the arraylist (using the .contains() method). If it does, repeat the process, else, move to the next number.
Code example:
Arraylist<Integer> arr = new Arraylist<>();
arr.add(generate()); //I included this line so that the arraylist won't be empty
//Note that the method *generate()* generates a new random number
for(int i = 0; i < 9999; i++){
int next = generate(); //the method that generates your number
if(arr.contains(next)){
i--; //The entire operation will be repeated for this index.
}
else{
arr.add(next); //Add the number to the arraylist
}
}
int[] finalArray = arr.toArray(); //Your final resultant array!
I hope this helps.. Merry coding!
You can use Set. This Collection that contains no duplicate elements.
Documentation https://docs.oracle.com/javase/7/docs/api/java/util/Set.html
Set<Integer> numbers = new HashSet();
do {
numbers.add(ThreadLocalRandom.current().nextInt());
} while(numbers.size() < 10000);

Dividing a Java List into sublists based on values

Here's my list:
myList =
["HEADING","POST","POST","POST","CALL_TO_ACTION","HEADING","POST","POST","POST","CALL_TO_ACTION","HEADING","POST","POST","CALL_TO_ACTION"]
I would like to have some logic in place that would help me divide myList into below three sub-lists (stored as, say, List<List<String> subLists):
["HEADING","POST","POST","POST","CALL_TO_ACTION"]
["HEADING","POST","POST","POST","CALL_TO_ACTION"]
["HEADING","POST","POST","CALL_TO_ACTION"]
Please note, the number three comes from the number of occurrences of the element "HEADING" (which I could find out using Collections.frequency(myList, "HEADING")).
One way to do this is,
Step 1: Collect all the indices from your myList where "HEADING" appears.
List<Integer> indexList = new ArrayList<>();
for(int index = 0; index < list.size(); index++) {
if(list.get(index).equals("HEADING"))
indexList.add(index);
}
Step 2: Iterate through this indexList and create sub lists by using current index and the next index.
for(int builderIndex = 0; builderIndex < indexList.size(); builderIndex++) {
List<String> test = null;
if(builderIndex == indexList.size() - 1) {
test = list.subList(indexList.get(builderIndex), list.size());
} else {
test = list.subList(indexList.get(builderIndex), indexList.get(builderIndex + 1));
}
System.out.println(test);
}
Boundary condition is to check if the current index is equal to one less than the size of the indexList. If yes, then the end index of the sub list would be the size of the original list.
I hope this helps.

How do I loop thorough a 2D ArrayList in Java and fill it?

I am trying to use 2D arrayLists in Java.
I have the definition:
ArrayList<ArrayList<Integer>> myList = new ArrayList<ArrayList<Integer>>();
How can I loop through it and enter in numbers starting from 1?
I know that I can access a specific index by using:
myList.get(i).get(j)
Which will get the value. But how do I add to the Matrix?
Thanks
You can use a nested for loop. The i-loop loops through the outer ArrayList and the j-loop loops through each individual ArrayList contained by myList
for (int i = 0; i < myList.size(); i++)
{
for (int j = 0; j < myList.get(i).size(); j++)
{
// do stuff
}
}
Edit: you then fill it by replacing // do stuff with
myList.get(i).add(new Integer(YOUR_VALUE)); // append YOUR_VALUE to end of list
A Note: If the myList is initially unfilled, looping using .size() will not work as you cannot use .get(SOME_INDEX) on an ArrayList containing no indices. You will need to loop from 0 to the number of values you wish to add, create a new list within the first loop, use .add(YOUR_VALUE) to append a new value on each iteration to this new list and then add this new list to myList. See Ken's answer for a perfect example.
Use for-each loop, if you are using Java prior 1.5 version.
for(ArrayList<Integer> row : myList) {
for(Integer intValue : row) {
// access "row" for inside arraylist or "intValue" for integer value.
}
}
Assuming the matrix is not initialized,
int m = 10, n = 10;
ArrayList<ArrayList<Integer>> matrix = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < m; i++) {
List<Integer> row = new ArrayList<Integer>();
for (int j = 0; j < n; j++) {
row.add(j);
}
matrix.add(row);
}

Which of these loops are more efficient?

I have these three collections in Java:
ArrayList<Integer> list1 = new ArrayList<Integer>(6000);
ArrayList<Integer> list2 = new ArrayList<Integer>(6000);
ArrayList<Integer> list3 = new ArrayList<Integer>(6000);
Which is more efficient to loop through and set to 0?
for(int i =0; i < rHist.size(); i++) {
list1.set[i] = 0;
list2.set[i] = 0;
list3.set[i] = 0;
}
Or this?
for (int n : list1) {
n = 0;
}
for (int n : list2) {
n = 0;
}
for (int n : list3) {
n = 0;
}
Thanks
As already mentioned in the comments, both of the variants do not reach the goal you stated. That being said, better look to write readable, understandable and short code and refrain to the methods given in the Collections API. Something like that fills your list with 6000 copies of zeros:
List<Integer> list = Collections.nCopies(6000, 0);
If you need to mutate the list afterwards, you need to wrap it in a modifiable List like so:
List<Integer> list = new ArrayList<Integer>(Collections.nCopies(6000, 0));
The first one is better because you are looping one time instead of three if you put the size to 6000 in the loop, and the set should look like this list1.set(i,0) instead of list1[i]=0
if you decompiled both them uisng javap -c "appname" lets assume that they are under the main, you can see your self whats happening

Create an array of UNIQUE 5-digit random numbers in Java?

I have the following code generating 5-digit random numbers and adding them to an ArrayList. These numbers however must be unique ids.
for(int i = 0; i < myArr.length; i++) {
int id = (int) (Math.round(Math.random() * 89999) + 10000);
idArr.add(id);
}
I'm trying to work out how I could check to see if the number was already in the array before adding it but I can't get my head around the best way to do this.
Don't use an (Array)List, use a Set:
Set<Integer> set = ...;
while (set.size() < myArr.length) {
set.add(yourRandomNumber);
}
Use an ArrayList instead of an array. That way you would just need to use ArrayList#contains(obj) method to test whether the id is already in the ArrayList or not.
Or, you can just work with a HashSet, which will work faster with its HashSet#contains() method.
You can create a Set of the numbers. E.g.:
Set<Integer> intSet = new HashSet<Integer>();
while(intSet.size() < myArr.length) {
intSet.add(getNextRandomInt());
}
Then yo can do anything with that Set.
So, if you need an array, just call:
Integer[] intArray = intSet.toArray(new Integer[myArr.length]);
or, if you need an ArrayList or int[] array:
// ArrayList:
List<Integer> ints = new ArrayList<Integer>();
ints.addAll(intSet);
// int[] array:
int[] intArray = new int[myArr.length];
for( int i = 0; i<intArray.length; ++i) {
intArray[i] = int.get(i);
}
Anything which involves looping until you find enough unique random numbers is never guaranteed to complete. It's possible, if extremely unlikely, that the random number generator will never output enough unique numbers in a reasonable amount of time.
(I know this will never happen in practice, but it's a theoretical possibility.)
A safe alternative is to choose one random number, and then increment it in a loop until you have enough numbers.
int n = new Random().nextInt(89999 - myArr.length) + 10000;
for (int i = 0; i < myArr.length; i++) {
idArr.add(n++);
}

Categories

Resources