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
Related
I have a scenario where I am reading from a csv file and loading into a List collection. The items are as below.
index name val1 val2 state note
1 xxx 12.43 13.56 1 1
2 xxx 12.43 13.56 0 0
3 xxx 12.43 13.56 0 0
4 yyy 5.9 13 1 1
5 zzz 5.4 5 0 1
6 ddd 6.8 7.78 1 1
7 ddd 6 1 1 0
8 xxx 12.43 13.56 1 1
9 zzz 1 1.56 1 1
10 ppp 1 0 0 0
11 yyy 1 1 1 0
12 ggg 1 1 1 1
13 ddd 1 1 0 0
14 www 0 0 0 0
15 www 1 0 0 0
Question 1 : I am trying to find three consecutive entries for a given item-name where the details of val1 and val2 haven't changed. If the values of these two fields haven't changed where they are non consecutive then it will still be fine (still count as consecutive).
How can i do using stream and get the number of consecutive entries with these three values ( name, val1 and val2) remaining same ?
Question 2: How can get a similar count for items which dont have three consecutive entries using stream for a given name?
I have tried doing something like this so far..
Map<String,Map<String,Map<String,Long>>> counting = list.stream()
.filter(p -> p.getName().equals(name))
.collect(Collectors.groupingBy(Item::getName,
Collectors.groupingBy(Item::getVal1,
Collectors.groupingBy(Item::getVal2, Collectors.counting()))));
Edit : streams or no streams how can I do this ?
The phrase "three consecutive entries" indicated that it is unlikely that a straight stream solution is appropriate: streams are designed for operations on independent items.
Given you are only looking at items with the same name the first step is to group by name. You can use streams to do this with something like: list.stream().collect(Collectors.groupingBy(Item::getName)).
The for each list of items (i.e. the values in the generated map), you can use logic like the following:
int currentRun = 0;
for (int i = 1; i < list.size(); i++) {
if (valuesMatch(list.get(i), list.get(i - 1))
currentRun++;
else
currentRun = 0;
if (currentRun > 3)
...
}
Following code snippet will give a Map of the Items for a given item name whose val1 and val2 are equal. And the map will be grouped by val1 (or val2, doesn't matter as val1 and val2 will be same). And for your second issue, you can just append an '!' before p.getName().equals(name), like !p.getName().equals(name) . You have to check the size of the list of the items against the key though.
Map<Long, List<Item>> itemsMap = list.stream()
.filter(p -> p.getName().equals(name) && p.getVal1().longValue()==p.getVal2().longValue())
.collect(Collectors.groupingBy(Item::getVal1));
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
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();
}
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?
Hello i am a beginner in java programming, recently i am studying Threads, i am having problem in output of this program.
class s1 implements Runnable
{
int x = 0, y = 0;
int addX() {x++; return x;}
int addY() {y++; return y;}
public void run() {
for(int i = 0; i < 10; i++){
System.out.println(addX() + " " + addY());
}
}
public static void main(String args[])
{
s1 run1 = new s1();
s1 run2 = new s1();
Thread t1 = new Thread(run1);
Thread t2 = new Thread(run2);
t1.start();
t2.start();
}
}
I am getting output like this,
1 1 2 2 1 1 3 3..., please explain why?
The threads are executing asynchronously - so their output will be naturally intertwined, that's to be expected. In your case:
1 1 2 2 1 1 3 3
...The bit I've "bolded" is the output from one thread, the bit I've left plain is the (start of) the output from the other. I can only work this out because of how the program executes - if you had two threads just printing the character "1" for example, it would be impossible to distinguish what thread was printing what character.
Note that the order in which the numbers appear and the way they intertwine is completely arbitrary - it could have just as easily been something like:
1 1 1 1 2 2 3 3 2 2..
...Or any other possible combination. Don't rely on the order that you happen to get for any particular program, it's completely undefined.
Each instance of the s1 class has its own variables, so they will increment independent of each other. If you only made one instance, the output would be 1 1 2 2 3 3 ....
If you take two threads each printing 1 1 2 2 3 3 ..., you will see the two streams mixed up. As long as it outputs the correct number of each number, in the right order, it is doing what you expect. You cannot expect how the threads will be scheduled.
So, you might see 1 1 2 2 3 3 1 1 2 2 3 3... or 1 1 1 1 2 2 2 2 3 3 3 3... or any other variation.
(You might even get lucky and see 1 1 1 1 2 2 2 2 3 3 3 3 ..., one day, if the scheduler slices in a certain way)
EDIT: Also read this answer on thread-safety within the println call.
Try executing this code:
class Test extends Thread {
Test(String name) {
super(name);
}
int x = 0, y = 0;
int addX() {x++; return x;}
int addY() {y++; return y;}
public void run() {
for(int i = 0; i < 10; i++)
System.out.println(addX() + " " + addY() + ", name:" + getName());
}
public static void main(String args[]) {
Test run1 = new Test("thread1");
Test run2 = new Test("thread2");
run1.start();
run2.start();
}
}
You will get output similar to this one:
1 1, name:thread2
2 2, name:thread2
1 1, name:thread1
2 2, name:thread1
3 3, name:thread2
3 3, name:thread1
That is because treads do not execute synchronously. You don't know when will one be executed. In your code 1 1 and then later again 1 1 is just the output of two threads doing the same thing.