//ハッシュ法を用いたデータベース管理         

 

#include<iostream.h>

 

const int Nothing = -1;  // 未格納であることを示す

const int N = 10;   // データ格納領域の個数

                    // 但し格納可能個数はN-1個

int    Key[N];      // キー値を格納

double Table[N];    // データ値を格納

int    M = 0;       // 現格納個数    

 

 

//ハッシュ関数 

int H(int k)

{

        int n;

        n = k - N * int(k / N);

        return n;

}

 

//      移動チェック

int ido_check(int i, int j)

{

        int sw2 = 0;

    int r = H(Key[i]); //正規の場所

       

        if(r <= i)

        {    //正規の場所はそこから前

                if(j < i)  //

                        if(r <= j) //正規の場所は削除したところから前

                                sw2 = 1; //移動の必要あり

        }

        else

        {          //正規の場所はそこより後

                if(j >= r)     //正規の場所は削除したところから前

                                sw2 = 1; //移動の必要あり

                else

                        if(j < i)  //

                                sw2 = 1; //移動の必要あり

        }

 

        return sw2;

}

 

//削除処理

void Sakujoshori(int i)

{

        int j = i;

        int sw1 = 0;

        int sw2 = 0;

       

        do{

                Key[i] = Nothing;

                Table[i] = Nothing;

                //後続のデータを詰める作業

                do{

                        i++;

                        if(i==N)i=0;

 

                        if(Key[i] == Nothing)

                        {

                                sw1 = 1; //これ以上後続のデータを詰める作業必要無し

                                break;

                        }

                        else

                        {

                                //移動の必要性チェック

                                sw2 = ido_check(i,j);

                        }

                }while(sw1 == 0 || sw2 == 0);

                //移動の必要性の有る場合のデータの移動処理

                if(sw2 == 1)

                {

                        sw2 = 0;

                        Key[j]=Key[i];

                        Table[j]=Table[i];

                }

        }while(sw1 == 0);

}

 

void Kakunou(void)

{      

        int i,k;

        double Data;

        char c=' ',cc=' ';

       

        do

        {

                //格納するデータのキー値を入力

                do

                {

                        cout << "現在 " << M << " 個のデータがあります。\n"

                                 << "格納データのキー値(正整数)を入力せよ。"

                                 << "(格納中止は999を入力。)" << '\n';

                        cin  >> k;

                        if(k==999)break;

                        cout << "キー値は " << k << " ですね。(Y/N) ->";

                        cin  >> c;

                }while (c=='n' || c=='N');

                if(k==999)break;

                                                               

                //格納場所を探す。

                i = H(k);

 

 

                while(Key[i] != Nothing && Key[i] != k)

                {

                        i++;

                        if(i>=N)i=0;

                }

 

                //格納するデータを入力

                if(Key[i]==k)

                {

                        cout << "既にそのデータは存在しています。\n";

                }

                if(M>=N-1)

                {

                        cout << "格納場所に空きがありません。\n";

                        break;

                }

                if(Key[i]!=k)

                {

                        cout << "格納場所のアドレスは " << i << " です。\n";                   

                        Key[i] = k;

                        cout << "格納するデータ(実数値)を入力してください。\n";

                        cin  >> Data;

                        Table[i] = Data;

                        cout << "データ:" << Data << "が格納されました。\n";

                        M++;

                }

 

                //続行判断

                cout << "格納を続けますか。(Y/N) ->";

                cin  >> cc;

        } while(cc=='y' || cc=='Y');

        cout << "入力を終了します。\n\n";

}

 

void Kensaku(void)

{

        int i,k;

        char c;

 

        do

        {

                //検索するデータのキー値を入力

                do

                {

                        cout << "検索するデータのキー値を入力してください。"

                                 << "(中止は999を入力)\n";

                        cin  >> k;

                        if (k==999)break;

                        cout << "検索するデータのキー値は " << k

                                 << " ですね。(Y/N) ->";

                        cin  >> c;

                } while(c=='n' || c=='N');

                if (k==999)break;

                       

                //検索実行

                i=H(k);

                do

                {

                        if(Key[i]==k)

                        {

                                cout << "データは存在しました。データは "

                                         << Table[i] << "です。\n";

                                break;

                        }

                        else

                        {

                                if(Key[i] == Nothing)

                                {

                                        cout << "データは存在しません。\n";

                                        break;

                                }

                                else

                                {

                                        i++;

                                }

                        }

                        if(i>=N)i=0;

                } while(1);

 

                //続行判断

                cout << "別のデータを検索しますか。(Y/N) ->";

                cin  >> c;

        } while (c=='y' || c=='Y');

        cout << "検索を終了します。\n";

}

 

void Sakujo(void)

{

        int i,k;

        char c;

                       

        do

        {

                //削除するデータのキー値を入力

                do

                {

                        cout << "削除するデータのキー値を入力してください。"

                                 << "(中止は999を入力)\n";

                        cin  >> k;

                        if(k==999)break;

                        cout << "削除するデータのキー値は " << k

                                 << " ですね。(Y/N) ->";

                        cin  >> c;

                } while(c=='n' || c=='N');

                if (k==999)break;

 

                //削除するデータの存在場所を見つける

                i = H(k);

 

                do

                {

                        if(Key[i]==k)

                        {

                                cout << "データが見つかりました。\n";

                                Sakujoshori(i);  //削除処理実行

                                cout << "データを削除しました。\n";

                                M--;

                                cout << "格納データの個数は " << M

                                         << " 個になりました。\n";

                                break;

                        }

                        else if(Key[i] == Nothing)

                        {

                                cout << "そのデータは存在しません。\n";

                                break;

                        }

                        else

                        {

                                i++;

                        }

                        if(i>=N)i=0;

                } while(1);

 

                //続行判断

                cout << "別のデータを削除しますか。(Y/N) ->";

                cin  >> c;

        } while (c=='y' || c=='Y');

        cout << "削除を終了します。\n";

}

 

int main(void)

{      

        int  k,p;

       

        for(k=0;k<12;k++)

        {

                Key[k] = Nothing;  //キー値の初期化

                Table[k] = Nothing;//データ値の初期化

        }

 

        do{

                cout << "作業を選択してください。\n"

                         << "1.データ格納 \n"

                         << "2.データ検索 \n"

                         << "3.データ削除 \n"

                         << "9. 終了 \n"

                         << "(1/2/3/9) ->";

                cin  >> p;

                if(p==9)break;

 

                if(p>0 || p<4)

                {

                        switch(p)

                        {

                        case 1://データの格納  

                                cout << "「データの格納」が選択されました。\n";

                                Kakunou();

                                break;

                        case 2://データの検索

                                cout << "「データの検索」が選択されました。\n";

                                Kensaku();

                                break;

                        case 3://データの削除

                                cout << "「データの削除」が選択されました。\n";

                                Sakujo();

                                break;

                        }

                }

        }while(1);

 

        return(0);

}