So I have to write a function to delete Node with consecutive same items. Like: {1,1,1,2,3,3,4} becomes: {1,2,3,4}
I have written the following code, cant figure out whats wrong with it. It works for the first few items only.
public void deleterepetitive()
{
Node itr = head;
Node itrfront=itr.getNext();
while(itr.getNext()!=null)
{
if(itr.getItem()==itrfront.getItem())
{
itr.setNext(itrfront.getNext());
}
itr = itr.getNext();
itrfront = itrfront.getNext();
}
Any help will be appreciated.
Change the line itrfront = itrfront.getNext(); to itrfront = itr.getNext(); within the while loop. I guess your code breaks after first duplicate omission.
Change the if block as below:(we need check the new next item and not skip it.)
if(itr.getItem()==itrfront.getItem())
{
itrfront = itrfront.getnext();
itr.setNext(itrfront);
continue;
}
Earlier you code was
1st iteration:
1 1 1 1 1 2 3 3 4
^ ^
ITR NExt
duplicate fond so remove node
2nd iteration:
1 1 1 1 2 3 3 4
^ ^
ITR NExt
there are many ways to do this.
i find either stepping through the list from the bottom (starting at the N'th item and iterating back to zero'th item) or taking the collection and inserting it into a Set collection to force the collapse of identical values also works.
cheers
You're not incrementing your iterators correctly, you want itrfront to always be in front of itr, but its actually on top of it:
Let itr be : ^, itrfront be: A, and itr.getNext() be: n, this is what's occurring:
n
1 1 1 2 2 2 2 3
^ A
n
1 1 1 2 2 2 2 3
^ A
n
1 *1* 1 2 2 2 2 3
^
A
n
1 *1* 1 2 2 2 2 3
^
A
n
1 *1* 1 2 2 2 2 3
^
A
where the *1* means garbage collected
What you want to do is something like this:
while(itr.getNext()!=null)
{
while(itr.getItem()==itrFront.getItem())
{
itrfront = itrfront.getNext();
}
itr.setNext(itrfront);
itr = itr.getNext();
itrfront = itr.getNext();
}
Related
I have a vector that looks like this:
y =
Columns 1 through 19:
1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2
Columns 20 through 38:
2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4
Columns 39 through 57:
4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6
Columns 58 through 67:
6 6 6 6 6 6 6 6 6 6
The vector y is always start at 1 and be counted up. You see that there are lots of same numbers. It's the classes for the samples.
Here we have 1 1 1 1 1 1 1 1 1 1 1 1 = 12 samples for class number 1.
We have 2 2 2 2 2 2 2 2 2 2 2 = 11 samples for class number 2.
My problem here is that I want to find start and stop for every class. For example: Class 1 begins always at index 0 and ends, in this case, at index 11.
Class 2 begins directly after class 1 ends.
Question:
I'm using EJML (Effient Java Matrix Library) and I'm planning to use this function:
C = A.extractMatrix(1,4,2,8)
Which is equal to this MATLAB code:
C = A(2:4,3:8)
But I need to find the start and stop indexes from this y vector. In what index does e.g class 3 stops and starts? Do you have any smart ideas how to do that?
Sure, I could use a for-loop, to do this, but for-loops in Java is quite slow because I'm going to have a very very large y vector.
Suggestions?
Edit:
Here is an suggestion. Is that good, or could it be done better?
private void startStopIndex(SimpleMatrix y, int c, Integer[] startStop) {
int column = y.numCols();
startStop[0] = startStop[1] + 1; // Begin at the next class
for(int i = startStop[0]; i < column; i++) {
if(y.get(i) != c) {
break;
}else {
startStop[1] = i;
}
}
}
Assuming that we are calling the method from:
Integer[] startStop = new Integer[2];
for(int i = 0; i < c; i++) {
startStopIndex(y, c, startStop);
}
If you want to do it faster then binary search is your friend. Threw this together really quick and it does things in O(log n) time, where as a linear search does it in O(n). It's pretty basic and assumes your data looks pretty much like you describe it. Feed it weird data and it will break.:
int[] breakPoints(int[] arr, int low, int high){
int[] rtrn = new int[high];
for(int i=low;i<high;i++){
rtrn[i]=binarySearch(arr, i, 0, arr.length-1);
}
return rtrn;
}
int binarySearch(int[] arr, int k, int start, int end){
int mid = (start+end)/2;
if(mid==arr.length){
return -1;
}
if(arr[mid]==k && arr[mid+1]==k+1){
return mid+1; //or just mid if you want before breakpoint
}
if(arr[mid]<=k){
return binarySearch(arr, k, mid+1, end);
}
return binarySearch(arr, k, start, mid-1);
}
You'd call it like this:
int[] data = {1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,6,6,6,6};
int[] bp = breakPoints(data,1,6);
//return 0, 3, 8, 13, 16, 18
I think there is a name for this, but I can't remember what it might be, but you start looking for the next boundary with an accelerating search, and use a binary search after that.
You know the numbers are in ascending order, and there are potentially a lot of the same number, so you start by checking the next element. But instead of keep going 1 step at a time, you accelerate and step 2, 4, 8, 16, ... until you find a higher number.
Once you've found a higher number, you've gone too far, but the last step had the initial number, so you know the boundary is somewhere between the last two steps, and you then apply a binary search for the boundary.
Once you've fund the boundary, you start over stepping 1, 2, 4, ... for the next boundary.
If you expect most numbers to have about the same number of occurrences, you could keep a running average count, and make the first step with that average, to get a running start.
I'll leave it to you to actually code this.
The below is in MATLAB. the for loop will go through each unique value stored in x1 and then find the first and last occurrence of that value.
x = [ 1 1 1 2 2 3 3 3 3 3 4 4 4 4 5 5 5 ]
x1 = unique(x)'
for k1 = 1:length(x1)
x1(k1,2:3) = [find(x == x1(k1,1),1,"first"), find(x == x1(k1,1),1,"last")];
end
the above code yields x1 to be a 3 column matrix
1 1 3
2 4 5
3 6 10
4 11 14
5 15 17
Hoping to get input on whether my logic is correct or not. My assignment is just to modify the function to keep track of word frequency. I think I have added a counter to do this.
public void enterWord (Object word, Integer line) {
Vector set = (Vector) dict.get(word);
int counter = 0;
if (set == null) { // word not in dictionary
set = new Vector( );
dict.put(word, set); // enter word and empty Vector
} // if
if (allowDupl || !set.contains(line)) {
counter++;
set.addElement(line);
set.addElement(counter);
}
} // enterWord
Original code
Sample input:
this is just a test or is it
is
just
a
test
output:
a: 1 4
this: 1
it: 1
is: 1 1 2
or: 1
just: 1 3
test: 1 5
With the counter I added the output looks like this:
a: 1 1 4 1
this: 1 1
it: 1 1
is: 1 1 1 1 2 1
or: 1 1
just: 1 1 3 1
test: 1 1 5 1
Consider an array of integers A having N elements in which each element has a one- to-one relation with another array element.
For each i, where 1≤i≤N there exists a 1−>1 relation between element i and element N−i+1
The Task is to perform following operations on this array which are as follows:
Given two integers (L,R) we have to swap each element in that range with its related element.(See Sample explanation below)
Sample Input
5
1 2 3 4 5
2
1 2
2 3
Sample Output
5 2 3 4 1
Explanation
For first query,we will swap 1 with 5 and 2 with 4.
Now the array becomes- 5 4 3 2 1
Similarly now ,for the second query we will swap 4 with 2 and 3 with itself.
So the final array will be 5 2 3 4 1
My Program goes like this:
import java.util.Scanner;
public class ProfessorAndOps {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
int n=in.nextInt();//length of array
int a[]=new int[n];//array declaration
for(int i=0;i<n;i++){
//inputting array elements
a[i]=in.nextInt();
}
int q=in.nextInt();//number of queries
for(int i=0;i<q;i++){
int l=in.nextInt();//left limit
int r=in.nextInt();//right limit
//swapping while iterating over the given range of array elements:
for(int j=l-1;j<=r-1;j++){
int temp=a[j];
a[j]=a[n-j-1];
a[n-j-1]=temp;
}
}
//Printing the output array:
for(int i=0;i<n;i++){
if(i!=n-1){
System.out.print(a[i]+" ");
}
else{
System.out.println(a[i]);
}
}
}
}
I could only come up with BruteForce solution. I'm pretty sure there will be some pre-processing step or some optimisation technique with l and r variables, whatever I could think of, giving me wrong answer. Please help me optimise this code. To be specific, I would need my code's time complexity to be reduced from O(N+ Q*(R-L)) to something like O(Q+N)
Here's an O(Q + N) time, O(N) space algorithm. Imagine a list of the corresponding swap counts only for L and R over the elements (we'll use a negative number for the R counts). What if we maintained a virtual stack while traversing it? (By "virtual," I mean it's not a real stack, just an integer that bears some theoretical similarity.)
For example:
1 2 3 4 5 6 7 8 9 10
O(Q) processing:
q [1,3]
1 9 8 7 5 ... <- what would happen to the array
0 1 0 -1 0 <- counts (what we actually store)
q [2,4]
1 9 3 4 6 ... <- what would happen to the array
0 1 1 -1 -1 <- counts (what we actually store)
O(N) traversal:
index 0 didn't move, no change, stack: 0
index 1 moved once, odd count, changed, stack: 1
index 2 moved 2 (stack + 1), even count, no change, stack: 2
index 3 moved 2 (stack), even count, no change, stack: 2 - 1
index 4 moved 1 (stack), odd count, changed, stack: 1 - 1
I am trying to use nested for loops (java) to print out the following:
331
330
322
311
300
222
111
and I am having some trouble. So far I have:
for(int a = 3; a >=0; a--)
{
for(int b = 3; b>=0; b--)
{
for(int c = 2; c>=0; c--)
{
System.out.println(a + " "+ b +" "+ c);
}
}
}
but that prints out something more like this:
3 3 2
3 3 1
3 3 0
3 2 2
3 2 1
3 2 0
3 1 2
3 1 1
3 1 0
3 0 2
3 0 1
3 0 0
2 3 2
2 3 1
2 3 0
2 2 2
2 2 1
2 2 0
2 1 2
What is wrong with my code? How can I get it to print out the first sequence, not the second? I'm pretty sure it has something to do with the middle loop, but I'm really not sure.
Thanks!
If you have nested for loops, unless you set the limits on the inner loops based on the values of the variables in the outer loops, the pattern generated by the inner loops (second and third numbers, in this case) is gonna be the same in each iteration of the outer loop.
I can't code right now, but it seems to me that if you set b to run from a to zero, instead of from 3 to zero you might get a little closer to what you want.
But still, since it seems there isn't a pattern in what you want to get, it's hard to think of an algorithm to print them. What do these numbers mean?
I have written java program, to add integer in ArrayList and remove that integer from ArrayList . but it not giving me proper result. here is my code..
public static void main(String args[])
{
ArrayList<Integer> a=new ArrayList<Integer>();
a.add(6);
a.add(7);
a.add(8);
a.add(9);
for(int i=0;i<=a.size();i++)
{
System.out.println("Removed Elements=>"+a.remove(i));
}
}
it giving me output as follows
Removed Elements=>6
Removed Elements=>8
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at CollectionTemp.main(CollectionTemp.java:19)
why i am getting output like this?
Your array:
a[0]=6
a[1]=7 <-- i
a[2]=8
a[3]=9
Then you remove at 1, and i increments to 2:
a[0]=6
a[1]=8
a[2]=9 <-- i
Remember that array indexes start at 0, so the last element is at a.length - 1
You get your exception because the loop condition i <= a.size(), so at the final iteration:
a[0] = 7
a[1] = 9
2 <-- i
When you remove items from a list, or any collection, you either use the iterator, or you use a reverse loop like this.
for (int i = (a.size() - 1); i >= 0; i--) {
System.out.println("Removed Elements=>" + a.remove(i));
}
By going backwards, you avoid the incrementing by 2 problem that has been documented in the other answers.
for first iteration, a.remove(i) causes the element 7 to be removed which is returned by remove method.
For second iteration, the size of list is 3 and you are removing the element at index 2 which is 9. SO remove method returns 9.
In short
Iteration | Size of list | index being removed | element removed
----------+--------------+---------------------+----------------
1 | 4 | 1 | 7
2 | 3 | 2 | 9
If you want a forward loop to remove all elements you could use the following code:
while(!a.isEmpty())
{
System.out.println("Removed Elements=>" + a.remove(0));
}
Your problem is that, as you remove elements, you resize the ArrayList. However, your loop counter is not updated, so you iterate past the bounds of the ArrayList.
ArrayList.remove(index) removes the element from the array, not just the contents of the ArrayList, but it actually resizes your ArrayList as you remove items.
First you remove the 1st element of the ArrayList.
Removed Elements=>6
Here the list has been resized from size 4 to size three. Now the element at index 0 is 7.
Next, you step to the element at index 1. This is the number 8.
Removed Elements=>8
Here the ArrayList has been resized to length 2. So there are only elements at index 0 and 1.
Next you step to index 2.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at CollectionTemp.main(CollectionTemp.java:19)
There is no index 2, so you get an IndexOutOfBoundsException.
the index starts with 0 and ends with size - 1
your loop goes from 1 to size - 2
ArrayList indexes start at zero, but your loop starts removing at 1. After adding the elements your arraylist looks like this:
0 - 6
1 - 7
2 - 8
3 - 9
Because your loop starts counting at 1, you will first remove the element labeled 1, which is 7.
The list will then look like this:
0 - 6
1 - 8
2 - 9
Then the loop will remove the element labeled 2, which is now 9.
So the two mistakes are starting at 1 instead of 0, and incrementing the counter after something has been removed (all elements after the removed element will shift down).
In the first iteration , i starts from 1, so your second element is removed ie. 7. Now list has
6
8
9
Next iteration is 2, so third element 9 is removed.
Your output is correct : Here is the explaination.
When the loop is executed for the first time, value of i will be 1. and it execute the statement a.remove(1). after removing the value 7 which is at place a[1], '8will be ata[1]'s place. After that i is incremented and becomes 2 and it removes the element a[2] which is 9.
This is simple logic:
First Iteration i=1:
a[0]=6,
a[1]=7,
a[2]=8;
a[3]=9;
Remove a[i] i.e a[1] removes 7
Second Iteration i=2:
a[0]=6
a[1]=7
a[2]=9
Remove a[i] removes 9
The value of i in the loop goes through the following values
0
1
2
3
4
The array has index with values 0 , 1 , 2 , 3
The loop will run for values 0,1,2,3,4
The array is not displayed ordered bcoz when one value is removed the next value is available at index 0
At i=2 , the size of array is 2 and max index is 1 , and hence IndexOutofBound exception is encountered
use the following loop :
while(a.size()>0)
{
System.out.println("Removed Elements=>"+a.remove(0));
}
whenever you remove an element from arraylist it deletes element at specified location.and this should be noted each time the size of arraylist decreases.
I dont understand what are you trying to remove. If you wan to clear list just call clear() method. If you are trying to remove objects contained in list, than you should know that ArrayList contains objects, not primitive ints. When you add them your are doing the following:
a.add(Integer.valueOf(6));
And there are two remove methods in ArrayList:
remove(Object o) //Removes the first occurrence of the specified element from this list
and the one you are calling:
remove(int index) //Removes the element at the specified position in this list
May be you should call first one:
a.remove(Integer.valueOf(i));