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

std::map[ (http://en.cppreference.com/w/cpp/container/map)を使用する代わりに、読み取っている数値が狭い範囲(たとえば、0-10、さらには0-200など)にある場合、単純な配列を使用できます。マップのキーは配列インデックスであり、マップの値(つまりオカレンス)はそのインデックスの配列値です。たとえば、番号3のオカレンスは、インデックス3の整数配列に格納されます。

詳細については、次のコメント付きコードを参照してください。

そのコードをVS2010SP1(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;
    }        
}

を使用する場合は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 に答える