public class test {
public static void main(String[] args) throws supernova, autowin{
ArrayList<Integer> integer = new ArrayList<Integer>();
integer.add(new Integer(0));
integer.add(new Integer(1));
integer.add(new Integer(2));
integer.add(new Integer(3));
System.out.println(integer.get(0));
System.out.println(integer.get(1));
System.out.println(integer.size());
for(int i = 0;i<2;i++){
if(i == integer.get(i)){integer.remove(i);System.out.println("remove");}
}
System.out.println(integer.get(0));
System.out.println(integer.get(1));
System.out.println(integer.size());
}
The outputs are
0
1
4
remove
1
2
3
.I expect this code to remove two elements(0 and 1),but it eventually only remove the first element. What if I want to remove all elements that have a special feature ,speaking like all elements store a odd number ,from an arraylist.
Could you explain the reason? Thank you a lot.
When you use the remove method, all elements ahead of the index are moved to the left. Therefore, after the first element is removed, i == integer.get(i) will always be false, because the Integer's value was set to be its original index, but now they are all "one ahead", so to speak.
Use a debugger in an IDE to see the process happen.
After the first iteration (i=0) the list is modified and becomes to
[1, 2, 3]
then for the next iteration i=1 adn then you do
if (i == integer.get(i)) {
if 1 == elementAtIndex1--> if 1==2 wich returns false an is not removing anything....
therefore your code is behaving like that...
Lets go step by step:
in for loop, when i = 0, you remove value from arraylist on position 0. Now, your ArrayList will be 1,2,3. Now, you check position i = 1, and in that position you have 2, not 1. because 2 is not equal to 1, if will not be executed.
One solution would be to change the direction of the for loop:
for(int i = 1;i >= 0;i--){
if(i == integer.get(i)) {integer.remove(i);System.out.println("remove");}
}
Now, the output will be:
0
1
4
remove
remove
2
3
2
Update: OP asked new question
If you want to remove odd numbers, just place logic for it in if:
for(int i = integer.size() - 1;i >= 0;i--){
if(integer.get(i) % 2 != 0 {
integer.remove(i);
System.out.println("remove");
}
}
Related
I'm making a method called fillList. The method will require an arrayList in order to work and the output will be void.
What the method is supposed to do is to fill the gaps between the numbers of the List.
Example:
Input:
4 8 5 9
Output:
4 5 6 7 8 7 6 5 6 7 8 9
The code I have so far is this:
public static void fillList(ArrayList<Integer> List) {
for(int i = 0; i < List.size(); i++) {
if(List.get(i) < List.get(i+1) ) {
List.add(List.get(i+1));
} else if(List.get(i) > List.get(i+1)) {
List.add(List.get(i-1));
}
}
}
My idea was to add 1 to the value of the first element if the first element was less than the second element in the List. For example if the first element is 4 then the code would add a 5 to the list and stop once the number added was equal to one less than the second element. And basically do the opposite if the first element was more than the second element.
I don't know how to stop this loop until the numbers that are being added reach the second element of the list. I am not confident about my code as well I'm pretty sure I am making an error I'm not seeing.
Great question, I think you can learn alot by working this one out and really understanding every single line. I have made a litte illutration for you, to visualize the problem better. Hope this can help you. General tips:
variables are always lowercase by convention so write list instead of List
list.add(5) will add the number 5 to the end of your ArrayList. You can use list.add(4, 5) for example to insert the number 5 into the array position 4.
To update the list while iterating over its indices, you can use method List.add(int index, E element), which expects an index and a new element to insert.
While iterating, you need to compare two adjacent elements and insert a new one under the following conditions:
Left element is less than the right one and difference between them is greater than 1. A new element should be equal left + 1.
Left element is greater than the right one, and they differ more than by 1. A new element should be equal left - 1.
Also have a look at the nicely illustrated answer by #yezper. And as a general advice: draw before coding in order to understand the algorithm better.
That's how implementation might look like:
public static void fillList(List<Integer> list) {
for (int i = 0; i < list.size() - 1; i++) {
int left = list.get(i);
int right = list.get(i + 1);
if (left < right && left + 1 != right) {
list.add(i + 1, left + 1);
} else if (left > right && left - 1 != right) {
list.add(i + 1, left - 1);
}
}
}
main()
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>(List.of(4, 8, 5, 9));
fillList(list1);
System.out.println(list1);
}
Output:
[4, 5, 6, 7, 8, 7, 6, 5, 6, 7, 8, 9]
if(responseArr.size()!=0) {
for(int i=0;i<responseArr.size();i++) {
if(responseArr.get(i).equals("busy")) {
stylistId.remove(i);
}
}
}
If any values in the array contain the string busy, I want to remove the value from the stylistId array in that position. In the code above, the responseArr array and the stylistId array are the same size.
When I try to remove values from stylistId, it works fine when the loop executes for the first time. When loop executes the second time, I get indexOutOfBound Exception.
This is happening because the index of some elements in the list changes when you remove an element. For example, if your list has five elements (0, 1, 2, 3, 4) and you remove element 2, then elements 3 and 4 will get renumbered so that you have (0, 1, 2, 3) afterwards.
There are many possible solutions to this problem, but one way is simply to traverse responseArr backwards.
for(int i= responseArr.size() - 1;i >= 0; i--){
if(responseArr.get(i).equals("busy")){
stylistId.remove(i);
}
}
That way, you'll only be changing the indexes of elements that you've already checked.
Because There are two version of remove method.
remove element at index
remove given element
You need to call second method which return element. So, You can use Like,
for (int i = 0; i < responseArr.size(); i++) {
if (responseArr.get(i).equals("busy")) {
int id = stylistId.remove(i); //use your type instead of int.
}
}
public class TestPossibleNumbers {
public static void main(String[] args) {
int input[] = { 1, 2, 3 };
// int input[] = {10,11,12,13};
possibleNumbers(input, 0);
}
public static void possibleNumbers(int[] x, int index) {
if (index == x.length) {
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
System.out.println();
}
for (int i = index; i < x.length; i++) {
int temp = x[index];
x[index] = x[i];
x[i] = temp;
possibleNumbers(x, index + 1);
temp = x[index];
x[index] = x[i];
x[i] = temp;
}
}}
Can anyone help me to understand the code inside for loop?
This program run perfectly. But, I am unable to figure out how it is working
You are recursively calling the method again at:
possibleNumbers(x, index + 1);
Thus the method runs the method again, with index + 1 passed. It checks if
if(index == x.length)
If the statement is correct it prints the numbers.
It then enters the 2nd for loop again(if the if statement was incorrect it will still enter it). And calls the recurring method again. It will keep entering 2nd for loop but when "index" will be equal to or greater than "i.length" no iterations of the for loop will run because you specified for loop to run only when:
i<i.length
When 2 for loop does not do any iterations the method will stop recurring. So in your case when index is equal to 3 no iterations of 2nd for loop will run.
Try running debug step by step to see what is happening more in depth.
The Program prints permutation of numbers not combination.
Permutation - Order matters
Combination - Order doesnt matter and more of choosing k elements out of n
for example
int a= {a,b};
permutation = {ab,ba}
whereas combination ={{},{a},{b},{a,b}}
To understand how the program works
go through the following link will
https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
Don't get confused on recursion inside for loop.
if (index == x.length) is the terminating condition for recursion.
Inside the for loop before and after calling the recursive call possibleNumberselements are swapped.
Before swap helps to generate all possible outcomes and after swap elements will swap to previous position so that all other permutation will be generated from the for loop. It may sounds confusing please go through the link.
I'll provide an alternative explanation that I feel is more intuitive.
Consider the case of only 1 number in the list: [a]. This is pretty trivial: there's a single combination [a].
Now consider the case of 2 numbers in the list: [a, b]. In this case you can take each of the elements in turn and then look at all combinations of the remaining element using the previous method and then add the element back.
Now consider the case of 3 numbers in the list: [a, b, c]. In this case you can take each of the elements in turn and then look at all combinations of the other 2 elements using the previous method and then add the element back.
And so on for 3, 4, 5... elements.
So, in general, consider the case of n numbers in the list: [a1, a2, ... an]. In this case take each of the elements in turn and then look at all combinations of the other n-1 elements using the exact same method and then add the element back.
Converting to pseudo code:
getCombos(values)
for each value
for each combo in getCombos(values with value removed)
add value + combo to results
return results
The only thing to add is the base case which is necessary for all recursive implementations. One possibility is the case of a single item. However there's an even simpler one: if there are no values then the result is a single empty list.
So converting that to Java, using sets to make clear that the elements need to be unique (to avoid duplicate results), using streams and making it generic so it'll work for any type:
Stream<List<C>> combos(Set<C> values) {
if (values.isEmpty())
return Stream.of(new ArrayList<>());
else
return values.stream().flatMap(value ->
combos(values.stream()
.filter(v -> !v.equals(value))
.collect(toSet())).peek(r -> r.add(value)));
}
Your code is really just an alternate implementation of the same algorithm that swaps the element under consideration to the front of the array instead of creating a new collection.
Given two ArrayLists, one containing Strings whereas the other contains Integers.
The next step would be to grab the first position of each ArrayList and print them out side by side next to each other.
Then 2, 3, 4 , 5, You name it.
1st List: public List getDoubleHistory(){...}
2nd : List<StringBuilder> timeAtThatMoment = new ArrayList<>();
I guess that we start with a for loop in which i is the index.
First we have to assume that the lists are the same size, or else we cannot continue to do as you asked.
for (int i = 0; i < getDoubleHistory().size(); i++){
System.out.println(getDoubleHistory.get(i));
System.out.println(timeAtThatMoment.get(i));
}
If the lists are not the same size you will have to add some if statements to make sure you dont get index out of bounds exceptions.
You can read more on this here. https://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html
I am not sure why my heap method is not printing the heap in the correct order. Can someone tell me what am I doing wrong here?
Here is my getHeap method:
public static String getHeap(ArrayBasedList<Edge> edgeList)
{
// Build the heap
insert(new Edge(-1,-1,-1));
for(int i = 1; i < edgeList.size(); i++)
{
// Insert into the heap
insert(edgeList.get(i));
}
// Print the heap
String output="";
for(int i = 1; i < edgeList.size(); i++)
{
//System.out.printf("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2());
output+=String.format("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2());
}
return output;
}
and here are my insert and upHeap methods:
public static void insert(Edge e)
{
heap[edgeCount] = e;
edgeCount++;
upHeap(edgeCount - 1);
}
public static void upHeap(int pos){
if(pos > 0){
if(heap[(pos-1)/2].getWeight() > heap[pos].getWeight()){
/** Temporary edge for swapping */
Edge temp = heap[pos];
heap[pos] = heap[(pos-1)/2];
heap[(pos-1)/2] = temp;
upHeap((pos-1)/2);
}
}
}
and here is the print out of the edges of my heap :
0 1
1 2
2 3
1 3
0 3
but it is incorrect. the correct result is as follows:
0 1
0 2
1 2
2 3
1 3
0 3
what am I doing wrong here? would greatly appreciate any thoughts.. i am at a loss here.
One problem is that your upHeap method is apparently treating your heap as if the root node is at index 0, but your output code starts at index 1. So you never output the heap's root node.
Second, the array representation of a heap doesn't necessarily store things in sequential order. For example, inserting the items 1, 2, and 3 into a min-heap can create the array representation [1, 3, 2] or [1, 2, 3]. Both are valid heaps. Which one is created by inserting depends on insertion order.
If you want to remove items from the heap in order, you have to create an extractMin method, which takes the item at index 0 in the heap, and then re-adjusts the heap to move the next smallest item to index 0 and arranges the rest of the items. Typically that's done by moving the last item in the heap (i.e. the item at heap[heap.size-1] to heap[0], and then sifting it down to its proper place.
This is probably not the whole answer, but you're increasing edgeCount twice
heap[++edgeCount] = e;
edgeCount++;
You do not add edgeList.get(0) to your heap, so that edge (most probably the one printed out as 0 2) is missing from your output.
To add all edges to your heap your first loop should be:
for(int i = 0; i < edgeList.size(); i++)
{
// Insert into the heap
insert(edgeList.get(i));
}
To print out all edges your second loop needs to be:
StringBuilder output=new StringBuilder();
for(int i = 1; i <= edgeList.size(); i++)
{
//System.out.printf("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2());
output.append(String.format("%4d%5d\n", heap[i].getVertex1(), heap[i].getVertex2()));
}
return output.toString();
This loop goes from 1 to edgeList.size() since your heap seems to contain a root element that should not be printed.
I've also changed to code from string concatenation to using a StringBuilder - string concatenation in a loop is slow, since strings are immutable. That might not make a big difference for small amounts of data, but it is better to always do it right.