BuringStraw

BuringStraw

贴个ハッシュテーブルのコード

問題リンク:
https://www.luogu.com.cn/problem/P4305

#include <stdio.h>
#include <stdlib.h>
#define MAXN 50005//データ範囲
#define MOD 400000//モジュロ、大きすぎないように、そうでないとメモリが足りなくなる
int a[MAXN];//結果を保存するための配列

struct node
{
    struct node* next;//次の項目を指すポインタ
    int value;//このノードに保存されている値
};

struct node* head[MOD];//ハッシュテーブル、いくつかのリストで構成されており、リストのヘッドポインタを格納している

void insert(struct node* p, int v)//ノードpの後にvを挿入する
{
    if (p == NULL) return;//NULLに対して操作はできないので、安全策
    struct node *t = malloc(sizeof(struct node));//新しいノードにメモリを割り当てる
    t -> value = v;//値を設定する
    //挿入のプロセス
    t -> next = p -> next;//この項目の次の項目を前の項目の次の項目に設定する
    p -> next = t;//前の項目の次の項目をこの項目に設定する
}

int find(struct node*p, int v)//ノードpから後ろに向かって探索し、見つかるかリストの末尾に到達するまで探索する
{
    while(p != NULL)//NULLに到達するまでループする。最後の項目のnextはデフォルトでNULLになる
    {
        if (p -> value == v)//vが見つかった
        {
            return 1;//見つかったらループを抜ける
        }
        p = p -> next;//前に進む
    }
    return 0;//見つからなかった場合にのみループを終了する
}

int main() {
    int t;//データの数
    scanf("%d", &t);
    while (t--)//t回だけループする
    {
        for (int i = 0; i < MOD; ++i)
        {
            head[i] = NULL;
        }
        int n;
        scanf("%d", &n);
        int newp = 0;//aの最新の要素のインデックスを記録する。個人的な習慣で、1を最初の要素のインデックスとする
        for (int i = 1; i <= n; ++i)
        {
            int x;
            scanf("%d", &x);//数値を入力する
            int flag = 0;//0は同じデータがないことを示し、1はあることを示す
            int m = x % MOD;//モジュロの結果、headでのインデックスに使用する
            if (m < 0)//負の数のモジュロは負の数になり、インデックスが範囲外になるため
                m = -m;
            //探索は3つの場合に分かれる
            if (head[m] == NULL)//head[m]が指すリストが存在しない
            {//手動で最初の要素を初期化する
                head[m] = malloc(sizeof(struct node));//メモリを割り当てる
                head[m] -> value = x;//値を設定する
                head[m] -> next = NULL;//次の項目はまだない
            } else
            {//リストが存在する
                if (find(head[m], x)/*xを探索*/) flag = 1;//見つかった
                else
                {//見つからなかった
                    struct node* p = head[m];//リストのヘッドポインタを取得する
                    while (p -> next != NULL) p = p -> next;//末尾まで移動する
                    insert(p, x);//挿入する
                }
            }
            if (!flag) a[++newp] = x;//OK、xが見つからなかったので、新しい要素をaに挿入できる
        }

        for (int i = 1; i <= newp; ++i)//出力...
        {
            printf("%d ", a[i]);
        }
        putchar('\n');
    }
    return 0;
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。