Reputation: 1456
Let's assume the items
array consists of the following items {3.1, 3.1, 3.1, 3.2, 3.2, 3.3, 3.4, 3.4, 3.4, 3.4, 3.1, 3.1}
What I want is to count the occurrence of each item in the successive items such that:
3.1 = 3
3.2 = 2
3.3 = 1
3.4 = 4
3.1 = 2
I wrote the following function:
private void displayItems(List<Double> items) {
double current_item=0;
for(int i=0; i<items.size(); i++) {
int count=1;
current_item = items.get(i);
if(i != items.size()) {
for(int j=i+1; j<items.size(); j++) {
double next_item = items.get(j);
if(current_item == next_item) {
count++;
}else {
break;
}
}
System.out.println("item value is " + current_item + " and count is " + count);
}
}
}
I got the following result:
item value is 3.1 and count is 3
item value is 3.1 and count is 2
item value is 3.1 and count is 1
item value is 3.2 and count is 2
item value is 3.2 and count is 1
item value is 3.3 and count is 1
item value is 3.4 and count is 4
item value is 3.4 and count is 3
item value is 3.4 and count is 2
item value is 3.4 and count is 1
item value is 3.1 and count is 2
item value is 3.1 and count is 1
What can I do to show the results like the following:
item value is 3.1 and count is 3
item value is 3.2 and count is 2
item value is 3.3 and count is 1
item value is 3.4 and count is 4
item value is 3.1 and count is 2
Please not that I don't want to count the occurrence of each item in the entire array, I just want to count its occurrence in the successive items only.
Upvotes: 2
Views: 209
Reputation: 519
I guess all the above answers are correct but I also wanted to try this with single loop so here it is with single loop:
import java.util.Arrays;
import java.util.List;
public class SuccessiveCount {
public static void main(String[] args) {
List<Double> list = Arrays.asList(3.1, 3.1, 3.1, 3.2, 3.2, 3.3, 3.4, 3.4, 3.4, 3.4, 3.1, 3.1);
double prevValue = list.get(0);
int count = 0;
for(int i=0; i < list.size(); i++) {
if(prevValue == list.get(i)) {
count++;
}else {
System.out.println("item value is "+list.get(i-1)+ " and count is "+ count);
prevValue = list.get(i);
count = 1;
}
if(list.size() == (i+1)) {
System.out.println("item value is "+list.get(i-1)+ " and count is "+ count);
}
}
}
}
PS : If anyone wants to make it look more cleaner I am up for suggestions.
Upvotes: 1
Reputation: 737
I think this will give the expected result
int count = 1;
for (int i = 0; i < arr.size(); i++) {
if (i != 0) {
if (arr.get(i) - arr.get(i - 1) == 0) {
count++;
} else if (arr.get(i) - arr.get(i - 1) != 0) {
System.out.println("Item value is " + arr.get(i - 1) + " and count is " + count);
count = 1;
}
}
if (arr.size() == i + 1) {
System.out.println("Item value is " + arr.get(i) + " and count is " + count);
}
}
Upvotes: 0
Reputation: 8561
x[n-1]-x[n]==0
should be the formula.
public class SuccessiveCounter {
public static void main(String[] args) throws Exception {
double[] x = {3.1,3.1,3.1,3.2,3.2,3.1,3.1,3.4,3.4,3.1,3.1};
for(int n=1,count = 1;n<x.length;n++){
if(x[n-1]-x[n]==0){
count++;
}else{
System.out.println(x[n]+" "+count);
count = 1;
}
}
}
}
Upvotes: 2
Reputation: 146
Here are the changes,
int dec = 0;
int inc = 0;
if(current_item == next_item) {
count++;
dec = count; //new line
}
else {
break;
}
}
//new stuff from here, printing "inc" instead of "count" in print statement.
dec--;
inc++;
if(dec==0){
System.out.println("item value is " + current_item + " and count is " + inc);
}
Upvotes: 0
Reputation: 101
Your code is iterating over the values which were already counted in the previous iterations. A small tweak in the logic works as expected.
private void displayItems(List<Double> items) {
double current_item=0;
for(int i=0; i<items.size(); i++) {
int count=1;
current_item = items.get(i);
if(i != items.size()) {
int j=i+1;
for(; j<items.size(); j++) {
double next_item = items.get(j);
if(current_item == next_item) {
count++;
}else {
break;
}
}
System.out.println("item value is " + current_item + " and count is " + count);
i = j-1;
}
}
}
Upvotes: 2
Reputation: 44230
You can use a map to map the double to how many times it occurs. Then simply loop over the map to print the values.
private static void count(List<Double> numbers)
{
final Map<Double, Integer> numberToOccurrences = new HashMap<>();
for(Double num : numbers)
{
numberToOccurrences.putIfAbsent(num, 0);
numberToOccurrences.compute(num, (k, occurrences) -> ++occurrences);
}
numberToOccurrences.forEach((num, occurrences) ->
System.out.println("Number " + num + " occurs " + occurrences + " times")
);
}
A few uses of lambdas here which may be considered more advanced, but they often result in the the most concise solution.
Upvotes: 1
Reputation: 48
What about making an ArrayList<String>
?
ArrayList<String> runs = new ArrayList<String>();
Then storing something like
runs.add(current_item + "," + count);
instead of your print line, Then going through the array list and split each string by the comma to get desired output.
While it may work it is probably not ideal, but still a possible solution.
EDIT: You would go through runs after the nested loop
Upvotes: 0