前提・実現したいこと
どんな入力データを入力しても出力されるようにしたいです。
https://paiza.jp/works/mondai/prob60/fortune_telling_4
出力されない入力データ(2つ)
(1つ目)
CCC
3
AAA aaa111
BBB bbb222
CCC ccc333
5
aaa111 zzz
bbb222 yyy
ccc333 xxx
ddd444 www
eee555 vvv
(2つ目)
x
100
FTENQ 4l3AIz3Wz
kv5U hf9iuGifMQ1Y7
9f3yq WFCd
6e 4l3AIz3Wz
AGqZRzuAXDIuYUe EQKjgXYQ9
yvT18uHsaHrOyFDUm8 Un
ZMbluwvUXFoi8 zjsUsGxnFygfRBBMi
x rUW1ZgksZXq5pZey
・・・
発生している問題・エラーメッセージ
Main.c:103:29: warning: incompatible pointer to integer conversion passing 'void *' to parameter of type 'int' [-Wint-conversion] memset(hashtable->data, NULL, sizeof(User*) * size); ^~~~ /usr/lib/llvm-10/lib/clang/10.0.0/include/stddef.h:89:16: note: expanded from macro 'NULL' # define NULL ((void*)0) ^~~~~~~~~~ /usr/include/string.h:61:37: note: passing argument to parameter '__c' here extern void *memset (void *__s, int __c, size_t __n) __THROW __nonnull ((1)); ^ 1 warning generated.
該当のソースコード
C
1 2#include <stdio.h> 3#include <string.h> 4#include <stdlib.h> 5#include <stddef.h> 6 7typedef struct { 8 char user[100]; 9 char blood[100]; 10 char blood2[100]; 11 char fortune[100]; 12} User; 13 14//ハッシュ表 15typedef struct { 16 User **data; 17 unsigned int size; 18} HASHTABLE; 19 20unsigned int MakeHash2(char* str, unsigned int hashmax) 21{ 22 unsigned int n, length, hash, weight; 23 24 length = strlen(str); 25 for (n = weight = hash = 0; n < length; n++, weight++) { 26 if (weight > 7) { 27 weight = 0; 28 } 29 hash += (int)str[n] << (4 * weight); 30 } 31 return hash % hashmax; 32} 33 34unsigned int ReHash(HASHTABLE *hashtable, unsigned int firsthash) 35{ 36 unsigned int hashval, k; 37 38 for (k = 1; k <= hashtable->size / 2; k++) { 39 hashval = (firsthash + k * k) % hashtable -> size; 40 if (hashtable->data[hashval] == NULL) { 41 return hashval; 42 } 43 } 44 return -1; 45} 46 47void AddDataToMap(HASHTABLE *hashtable, User *newdata) 48{ 49 unsigned int hashval; 50 51 hashval = MakeHash2(newdata->user, hashtable->size); 52 53 if (hashtable->data[hashval] != NULL) { 54 hashval = ReHash(hashtable, hashval); 55 if (hashval == -1) { 56 return; 57 } 58 } 59 hashtable->data[hashval] = newdata; 60} 61 62char *GetDataFromMap(HASHTABLE *hashtable, char *key) 63{ 64 unsigned int hashval, k; 65 User *word; 66 67 hashval = MakeHash2(key, hashtable->size); 68 69 for (k = 0; k <= hashtable->size / 2; k++) { 70 word = hashtable->data[(hashval + k * k) % hashtable->size]; 71 if (word != NULL) { 72 if (strcmp(key, word->user) == 0) { 73 return word->blood; 74 } 75 } 76 } 77 return NULL; 78} 79 80char *GetDataFromMap2(HASHTABLE *hashtable, char *key) 81{ 82 unsigned int hashval, k; 83 User *word; 84 85 hashval = MakeHash2(key, hashtable->size); 86 87 for (k = 0; k <= hashtable->size / 2; k++) { 88 word = hashtable->data[(hashval + k * k) % hashtable->size]; 89 if (word != NULL) { 90 if (strcmp(key, word->blood2) == 0) { 91 return word->fortune; 92 } 93 } 94 } 95 return NULL; 96} 97 98 99 100void IniHashTable(HASHTABLE *hashtable, unsigned int size) 101{ 102 hashtable->data = (User**)malloc(sizeof(User*) * size); 103 104 memset(hashtable->data, NULL, sizeof(User*) * size); 105 hashtable->size = size; 106} 107 108void CleanupHashTable(HASHTABLE *hashtable) 109{ 110 free(hashtable->data); 111 hashtable->size = 0; 112} 113 114void PrintAllData(HASHTABLE *hashtable) 115{ 116 unsigned int n; 117 for (n = 0; n < hashtable->size; n++) { 118 if (hashtable->data[n] != NULL) { 119 printf("%s\n", hashtable->data[n]->fortune); 120 } 121 } 122} 123 124int main(void) 125{ 126 char *blood, *blood2; 127 HASHTABLE hashtable; 128 129 IniHashTable(&hashtable, 503); 130 131 char target[100]; 132 scanf("%s", target); 133 134 int n; 135 scanf("%d", &n); 136 137 User u[n]; 138 for (int i = 0; i < n; i++) { 139 scanf("%s%s", u[i].user, u[i].blood); 140 } 141 142 int m; 143 scanf("%d", &m); 144 for (int i = 0; i < m; i++) { 145 scanf("%s%s", u[i].blood2, u[i].fortune); 146 } 147 148 for (int i = 0; i < n; i++) { 149 AddDataToMap(&hashtable, &u[i]); 150 } 151 152 blood = GetDataFromMap(&hashtable, target); 153 154 blood2 = GetDataFromMap2(&hashtable, blood); 155 if (blood2 != NULL) { 156 printf("%s\n", blood2); 157 } 158 159 CleanupHashTable(&hashtable); 160 161 return 0; 162 163}
C
1//エラーはなくなっていませんが100点を取れたコードです。 2#include <stdio.h> 3#include <string.h> 4#include <stdlib.h> 5#include <stddef.h> 6 7typedef struct { 8 char user[100]; 9 char blood[100]; 10} User; 11 12typedef struct { 13 char blood2[100]; 14 char fortune[100]; 15} Result; 16 17//ハッシュ表 18typedef struct { 19 User **data; 20 unsigned int size; 21} HASHTABLE; 22 23typedef struct { 24 Result **data2; 25 unsigned int size2; 26} HASHTABLE2; 27 28unsigned int MakeHash2(char* str, unsigned int hashmax) 29{ 30 unsigned int n, length, hash, weight; 31 32 length = strlen(str); 33 for (n = weight = hash = 0; n < length; n++, weight++) { 34 if (weight > 7) { 35 weight = 0; 36 } 37 hash += (int)str[n] << (4 * weight); 38 } 39 return hash % hashmax; 40} 41 42unsigned int ReHash(HASHTABLE *hashtable, unsigned int firsthash) 43{ 44 unsigned int hashval, k; 45 46 for (k = 1; k <= hashtable->size / 2; k++) { 47 hashval = (firsthash + k * k) % hashtable -> size; 48 if (hashtable->data[hashval] == NULL) { 49 return hashval; 50 } 51 } 52 return -1; 53} 54 55unsigned int ReHash2(HASHTABLE2 *hashtable, unsigned int firsthash) 56{ 57 unsigned int hashval, k; 58 59 for (k = 1; k <= hashtable->size2 / 2; k++) { 60 hashval = (firsthash + k * k) % hashtable -> size2; 61 if (hashtable->data2[hashval] == NULL) { 62 return hashval; 63 } 64 } 65 return -1; 66} 67 68void AddDataToMap(HASHTABLE *hashtable, User *newdata) 69{ 70 unsigned int hashval; 71 72 hashval = MakeHash2(newdata->user, hashtable->size); 73 74 if (hashtable->data[hashval] != NULL) { 75 hashval = ReHash(hashtable, hashval); 76 if (hashval == -1) { 77 return; 78 } 79 } 80 hashtable->data[hashval] = newdata; 81} 82 83void AddDataToMap2(HASHTABLE2 *hashtable, Result *newdata) 84{ 85 unsigned int hashval; 86 87 hashval = MakeHash2(newdata->blood2, hashtable->size2); 88 89 if (hashtable->data2[hashval] != NULL) { 90 hashval = ReHash(hashtable, hashval); 91 if (hashval == -1) { 92 return; 93 } 94 } 95 hashtable->data2[hashval] = newdata; 96} 97 98char *GetDataFromMap(HASHTABLE *hashtable, char *key) 99{ 100 unsigned int hashval, k; 101 User *word; 102 103 hashval = MakeHash2(key, hashtable->size); 104 105 for (k = 0; k <= hashtable->size / 2; k++) { 106 word = hashtable->data[(hashval + k * k) % hashtable->size]; 107 if (word != NULL) { 108 if (strcmp(key, word->user) == 0) { 109 return word->blood; 110 } 111 } 112 } 113 return NULL; 114} 115 116char *GetDataFromMap2(HASHTABLE2 *hashtable, char *key) 117{ 118 unsigned int hashval, k; 119 Result *word; 120 121 hashval = MakeHash2(key, hashtable->size2); 122 123 for (k = 0; k <= hashtable->size2 / 2; k++) { 124 word = hashtable->data2[(hashval + k * k) % hashtable->size2]; 125 if (word != NULL) { 126 if (strcmp(key, word->blood2) == 0) { 127 return word->fortune; 128 } 129 } 130 } 131 return NULL; 132} 133 134 135 136void IniHashTable(HASHTABLE *hashtable, unsigned int size) 137{ 138 hashtable->data = (User**)malloc(sizeof(User*) * size); 139 140 memset(hashtable->data, NULL, sizeof(User*) * size); 141 hashtable->size = size; 142} 143 144void IniHashTable2(HASHTABLE2 *hashtable, unsigned int size) 145{ 146 hashtable->data2 = (User**)malloc(sizeof(User*) * size); 147 148 memset(hashtable->data2, NULL, sizeof(User*) * size); 149 hashtable->size2 = size; 150} 151 152void CleanupHashTable(HASHTABLE *hashtable) 153{ 154 free(hashtable->data); 155 hashtable->size = 0; 156} 157 158void CleanupHashTable2(HASHTABLE2 *hashtable) 159{ 160 free(hashtable->data2); 161 hashtable->size2 = 0; 162} 163 164void PrintAllData(HASHTABLE2 *hashtable) 165{ 166 unsigned int n; 167 for (n = 0; n < hashtable->size2; n++) { 168 if (hashtable->data2[n] != NULL) { 169 printf("%s\n", hashtable->data2[n]->fortune); 170 } 171 } 172} 173 174int main(void) 175{ 176 char *blood, *blood2; 177 HASHTABLE hashtable; 178 HASHTABLE2 hashtable2; 179 180 IniHashTable(&hashtable, 503); 181 IniHashTable2(&hashtable2, 503); 182 183 char target[100]; 184 scanf("%s", target); 185 186 int n; 187 scanf("%d", &n); 188 189 User u[n]; 190 for (int i = 0; i < n; i++) { 191 scanf("%s%s", u[i].user, u[i].blood); 192 } 193 194 int m; 195 scanf("%d", &m); 196 197 Result r[m]; 198 for (int i = 0; i < m; i++) { 199 scanf("%s%s", r[i].blood2, r[i].fortune); 200 } 201 202 for (int i = 0; i < n; i++) { 203 AddDataToMap(&hashtable, &u[i]); 204 AddDataToMap2(&hashtable2, &r[i]); 205 } 206 207 blood = GetDataFromMap(&hashtable, target); 208 209 blood2 = GetDataFromMap2(&hashtable2, blood); 210 if (blood2 != NULL) { 211 printf("%s\n", blood2); 212 } 213 214 CleanupHashTable(&hashtable); 215 CleanupHashTable2(&hashtable2); 216 217 return 0; 218 219}
試したこと
MakeHash2関数とReHash関数で衝突が起こっているのかなと考え、特にMakeHash2関数の
hash += (int)str[n] << (4 * weight);の数字の部分を変えてみたりしましたが上手くいきませんでした。
補足情報(FW/ツールのバージョンなど)
paiza.ioを使用。
「プログラミングの宝箱 アルゴリズムとデータ構造」をもとに少しコードを加えて改造しました。加えた個所はGetDataFromMap2関数です。
回答3件
あなたの回答
tips
プレビュー