0

I am trying to convert some code from c# to c++ but lack of dictionary tables/enumerables etc making me difficult to get the result needed in c++. Can anyone help with the type of container/methods to use in c++ to get the result needed?

Thanks in advance.

Find all c1 and it's count group by c1 where c2 > 0 and c3 < 4 order by c1

table(c1,c2,c3)  ( number of rows expected is not finite - so - can't use Array as a structure for this )
5 1 2
4 2 3  --> edited this line to make it into the list
4 4 3
4 0 1  --> ignore this row as c2=0
3 1 3  
2 1 5  --> ignore this row as c3 > 4
.....

.....

expected output(number of rows meeting criteria for each c1):
3 1
4 2
5 1
ejuser
  • 181
  • 2
  • 5
  • 13

2 Answers2

1

You will need at the very least:

  • A struct to hold each c1/c2/c3 tuple (or a std::tuple if you use C++11).
  • A std::vector (array-like container, but with dynamic size) to hold all your tuples.
  • A std::map (sorted associative container) to act as a dictionary to compute your output.

I believe this is enough to get you started, if you have a specific problem when actually writing the code don't hesitate to ask new questions.


Edit according to your comments:

You're not missing much, elvena's solution is almost what you need except it lacks the vector container to store the objects. This is quite straightforward:

#include <iostream>
#include <map>
#include <vector>
#include <tuple>

int main()
{
    std::vector<std::tuple<int, int, int>> values;
    while (you_have_more_data) {
        int c1, c2, c3;
        // somehow read c1, c2, c3 from cin/file/whatever
        values.push_back(std::make_tuple(c1, c2, c3));
    }

    std::map<int, int> dict;
    // iterate over the vector
    for (auto i = values.begin(); i != values.end(); ++i) {
        // *i (dereferencing the iterator) yields a std::tuple<int, int, int>
        // use std::get to access the individual values in the tuple
        // 0 => c1; 1 => c2; 2 => c3 (same order as in std::make_tuple)
        if (std::get<1>(*i) > 0 && std::get<2>(*i) < 4)
            dict[std::get<0>(*i)] += 1; // see std::map::operator[]
    }

    // iterate over the map and print its items
    for (auto i = dict.begin(); i != dict.end(); ++i)
        // *i (dereferencing the iterator) yields a std::pair<int, int>
        // but writing (*i).first is cumbersome
        // let's write i->first instead (this is the same, just a different notation)
        std::cout << i->first << " " << i->second << std::endl;

    return 0;
}
syam
  • 14,701
  • 3
  • 41
  • 65
  • Thanks syam. I am using c++11 and actually got started on some what similar path but couldn't make much progress. In c# I can make a filter(view) of the base table and then apply the filter/group/sort options to get the required output. Would make another go at this to see if I can get anywhere with this.. Thanks – ejuser May 06 '13 at 11:28
  • @ejuser: I edited my answer to include a `vector/tuple` example. – syam May 06 '13 at 13:44
  • Thanks a lot Syam. Very nice of you to provide an usable example that I can expand further. Appreciate it. if (std::get<1>(*i) > 0 && std::get<2>(*i) < 4) --> This was one of the very useful syntax for me as I couldn't get my hand earlier on this well. – ejuser May 06 '13 at 15:25
1

Something like this should do, the only memory used is for c1 and the count of valid c2/c3 for this c1:

#include <iostream>
#include <map>

using namespace std;

int main()
{
    int a,b,c = 0;
    map<int, int> n;
    int i;

    for( i = 0 ; i < 6 ; i ++ )
    {
        cout << "Enter three numbers separated by space" << endl;
        cin >> a >> b >> c;
        if( b > 0 &&  c < 4 )
            n[a] += 1;
    }

    for( auto iter = n.begin(); iter != n.end() ; ++iter )
        cout << iter->first << " " << iter->second << endl;

    return 1;
}

Gives

3 1
4 1
5 1

Note that your example is not good for c1=4, as 4.2.4 fails on c3 rule.

elvena
  • 411
  • 3
  • 5
  • Thanks elvena. However this solution doesn't look like a feasible solution as all these rows must be stored in a container by some means. Thanks. – ejuser May 06 '13 at 11:20