2

我的文件内容是:

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

我的代码是:

#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++;
        }
    }
}

我正在实现 Apriori 算法,每行代表事务,即存储在文件中的项目我的文件由这样的数字组成,如何存储每个数字的出现及其计数

我的输出应该是这样的:

 1 6
 2 7
 3 7
 4 2
 5 2

但是我无法单独存储我的意思是 1 及其所有出现 2 及其所有出现等等等。

谁能告诉我如何像上面的例子一样存储

4

3 回答 3

4

如果您正在阅读的数字在一个很小的范围内(例如 0-10,甚至 0-200 等),而不是使用 [ std::map( http://en.cppreference.com/w/cpp/container/map ) ,你可以使用一个简单的数组。Map 的键是数组索引,map 的值(即出现次数)是该索引的数组值。例如,数字 3 的出现存储在索引 3 处的整数数组中。

有关详细信息,请参阅以下注释代码。

我用 VS2010 SP1 (VC10) 编译了该代码并执行了它,它似乎工作正常(至少对于您的输入文件示例数据)。

#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;
    }        
}

如果要使用 a std::map,只需添加#include <map>,并将数组定义替换为:

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

您可以使用如下代码打印地图内容:

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

请注意,使用std::map出现更新代码在形式上与数组案例相同:

// Update occurrence of given number    
occurrences[num]++; // works also for std::map
于 2013-03-02T18:17:39.010 回答
3

我将从一个 ctype_facet 开始,它将除数字(和可选-)之外的所有内容分类为“空白”,因此在您读取数据时将完全跳过它:

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]; 
    } 
};

这样,读取数据就变得更加直接——我们不需要做任何事情来忽略逗号,因为从流中提取一个 int 会自动为我们做这件事。一旦我们读取它们,我们只需在地图中增加它们的计数,然后打印出地图:

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"));
}
于 2013-03-02T18:30:22.350 回答
1

您应该考虑使用映射,其中键是数字,值是计数。

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

它基本上可以让你做类似的事情。我知道这不是有效的 C++ :) 但它应该让您了解我的意思。

std::map<int, int> numbers;

for (read number from file) {
    numbers[number from file] = numbers[number from file] + 1;
}
于 2013-03-02T17:50:08.497 回答