[ 簡単な説明 ]
バイナリ探索ルーチンの使用例です。 int 型、double 型、文字列型の整列済みのデータ配列内を探索し、その位置を返します。 ランダムデータ生成関数や、乱数発生ルーチン、クイックソートルーチン等を使用しています。 |
/* t_search.c 探索テストルーチン */ #include <stdio.h> #include <stdlib.h> #include "match.h" #define MASK 987612345L #define uchar unsigned char long _idum_o0; /* ornd0()〜ornd2()の乱数核 */ void init_ornd0(long seed); int irnd(int max, int min); double ornd0(void); int *mkdata_i(int n, int min, int max); uchar *mkdata_c(int n, uchar min, uchar max); double *mkdata_d(int n, double min, double max); uchar **mkdata_s(int n, int smin, int smax, uchar min, uchar max); uchar **mkdata_sd(int n, int smin, int smax, uchar min, uchar max); void qsort_i(int a[], int n); void subquick_i(int *first, int *last); void qsort_d(double a[], int n); void subquick_d(double *first,double *last); void qsort_c(uchar *a[], int n); int dbldel_i(int a[], int n, int flag); int dbldel_d(double a[], int n, int flag); int dbldel_c(uchar *a[], int n, int flag); void inssort_i(int a[], int n); void inssort_d(double a[], int n); void inssort_c(uchar *a[], int n); int strcomp(uchar *a, uchar *b); void shuffle_c(uchar **a, int n); int main(void) { int *data_i, *ip, srch_i; double *data_d, *dp, srch_d; uchar **data_c, **cp, *srch_c; int i, n = 100, nn; init_ornd0(1L); data_i = mkdata_i(n, 1, 299); qsort_i(data_i, n); nn = dbldel_i(data_i, n, 1); printf("[int data %d ]\n", nn); for(i = 0, ip = data_i; i < nn; ) printf("%3d:%3d ", i++, *ip++); putchar('\n'); for(i = 0; i < 10; i++) { srch_i = irnd(299, 1); printf("search %3d --> result = %d\n", srch_i, bsrch_i(srch_i, data_i, nn)); } printf("\n\n"); data_d = mkdata_d(n, 1., 299.); for(i = 0, dp = data_d; i < n; i++) *dp++ = (int)(*dp); qsort_d(data_d, n); nn = dbldel_d(data_d, n, 1); printf("[double data %d ]\n", nn); for(i = 0, dp = data_d; i < nn; ) printf("%3d:%3.0f ", i++, *dp++); putchar('\n'); for(i = 0; i < 20; i++) { srch_d = irnd(299, 1); printf("search %3.0f --> result = %d\n", srch_d, bsrch_d(srch_d, data_d, nn)); } printf("\n\n"); data_c = mkdata_sd(n, 2, 2, 'a', 'k'); qsort_c(data_c, n); printf("[string data %d ]\n", n); for(i = 0, cp = data_c; i < n; ) printf("%3d:%2s ", i++, *cp++); putchar('\n'); for(i = 0; i < 10; i++) { srch_c = mkdata_c(2, 'a', 'k'); printf("search %2s --> result = %d\n", srch_c, bsrch_c(srch_c, data_c, n)); } printf("\n\n"); return 1; } double ornd0(void) /* Park and Miller の「最低基準」乱数 */ { long w; double d = 1. / 2147483647.; w = _idum_o0 / 127773L; if((_idum_o0 = (_idum_o0 - w * 127773L) * 16807L - w * 2836L) <= 0) _idum_o0 += 2147483647L; return (double)_idum_o0 * d; } int irnd(int max, int min) { return min + (int)(ornd0() * (double)(max - min + 1)); } void init_ornd0(long seed) { _idum_o0 = seed ^ MASK; } int *mkdata_i(int n, int min, int max) { int i, *data, *p; if(n < 1 || max < min) { fprintf(stderr, "Error : illegal input in mkdata_i()\n"); fprintf(stderr, " n=%d, min=%d, max=%d\n", n, min, max); return NULL; } data = (int *)malloc(n * sizeof(int)); if(data == NULL) { fprintf(stderr, "Error : out of memory in mkdata_i()\n"); return NULL; } for(i = 0, p = data; i < n; i++) *p++ = irnd(max, min); return data; } uchar *mkdata_c(int n, uchar min, uchar max) { int i; uchar *data, *p; if(n < 1 || max < min) { fprintf(stderr, "Error : illegal input in mkdata_c()\n"); fprintf(stderr, " n=%d, min=%u, max=%u\n", n, min, max); return NULL; } data = (uchar *)malloc((n + 1) * sizeof(uchar)); if(data == NULL) { fprintf(stderr, "Error : out of memory in mkdata_c()\n"); return NULL; } for(i = 0, p = data; i < n; i++) *p++ = (uchar)irnd(max, min); *p = '\0'; return data; } double *mkdata_d(int n, double min, double max) { int i; double *data, *p; if(n < 1 || max < min) { fprintf(stderr, "Error : illegal input in mkdata_d()\n"); fprintf(stderr, " n=%d, min=%e, max=%e\n", n, min, max); return NULL; } data = (double *)malloc(n * sizeof(double)); if(data == NULL) { fprintf(stderr, "Error : out of memory in mkdata_d()\n"); return NULL; } for(i = 0, p = data; i < n; i++) *p++ = min + (max - min) * ornd0(); return data; } uchar **mkdata_s(int n, int smin, int smax, uchar min, uchar max) { int i, *len, *lp; uchar **data, **p, *pp; if(n < 1 || max < min || smax < smin || smin < 1) { fprintf(stderr, "Error : illegal input in mkdata_s()\n"); fprintf(stderr, " n=%d, smin=%d, smax=%d, min=%u, max=%u\n", n, smin, smax, min, max); return NULL; } data = (uchar **)malloc(n * sizeof(uchar *)); len = mkdata_i(n, smin, smax); if(data == NULL || len == NULL) { fprintf(stderr, "Error : out of memory in mkdata_s()\n"); return NULL; } for(i = 0, p = data, lp = len; i < n; i++, lp++) { pp = *p++ = (uchar *)malloc((smax + 1) * sizeof(uchar *)); while((*lp)--) *pp++ = irnd(max, min); *pp = '\0'; } free((char *)len); return data; } uchar **mkdata_sd(int n, int smin, int smax, uchar min, uchar max) { uchar **data, **dp, *dpp; int i, len, nn; data = mkdata_s(n, smin, smax, min, max); while(1) { qsort_c(data, n); if((nn = n - dbldel_c(data, n, 1)) == 0) break; dp = data; while(nn--) { while(**dp) dp++; len = irnd(smax, smin); dpp = *dp; while(len--) *dpp++ = irnd(max, min); *dpp = '\0'; } } shuffle_c(data, n); return data; } void qsort_i(int a[], int n) { if(n <= 1) { fprintf(stderr, "Error : n <= 1 in qsort_i()\n"); return; } subquick_i(a, a + n - 1); } void subquick_i(int *first, int *last) { int w; int *i, *j, *p; int x, t; if((w = last - first) < 11) inssort_i(first, w + 1); else { x = *(first + (int)((last - first) / 2)); i = first; j = last; do { while(x > *i) i++; while(*j > x) j--; if(i > j) break; t = *i; *i++ = *j; *j-- = t; } while(i <= j); if(i - 1 > first) subquick_i(first, i - 1); if(j + 1 < last) subquick_i(j + 1, last); } } void qsort_d(double a[], int n) { if(n <= 1) { fprintf(stderr, "Error : n <= 1 in qsort_d()\n"); return; } subquick_d(a, a + n - 1); } void subquick_d(double *first,double *last) { int w; double *i, *j, *p; double x, t; if((w = last - first) < 11) inssort_d(first, w + 1); else { x = *(first + (int)((last - first) / 2)); i = first; j = last; do { while(x > *i) i++; while(*j > x) j--; if(i > j) break; t = *i; *i++ = *j; *j-- = t; } while(i <= j); if(i - 1 > first) subquick_d(first, i - 1); if(j + 1 < last) subquick_d(j + 1, last); } } void qsort_c(uchar *a[], int n) { uchar **i, **j, **l, **r; uchar **st1[32], **st2[32], ***s1, ***s2; uchar *x, *w; if(n <= 1) { fprintf(stderr, "Error : n <= 1 in qsort_c()\n"); return; } s1 = st1; s2 = st2; *s1 = a; *s2 = a + n - 1; do { l = *s1--; r = *s2--; if(r - l < 11) inssort_c(l, r - l + 1); else { do { i = l; j = r; x = *(l + (int)((r - l) / 2)); do { while(strcomp(x, *i) > 0) i++; while(strcomp(*j, x) > 0) j--; if(i > j) break; w = *i; *i++ = *j; *j-- = w; } while(i <= j); if(j - l < r - i) { if(i < r) { *(++s1) = i; *(++s2) = r; } r = j; } else { if(l < j) { *(++s1) = l; *(++s2) = j; } l = i; } } while(l < r); } }while (s1 >= st1); return; } int dbldel_i(int a[], int n, int flag) { int i, nn; int *dp, *wp; nn = 1; wp = dp = a + 1; for(i = 1; i < n; i++, dp++) { if(*(dp - 1) - *dp) { if(wp != dp && flag) *wp = *dp; wp++; nn++; } } if(nn != n && flag) for(i = nn; i < n; i++) *wp++ = 0; return nn; } int dbldel_d(double a[], int n, int flag) { int i, nn; double *dp, *wp; nn = 1; wp = dp = a + 1; for(i = 1; i < n; i++, dp++) { if(*(dp - 1) - *dp) { if(wp != dp && flag) *wp = *dp; wp++; nn++; } } if(nn != n && flag) for(i = nn; i < n; i++) *wp++ = 0.; return nn; } int dbldel_c(uchar *a[], int n, int flag) { int i, len, nn; uchar **dp; if(flag) { for(i = nn = 1, dp = a + 1; i < n; i++, dp++) { if(strcmp(*(dp - 1), *dp)) nn++; else **dp = '\0'; } } else { for(i = nn = 1, dp = a + 1; i < n; i++, dp++) if(strcmp(*(dp - 1), *dp)) nn++; } return nn; } void inssort_i(int a[], int n) { int *p, *pj, *alast, *q, x; if(n <= 1) { fprintf(stderr, "Error : n <= 1 in inssort_i()\n"); return; } alast = (p = a) + n - 1; while(++p <= alast) { q = (pj = p) - 1; x = *p; while(q >= a && *q > x) *pj-- = *q--; *pj = x; } } void inssort_d(double a[], int n) { double *p, *pj, *alast, *q, x; if(n <= 1) { fprintf(stderr, "Error : n <= 1 in inssort_d()\n"); return; } alast = (p = a) + n - 1; while(++p <= alast) { q = (pj = p) - 1; x = *p; while(q >= a && *q > x) *pj-- = *q--; *pj = x; } } void inssort_c(uchar *a[], int n) { uchar **p, **pj, **alast, **q, *x; if(n <= 1) { fprintf(stderr, "Error : n <= 1 in inssort_c()\n"); return; } alast = (p = a) + n - 1; while(++p <= alast) { q = (pj = p) - 1; x = *p; while(q >= a && strcomp(*q, x) > 0) *pj-- = *q--; *pj = x; } } int strcomp(uchar *a, uchar *b) { uchar *p, *q; p = a; q = b; while(*p) { if(*p > *q) return 1; if(*p++ < *q++) return -1; } if(*q) return -1; return 0; } void shuffle_c(uchar **a, int n) { int i, m; uchar **p, **q, *w; for(i = 0, m = n * 5; i < m; i++) { p = a + (int)(ornd0() * n); q = a + (int)(ornd0() * n); w = *p; *p = *q; *q = w; } } |
[int data 86 ] 0: 2 1: 9 2: 11 3: 12 4: 17 5: 35 6: 39 7: 43 8: 44 9: 45 10: 46 11: 56 12: 58 13: 65 14: 71 15: 72 16: 73 17: 75 18: 77 19: 79 20: 80 21: 81 22: 82 23: 85 24: 86 25: 93 26: 96 27: 98 28: 99 29:115 30:118 31:121 32:123 33:126 34:135 35:136 36:139 37:140 38:148 39:149 40:150 41:152 42:156 43:163 44:165 45:167 46:168 47:170 48:171 49:178 50:180 51:186 52:188 53:192 54:194 55:203 56:204 57:207 58:210 59:216 60:218 61:219 62:221 63:222 64:225 65:231 66:234 67:236 68:243 69:244 70:246 71:250 72:252 73:257 74:259 75:260 76:262 77:264 78:267 79:276 80:280 81:281 82:284 83:289 84:292 85:297 search 225 --> result = 64 search 31 --> result = -1 search 131 --> result = -1 search 204 --> result = 56 search 265 --> result = -1 search 207 --> result = 57 search 265 --> result = -1 search 252 --> result = 72 search 109 --> result = -1 search 241 --> result = -1 [double data 83 ] 0: 8 1: 21 2: 22 3: 29 4: 32 5: 33 6: 35 7: 38 8: 39 9: 42 10: 49 11: 61 12: 63 13: 64 14: 65 15: 66 16: 75 17: 77 18: 79 19: 81 20: 82 21: 83 22: 84 23: 93 24: 95 25: 97 26:101 27:102 28:103 29:119 30:123 31:127 32:132 33:136 34:139 35:140 36:146 37:147 38:152 39:154 40:158 41:164 42:166 43:168 44:169 45:170 46:177 47:181 48:183 49:184 50:198 51:199 52:205 53:209 54:211 55:218 56:223 57:226 58:231 59:232 60:234 61:238 62:241 63:244 64:245 65:246 66:252 67:255 68:256 69:258 70:260 71:264 72:266 73:269 74:272 75:277 76:278 77:279 78:283 79:285 80:288 81:296 82:298 search 148 --> result = -1 search 114 --> result = -1 search 243 --> result = -1 search 38 --> result = 7 search 213 --> result = -1 search 209 --> result = 53 search 4 --> result = -1 search 256 --> result = 68 search 89 --> result = -1 search 209 --> result = 53 search 165 --> result = -1 search 9 --> result = -1 search 169 --> result = 44 search 197 --> result = -1 search 108 --> result = -1 search 204 --> result = -1 search 192 --> result = -1 search 248 --> result = -1 search 151 --> result = -1 search 55 --> result = -1 [string data 100 ] 0:aa 1:ab 2:ad 3:ae 4:af 5:ag 6:ah 7:ai 8:ba 9:bb 10:bc 11:bd 12:be 13:bf 14:bg 15:bi 16:bj 17:bk 18:ca 19:cb 20:cd 21:ce 22:cf 23:cg 24:ch 25:ci 26:cj 27:ck 28:da 29:db 30:dc 31:dd 32:de 33:df 34:dg 35:di 36:dj 37:dk 38:ea 39:eb 40:ec 41:ee 42:eg 43:eh 44:ei 45:ej 46:ek 47:fa 48:fb 49:fc 50:fd 51:fe 52:ff 53:fg 54:fi 55:ga 56:gb 57:gc 58:gd 59:ge 60:gg 61:gi 62:gj 63:gk 64:ha 65:hb 66:hc 67:hd 68:he 69:hf 70:hi 71:hj 72:hk 73:ia 74:ib 75:ic 76:id 77:ie 78:if 79:ih 80:ii 81:ij 82:ik 83:jb 84:jc 85:jd 86:je 87:jf 88:jg 89:jh 90:ji 91:jj 92:jk 93:kb 94:kc 95:kd 96:ke 97:kf 98:kh 99:kk search kk --> result = 99 search ee --> result = 41 search bd --> result = 11 search af --> result = 4 search ii --> result = 80 search kc --> result = 94 search cd --> result = 20 search aj --> result = -1 search ke --> result = 96 search kf --> result = 97 |