0

私は拡張可能なハッシュを使用してクエリをより速く見つけることに取り組んでいます。私のコードは次の手順です:1)メインテキストファイル(ハッジファイル4 GiB)を読み取ります。ファイルは次のようなものです:

12435 alex romero
13452 jack robert
13485 marya car
45132 gun tribble
...

ユーザーは、たとえばキー12435が何に関連しているのか知りたいですか?(answer:alex romero)

2)ファイル内のキーのハッシュテーブルを作成し(つまり、12435,13452,13485、...)、このテーブルをハードディスクの0.txt、1.txt、2という名前のテキストファイルに動的に保存します。 txtと...。

3)ユーザーがプログラムへのクエリを取得すると、プログラムはその値に基づいてハッシュ関数を計算し、読み取る必要のあるファイルを見つける必要があります。そうすれば、結果を見つけるのが速くなります。

私は機能を持っています:

#define LIMIT 7
void writeInFile(int key , const char* charPos ){
    int remainder = key%(LIMIT*LIMIT);

    string myFileName;
    ostringstream convert;
    convert << remainder ;

    myFileName = convert.str();
    myFileName += ".txt";

    FILE *my_file;
    my_file = fopen(myFileName.c_str() ,"a");

    fputs("\n" ,my_file);
    fputs(charPos , my_file);
    //fclose(my_file);
}

fclose使用するとプログラムの速度が低下するのではないかと思いました!!! 次に、関数の最後でそれを使用しませんが、この関数を何度も使用すると、それらを閉じることができず、ファイルにアクセスできないという問題があります。次のような関数にファイルの参照を送信できるファイルの「リスト」を作成したいのですがFILE &* myFiles[]FILE &** myFiles関数が取得する3番目のパラメーターとして...エラーが表示されます。this.iの構文がどのようになっているのかわかりません。次のような構文:

void writeInFile(int key , const char* charPos , FILE &*myFiles[] ) // this makes error

私が思う他の方法は、今はアクセスできないファイルを閉じることができるかということです。または、これを引き起こすコードを変更できますか?

更新:これは私の完全なコードです

#include <iostream>
#include <fstream>
#include <limits>
#include <string>
#include <sstream>
#include <stdio.h>
#include <vector>

#define LIMIT 7

using namespace std;

void writeInFile(int key , const char* charPos ){
    int remainder = key%(LIMIT*LIMIT);

    string myFileName;
    ostringstream convert;
    convert << remainder ;

    myFileName = convert.str();
    myFileName += ".txt";

    FILE *my_file;
    my_file = fopen(myFileName.c_str() ,"a");

    fputs("\n" ,my_file);
    fputs(charPos ,my_file);
    //fclose(my_file);

}

int main(){
    string fileName;
    cout << "hello, please inter your file destination : " ;
    cin >> fileName;
    ifstream myFile ;
    myFile.open(fileName.c_str() ,ifstream::in |ifstream::binary);
    cout << "building the hash,please wait";
    string havij;//:D this is an unusable variable in this section :))
    int current;
    int index;
    int isCout=0;
    char buffer [10];

    //FILE *my_file[49];
    while(!myFile.eof()){

        cout << isCout << endl;
        isCout++;
        index = myFile.tellg();


        itoa(index , buffer ,10);
        //cout << buffer << endl;
        myFile >> current;
        writeInFile(current ,buffer);
        getline(myFile,havij);
    }
    myFile.close();
    fstream test;
    //for(int i =0 ; i<LIMIT*LIMIT-1 ; i++){
    //  fclose(my_file[i]);
    //}
    cout << endl << "static extensible hash structure builded please inter your query : " ;
    int query;
    cin >> query;
    int remainder = query%(LIMIT*LIMIT);

    string myFileName;
    ostringstream convert;
    convert << remainder ;

    myFileName = convert.str();
    myFileName += ".txt";

    ifstream myFile2;
    //myFile2 is now the files that create by program like : 12.txt ,25.txt ,....
    myFile2.open(myFileName.c_str() , ifstream::in | ifstream::binary);
    ifstream mainFile;
    mainFile.open(fileName.c_str(), ifstream::in | ifstream::binary);
    int position;
    string wanted;
    int tester;
    while(!myFile2.eof()){
        myFile2 >> position;

        mainFile.seekg(position ,ios::beg);
        mainFile >> tester;
        if (tester == query ){
            getline(mainFile ,wanted);
            cout << "the result of the key " << tester << " is  " << wanted << endl;
        }
    }
    return 0;
}
4

3 に答える 3

0

FILE *変数が宣言されているのと同じコンテキストでファイルを閉じないと、そのファイル記述子がリークされます。ある時点でリソースが不足し、プログラムがクラッシュします。

表示したスニペットのC++を使用しているので、std::vectorとstd::ofstreamを使用する方がはるかに良いでしょう。

void writeInFile(int key, const char* charPos, std::vector<std::ofstream> my_files )
于 2012-05-24T16:11:07.597 に答える
0

すでに述べたように、開いているスコープでファイルを閉じる必要があります。これは、C++ストリームのデフォルトの動作です。

ただし、追加する単語ごとに開閉する必要があるという意味ではありません。書き込むファイルは、追加するものがある限り開いたままにしておく必要があります(OSが処理できるファイル記述子の数には制限があることに注意してください)。

したがって、次のようにする必要があります。

  1. すべての宛先ファイルを開く(*)
  2. 行ごとに、テーブル/マップで適切なファイルを選択して書き込みます
  3. すべての宛先ファイルを閉じる

(*)前述のように、厳しい制限に遭遇する可能性があります。この場合、できることはあまりありません。ハッシュ関数に価値がある場合、キャッシュは効果的ではありません。可能性としては、大きなファイルに対して複数の実行を行い、各実行でハッシュの一部のみを保存することです(たとえば、実行1:[0-9]のハッシュ、実行2:[10-19]のハッシュ、... )。

基本的なタイプFILE*またはofstream使用するタイプはほとんど重要ではなく、どちらも同等の速度(正しく調整されている)を備えています。

于 2012-05-24T16:11:30.990 に答える
0

または、次のようにすることもできます。

void writeInFile(int key , const char* charPos , std::vector<std::ofstream> & myFiles );

これにより、脳の痛みが軽減されることがわかりました。

于 2012-05-24T15:59:51.037 に答える