文字列照合・探索ライブラリ 使用例(バイナリ探索)



[ 簡単な説明 ]

バイナリ探索ルーチンの使用例です。
int 型、double 型、文字列型の整列済みのデータ配列内を探索し、その位置を返します。
ランダムデータ生成関数や、乱数発生ルーチン、クイックソートルーチン等を使用しています。

プログラム・ソース("t_search.c")           top (先頭に戻る)
/*		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;
	}
}

出力結果           top (先頭に戻る)
[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