I'm working on some c problems from a book and my task is to count number occurrences in a list. The task can be solved with just one iterator walking on each item of the list. However, I've done this before with other other task and I'm trying something different with this one. The idea is basically to use two iterators that increase a counter whenever the step on a value until they meet each other. I'm done with that for just the first value of the list but now I want to do it for the rest of the different numbers of the list. The main problem currently is that I can't find out why the programs hangs when I pass an iterator as an argument since creating the start
iterator within the findNumberOccurrences
and initialize it with the input.begin()
value doesn't have any problem if that makes sense.
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
int findNumberOccurences(std::list<int> input, std::list<int>::iterator& start) {
std::cout << *start << '\n';
std::list<int>::iterator end = input.end();
int count = 1;
while (std::distance(input.begin(), start) != std::distance(input.begin(), end)) {
while (*end != *start) {
--end;
}
count;
start;
if (std::distance(input.begin(), start) == std::distance(input.begin(), end)) {
break;
}
while (*start != *end) {
std::cout << *start << '\n';
start;
}
count;
--end;
}
return count;
}
int main() {
std::list<int> input = {3, 4, 4, 2, 3, 3, 4, 3, 2};
std::list<int>::iterator start = input.begin();
int count = findNumberOccurences(input, start);
std::cout << count << '\n';
return 0;
}
I've written some cout logs within each while loop but I don't anything that gives me a clue about what's going on. Weird thing is that my terminal cursor keeps blinking without throwing exception like when having an infinite loop.
Can anyone shed some light on what I'm doing wrong please?
Cheers!
CodePudding user response:
Alright, I've just found the answer to this question. Basically, I must pass a reference of the list as a function argument like this:
int findNumberOfOccurrences(std::list<int> &input, std::list<int>::iterator &start)
I did that intuitively but I want to know why this solves the problem so I'm gonna read about references. If anyone wants add anything to the answer, please by all means.
CodePudding user response:
Passing the container by reference "fixes" the immediate problem in the code, but the code itself is flawed. When you're dealing with iterators you don't need the underlying container; indeed, there often isn't an underlying container. That's the point of iterators: they provide an abstraction that gives your code more flexibility.
In this case, just write the function to take two iterators:
int findNumberOccurences(std::list<int>::iterator first,
std::list<int>::iterator last) {
// code goes here
}
It's not clear to me what the code in the question is actually doing, so I haven't reproduced it. But in general, you can use first
and last
as the two ends of the data sequence and manipulate them appropriately.
while (first != last) {
// do something with *first
first;
}