Rajesh M
Rajesh M

Reputation: 634

i want to store the number and its count taken from a file

The contents of my file are:

1,2,5
2,4
2,3
1,2,4
1,3
2,3 
1,3 
1,2,3,5
1,2,3

And my code is:

#include<iostream>
#include<set>
#include<vector>
#include<fstream>
#include<sstream>
#include<set>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct store {
    string a;
    int count;
};
int main() {
    store ap[100];
    vector<string> v;
    set<string> input;
    int mycount;
    ifstream fin("trans.txt");
    string line, s, str1, token;
    while(!fin.eof()) {
        fin >> line;
        //  cout<<"i cant understand but correct"<<line<<endl;
        istringstream str1(line);
        while(getline(str1, token, ',')) {
            //cout<<"the token are\t"<<token<<endl;
            v.push_back(token);
            input.insert(token);
        }
        //v.push_back(token);
        //input.insert(token);
        int i = 0;
        for(set<string>::iterator it = input.begin(); it != input.end(); it++) {
            mycount = count(v.begin(), v.end(), *it);
            s = *it;
            ap[i].a = s;
            ap[i].count = mycount;
            cout << ap[i].a << "\t" << "mycount" << ap[i].a << endl;
            i++;
        }
    }
}

I am implementing Apriori algorithm each line represents the transaction i.e the items stored in a file my file consists of numbers like this how to store the occurrences of each number and its count

My output should be like this:

 1 6
 2 7
 3 7
 4 2
 5 2

However I am unable to store individually I mean 1 and all its occurrences 2 and all its occurrences etc etc.

Can any tell me how to store like above example

Upvotes: 2

Views: 1216

Answers (3)

Mr.C64
Mr.C64

Reputation: 42964

If the numbers you are reading are in a small range (e.g. 0-10, or even 0-200, etc.), instead of using [std::map(http://en.cppreference.com/w/cpp/container/map), you could use a simple array. Map's key is the array index, and map's value (i.e. occurrences) is the array value for that index. e.g. the occurrences of number 3 are stored in the integer array at index 3.

See the following commented code for details.

I compiled that code with VS2010 SP1 (VC10) and executed it, and it seems to work correctly (at least for your input file sample data).

#include <cstdlib>
#include <exception>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>

using namespace std;

int main() 
{
    static const int kExitOk = 0;
    static const int kExitError = 1;

    try
    {
        // Open text file for reading
        ifstream inFile("data.txt");

        // Occurrence table
        static const int kMaxNum = 10;
        int occurrences[kMaxNum + 1] = {0}; // init to 0s

        // Line read from file       
        string line;

        // For each line in file
        while (getline(inFile, line))
        {
            // Process each line content using string streams
            istringstream iss(line);

            // Read numbers (separated by comma) from current line
            string token;
            while (getline(iss, token, ','))
            {
                // Convert from string to integer
                const int num = atoi(token.c_str());

                // Just do a bounds checking for safety...
                if (num < 0 || num > kMaxNum)
                    throw runtime_error("Bad input number found in file.");

                // Update occurrence of given number    
                occurrences[num]++;
            }
        }

        // Print occurrences
        for (int i = 0; i <= kMaxNum; i++)
        {
            if ( occurrences[i] != 0 )
            {
                cout << i << ' ' << occurrences[i] << '\n';
            }
        }

        return kExitOk;
    }
    catch(const exception& e)
    {
        cerr << "\n*** ERROR: " << e.what() << endl;
        return kExitError;
    }        
}

If you want to use a std::map, just add #include <map>, and replace the array definition with:

// Occurrence table
map<int, int> occurrences;

You can print the map content with code like this:

// Print occurrences
for (auto it = occurrences.begin(); it != occurrences.end(); ++it)
{
    cout << it->first << ' ' << it->second << '\n';
}

Note that using std::map the occurrence update code is formally the same as for the array case:

// Update occurrence of given number    
occurrences[num]++; // works also for std::map

Upvotes: 4

Jerry Coffin
Jerry Coffin

Reputation: 490178

I'd start with a ctype_facet that classifies everything but digits (and, optionally -) as "whitespace", so it'll be completely skipped as you read the data:

struct number_only: std::ctype<char> { 
    number_only() : std::ctype<char>(get_table()) {} 

    static mask const *get_table() { 
        static std::vector<mask> rc(table_size, space);

        std::fill_n(&rc['0'], 10, digit);
        rc['-'] = punct;
        return &rc[0]; 
    } 
};

With that, reading the data becomes much more straightfoward -- we don't have to do anything to ignore the commas because extracting an int from the stream will do that for us automatically. Once we read them, we just increment their count in a map, then print out the map:

typedef std::pair<int, int> count;

std::ostream &operator<<(std::ostream &os, count const &p) {
    return os << p.first << "\t" << p.second;
}

int main() { 
    std::map<int, int> numbers;

    int temp;

    std::cin.imbue(locale(local(), new number_only);

    while (std::cin >> temp)
       ++numbers[temp];

    std::copy(numbers.begin(), numbers.end(), 
              std::ostream_iterator<count>(std::cout, "\n"));
}

Upvotes: 3

Tommy Andersen
Tommy Andersen

Reputation: 7220

You should consider using a map, where the key is the number, and the value it's count.

http://www.cplusplus.com/reference/map/map/

It basically lets you do something similar to this. I know this is not valid C++ though :) but it should give you an idea of what I mean.

std::map<int, int> numbers;

for (read number from file) {
    numbers[number from file] = numbers[number from file] + 1;
}

Upvotes: 1

Related Questions