|
[ 簡単な説明 ]
バイナリ探索ルーチンの使用例です。 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 |