I have three lists and I want to implement a search feature.
How the code works is that I create an iterator that begins at the start of each list and it compares what the user inputs with each and every value in the list, when it finds a match it is supposed to increase an integer variable by one, so in the end it would say:
your value is found: <x amount of times in Example list>
The problem I am having is that it is compiling fine but the end result still gives me 0 like it didn't increment the variable.
I am wondering if it is having trouble comparing the value where the iterator is pointing to the user input, can anyone please shed some light on this? For testing purposes in the
On the iterator search_disregard I manually put 4 identical values in the list, so I know the end result should show me 4, but I still get 0:
cout << "\nSearch for: ";
string edit_search;
cin >> edit_search;
list<string>::iterator search_disregard = disregard_list.begin();
list<string>::iterator search_compare = compare_list.begin();
int search_disregard_count = 0;
int search_compare_count = 0;
for (int x = 0; x < disregard_list.size(); ++x)
{
if (*search_disregard == edit_search)
{
++search_disregard_count;
}
}
for (int x = 0; x < compare_list.size(); ++x)
{
if (*search_compare == edit_search)
{
++search_compare_count;
}
}
cout << edit_tag << edit_search << " is found in the following: \n" << endl;
cout << search_disregard_count << " time(s) in the Disregard List" << endl;
cout << search_compare_count << " time(s) in the Compare List" << endl;
buffer_clear();
You never increment your iterators so they will always point to the first element. The idiomatic way:
for(auto it = container.begin(); it != container.end(); ++it) ...
Related
The purpose of this loop is to look through a 2d vector and count the frequency in which a value in the first column appears. If the value shows up all three times, then it is good to go. If it doesn't then I would like to delete the row that it's in from the vector. The "it" iterator stores the value as (value, frequency).
I can't figure out how to delete the row at this point though, i have been trying to use a counter "x" in the second for loop so that it can keep track of which row it is on, but when i run it through the debugger the x doesn't increment. What ends up happening is the vector deletes the first rows instead of the rows that make the if statement true.
Why isn't the "x" incrementing? Is there a different method i could use to keep track of which row the loop is currently in?
"data" is the 2d vector.
for (int i = 0; i < data.size(); i++) // Process the matrix.
{
occurrences[data[i][0]]++;
}
for (map<string, unsigned int>::iterator it = occurrences.begin(); it != occurrences.end(); ++it)
{
int x = 0;
if ((*it).second < 3) // if the value doesn't show up three times, erase it
{
data.erase(data.begin() + x);
}
cout << setw(3) << (*it).first << " ---> " << (*it).second << endl; // show results
x++;
}
You reset x back to 0 every loop. Initialize it outside the loop and it should work.
int x = 0;
You have to initialize x outside the for loop. If you declare it in the for loop it will be set to 0 every time. You current program deletes the first element each time because the x is always zero here: data.erase(data.begin() + x);
for (int i = 0; i < data.size(); i++) // Process the matrix.
{
occurrences[data[i][0]]++;
}
int x = 0;
for (map<string, unsigned int>::iterator it = occurrences.begin(); it != occurrences.end(); ++it)
{
if ((*it).second < 3) // if the value doesn't show up three times, erase it
{
data.erase(data.begin() + x);
}
cout << setw(3) << (*it).first << " ---> " << (*it).second << endl; // show results
x++;
}
I have a list
list<pair<Zeitpunkt, double>> l_tempdiff;
And I only want to cout the first 5 elements.
I only know the way of couting the whole list with:
for (auto elem : l_tempdiff)
{
cout << elem.first << elem.second << endl;
}
I dont know how to acces my elements when I use:
for (it = l_tempdiff.begin(); it != l_tempdiff.end(); ++it)
{
}
And I guess I need to change the l_tempdiff.end() to some other value but it doesnt seem to take just the number5`. How can I do this?
Since std::list iterators are not random access you cannot just increment them like l_tempdiff.begin() + 5. What you can do is use std::next to increment the iterator the required number of times. That would looks like
for (auto it = l_tempdiff.begin(), end = std::next(l_tempdiff.begin(), 5); it != end; ++it)
{
// use `*it` here
}
Before doing this though you should make sure the list is big enough because if it isn't then you'll have undefined behavior.
You only want to output the first five elements?
Well, a for-range-loop is a good place to start, just add the additional constraint as a break-condition:
int i = 0;
for (auto&& elem : l_tempdiff)
{
if (5 < ++i) break;
cout << elem.first << elem.second << endl;
}
I change auto to auto&& to avoid needless copying.
As an aside, consider reading "Why is "using namespace std" considered bad practice?" and "C++: "std::endl" vs "\n"".
list<pair<Zeitpunkt,double> > :: iterator it;
int m = 0;
it = l_tempdiff.begin();
while( it != l_tempdiff.end() && m < 5)
{
cout<<it->second<<"\n";
m++;
it++;
}
Try
auto it = l_tempdiff.begin();
auto end = l_tempdiff.end();
for (int count = 0; count < 5 && it != end; ++count)
{
std::cout << it->first << it->second << std::endl;
std::advance(it);
}
This prints the first five pairs (or all the pairs, if there are less than 5).
count is used to control the maximum number of elements to be printed.
it is an iterator that, in each iteration of the loop, references the current pair.
Note that advancing an end iterator gives undefined behaviour. So it is necessary to terminate the loop if the end iterator is reached (hence the it != end test in the loop condition) or if the maximum number of elements (5) is reached.
I'm currently working on a problem and I've been stumped on an error for about 3 hours now. Thus, I've given up being hard headed and I'm looking to the internet to see if someone else's wealth of knowledge can help to solve my problem.
A jist of the program, it takes in input from the command line of any number of numbers. It inserts them into a vector and then performs a series of statistical analysis' on the data set.
Currently, I'm having difficulty with the quintiles function (as my teacher says or "quantiles" for those of you looking it up on Wikipedia).
Logically, my code should work. However, it's seeming to hit an out of range error two before the actual end of the vector that I've created.
Heres the function followed by the functions called inside:
string quintile(vector<double> v) {
ostringstream oss;
oss << "Quintile means" << endl;
vector<unsigned> quintile{ 0 };
// get range of quintiles and insert into vector
for (unsigned i = 1; i <= 5; ++i)
quintile.push_back((v.size() * 0.2) * i);
// get the mean for each quintile
for (unsigned i = 0; i < 5; ++i)
oss << "Q" << (i + 1) << ": " << mean_sized(v, quintile[i], quintile[i + 1]) << " (" << quintile[i] << ".." << quintile[i + 1] << ")" << endl;
return oss.str();
}
double mean_sized(vector<double> v, int first, int last) {
double mean = 0.0;
vector<double> sub;
for (unsigned i = v[first]; i < v[last]; ++i)
sub.push_back(v[i]);
return (accumulate(sub.begin(), sub.end(), mean) / sub.size());
}
Any input is much appreciated as I'm seriously stumped.. I'm going to move on to the last function and hopefully by the time I'm done someone will have graced me with the knowledge to solve that issue.
Thanks!
This loop is wrong:
for (unsigned i = v[first]; i < v[last]; ++i)
sub.push_back(v[i]);
You're using the values in the vector as the range of indexes. You should just be using the range from first to last:
for (unsigned i = first; i <= last; i++) {
sub.push_back(v[i]);
}
P.S. See Why is it considered a bad practice to omit curly braces?
Stuck in very interesting problem.
You might have done this before in C/C++
map<string, string> dict;
dsz = dict.size();
vector<string> words;
int sz = words.size();
for(int i = 0; i < sz; ++i)
{
for(int j = i + 1; j < dsz; ++j)
{
}
}
How I will achieve the same thing using iterator.
Please suggest.
Ok.
I figure it out.
more precisely I wanted both i and j in inner loop.
here i did with iterator, sorry I have to move to multimap instead of map due to change in requirement.
vector<string>::iterator vit;
multimap<string, string>::iterator top = dict.begin();
multimap<string, string>::iterator mit;
for(vit = words.begin(); vit != words.end(); ++vit)
{
string s = *vit;
++top;
mit = top;
for(; mit != dict.end(); ++mit)
{
/* compare the value with other val in dictionary, if found, print their keys */
if(dict.find(s)->second == mit->second)
cout << s <<" = "<< mit->first << endl;
}
}
Any other efficient way to do this will be grateful.
Your final intent is not fully clear, because you start the j loop on i+1 (see comments at the end). Until you give clarity on this relationship, I propose you two interim solutions
Approach 1: easy and elegant:
You use the new C++11 range based for(). It makes use of an iterator starting with begin() and going until end(), without you having to bother with this iterator:
for (auto x : words) { // loop on word (size sz)
for (auto y : dict) { // loop on dict (size dsz)
// do something with x and y, for example:
if (x==y.first)
cout << "word " << x << " matches dictionary entry " << y.second << endl;
}
}
Approach 2: traditional use of iterators
You cas also specify explicitely iterators to be used. This is a little bit more wordy as the previous example, but it allows you to choose the best suitable iterator, for example if you want constant iterator like cbegin() instead of begin(), if you want to skip some elements or use an adaptator on the iterator, suc as for example reverse_iterator, etc.:
for (auto itw = words.begin(); itw != words.end(); itw++) {
for (auto itd = dict.begin(); itd != dict.end(); itd++) {
// do simething with *itw and *itd, for example:
if (*itw == itd->first)
cout << "word " << *itw << " matches dictionary entry " << itd->second << endl;
}
}
Remarks:
The starting of intter loop with j=i+1 makes sense only if elements of word vector are related to elements in dict map (ok, they are cerainly words as well), AND if the order of elements you access in the map is related to the order in the vector. As map is ordered according to the key, this would make sense only word would be ordered as well following the same key. Is it the case ?
If you'd still want to skip elements or make calculation based on distance between elements , you'd rather consider the second approach propose above. It makes it easier to use distance(itw, words.begin()) which would be the equivalent of i.
However, it's best to use containters taking advantage of their design. So instead of iterating trough a dictionaly map to find a word entry, it's better to do use the map as follows:
for (auto x : words) { // loop on word (size sz)
if (dict.count(x)) // if x is in dictionary
cout << "word " << x << " matches dictionary entry " << dict[x] << endl;
}
how should i run a for loop to pick two characters at a time from my string??
int main{
string data;
for (i = 0; i <= data.size(); i+=2)
d = data[i] + data[i+1];
cout << "the list of two characters at a time is" << d;
}
//i want to pick divide my string(data) for example: "hello how are you" into a list of two characters at a time (where the space should also be counted as a character) and listed such as:
cout should give:
he
ll
o(space)
ho
w(space)
ar
e(space)
yo
u //the last one is appended with 8 zeros with u to make a complete pair
i dont understand how to reach the ith position of string data in C++.
How about you use substr()?
for (int i=0; i<data.length(); i+=2) {
if(i+2 < data.length()){ //prevent it from throwing out_of_range exception
d = data.substr(i,i+2);
cout << d << endl;
}
}
std::cout << "the list of two characters at a time is:\n";
for (i = 0; i < data.size(); ++i) {
if (data[i] == ' ')
std::cout << "(space)";
else
std::cout << data[i];
if (i % 2 != 0)
std::cout << '\n';
}
You almost got it right except 2 issues:
you loop condition is wrong, it could be this:
for (i = 0; i + 1 < data.size(); i+=2)
otherwise you will try to access data behind end of string. In this case you will skip 1 symbol if string length is odd. If you need to process that, your loop should be different.
you add 2 chars as numbers, but you should make it as string:
d = std::string( data[i] ) + data[i+1];