ALDS1_4_C 辞書をC++で解いてみた[AIZU ONLINE JUDGE]

AIZU ONLINE JUDGE

こんにちは! mnbd(@mnbbbbbd)です。

プログラミング初心者なので、もっといい回答があるに違いありません。

あくまでも「動作はする」サンプルとしてご覧ください。

問題文

以下の命令を実行する簡易的な「辞書」を実装してください。

・insert strstr: 辞書に strstr を追加する。
・find strstr: 辞書に strstr が含まれる場合 ‘yes’と、含まれない場合 ‘no’と出力する。

入力
最初の行に命令の数 n が与えられます。続く n 行に n 件の命令が順番に与えられます。命令の形式は上記のとおりである。

出力
各 find 命令について、yes または no を1行に出力してください。

制約
・与えられる文字列は、’A’, ‘C’, ‘G’, ‘T’ の4種類の文字から構成される。
・1≤文字列の長さ≤12
・n≤1,000,000

https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/4/ALDS1_4_C

解答

#include <bits/stdc++.h>
using namespace std;

int const row = 1046527;
int const col = 14;

char hash_table[row][col];

long long get_char(char c) {
    if(c == 'A') {
        return 1;
    } else if(c == 'C') {
        return 2;
    } else if(c == 'G') {
        return 3;
    } else if(c == 'T') {
        return 4;
    }
    return 0;
}

long long get_key(char str[]) {
    long long sum = 0;
    long long p = 1;
    int len = strlen(str);
    for(long long i = 0; i < len; i++) {
        sum += p * get_char(str[i]);
        p *= 5;
    }
    return sum;
}

int h1(int key) { return key % row; }
int h2(int key) { return 1 + (key % (row - 1)); }

int find(char str[]) {
    long long key = get_key(str), h;
    for(int i = 0;; i++) {
        h = (h1(key) + i * h2(key)) % row;
        if(strcmp(hash_table[h], str) == 0) {
            return 1;
        } else if(strlen(hash_table[h]) == 0) {
            return 0;
        }
    }
}

int insert(char str[]) {
    long long key = get_key(str);
    long long h;
    for(int i = 0;; i++) {
        h = (h1(key) + i * h2(key)) % row;
        if(strcmp(hash_table[h], str) == 0) {
            return 1;
        } else if(strlen(hash_table[h]) == 0) {
            strcpy(hash_table[h], str);
            return 0;
        }
    }
}

int main() {
    int number;
	cin >> number;
    char cmd[20], str[20];
    for(int i = 0; i < row; i++) {
        hash_table[i][0] = '\0';
    }
	vector<bool> ans;
    for(int i = 0; i < number; i++) {
        cin >> cmd >> str;
        if(cmd[0] == 'i') {
            insert(str);
        } else {
            if(find(str)) {
				ans.push_back(true);
            } else {
				ans.push_back(false);
            }
        }
    }

	for (auto b : ans) {
		if (b) {
			cout << "yes" << endl;
		}
		else {
			cout << "no" << endl;
		}
	}

    return 0;
}

感想

最初にハッシュを使わずにvectorやpairを使ってコードを書きましたが、これだと実行時間オーバーで合格できませんでした。

一般解説を見てコードを参考に考えましたが、ハッシュについてわからずに断念しました。

上記は、他の方のコードを参考に写経したコードになります。

このコードで合格にはなるものの、コード内の数式などは理解できてません。

ひとつ一つの関数の理解を深めていきたいです。

まとめ

AIZU ONLINE JUDGEの「ALDS1_4_C 辞書」を解いてみましたので、その回答と解説をご紹介いたしました。

少しずつですが、プログラミングの勉強をしています。
まだ初心者ですが、よかったらつながっていただけると嬉しいです。
Twitterアカウント(@mnbbbbbd

以上です。
読んでいただきありがとうございました!

タイトルとURLをコピーしました