ランダム・データ生成プログラム



[ 簡単な説明 ]

int 型、char 型、double 型、文字列型のランダム・データ配列を生成する関数群です。
各関数を実行する前に、init_mkdata( )関数に、一様乱数の初期設定関数名、乱数生成関数名、初期設定の種を与えて実行する必要があります。

int 型、char 型および double 型のランダム・データ配列生成関数は、配列サイズおよびデータの最小値・最大値を引数に与えて実行すると、配列を自動生成し、その先頭ポインタを返します。

文字列型のランダム・データ生成関数は、配列サイズ、文字列長の最小値・最大値、使用する文字コードの最小値・最大値を引数に与えて実行すると、配列を自動生成し、その先頭ポインタを返します。

mkdata_sd( )関数は、文字列型のランダム・データ生成関数ですが、重複データは排除する機能を持っています。
その機能のため、クイックソート、挿入ソート、文字列比較、重複削除の各関数を実装しています。

ランダム・データ配列生成関数
mkdata_i( ) int 型
mkdata_c( ) char 型
mkdata_d( ) double 型
mkdata_s( ) 文字列型
mkdata_sd( ) 文字列型
(重複データ排除)

プログラム・ソース("mkdata.c")           top (トップに戻る)
/*		mkdata.c		*/
#include <stdio.h>
#include <stdlib.h>
#include "random.h"

void qsort_c(unsigned char *a[], int n);
int strcomp(unsigned char *a, unsigned char *b);
int dbldel_c(unsigned char *a[], int n, int flag);
void inssort_c(unsigned char *a[], int n);

void init_mkdata(void (*initfunc)(long s), double (*func)(void), long seed)
{
	init_irnd(initfunc, func, seed);
}

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;
}

unsigned char *mkdata_c(int n, unsigned char min, unsigned char max)
{
	int i;
	unsigned char *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 = (unsigned char *)malloc((n + 1) * sizeof(unsigned char));
	if(data == NULL)
	{
		fprintf(stderr, "Error : out of memory  in mkdata_c()\n");
		return NULL;
	}
	for(i = 0, p = data; i < n; i++)	*p++ = (unsigned char)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) * _rand();
	return data;
}

unsigned char **mkdata_s(int n, int smin, int smax, unsigned char min, unsigned char max)
{
	int i, *len, *lp;
	unsigned char **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 = (unsigned char **)malloc(n * sizeof(unsigned char *));
	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++ = (unsigned char *)malloc((smax + 1) * sizeof(unsigned char *));
		while((*lp)--)	*pp++ = irnd(max, min);
		*pp = '\0';
	}
	free((char *)len);
	return data;
}

unsigned char **mkdata_sd(int n, int smin, int smax, unsigned char min, unsigned char max)
{
	unsigned char **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, 5L);
	return data;
}

void qsort_c(unsigned char *a[], int n)
{
	unsigned char **i, **j, **l, **r;
	unsigned char **st1[32], **st2[32], ***s1, ***s2;
	unsigned char *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 strcomp(unsigned char *a, unsigned char *b)
{
	unsigned char *p, *q;

	p = a;
	q = b;
	while(*p)
	{
		if(*p > *q)	return 1;
		if(*p++ < *q++)	return -1;
	}
	if(*q)	return -1;
	return 0;
}

int dbldel_c(unsigned char *a[], int n, int flag)
{
	int i, nn;
	unsigned char **dp, **wp;

	nn = 1;
	wp = dp = a + 1;
	for(i = 1; i < n; i++, dp++)	if(strcomp(*(dp - 1), *dp))	nn++;
	if(nn != n && flag)
	{
		wp = a;
		dp = a + 1;
		i = n - nn;
		while(i > 0)
		{
			if(strcomp(*wp, *dp) == 0)
			{
				**dp = '\0';
				i--;
			}
			else	wp = dp;
			dp++;
		}
	}
	return nn;
}

void inssort_c(unsigned char *a[], int n)
{
	unsigned char *x;
	int i, j;

	if(n <= 1)
	{
		fprintf(stderr, "Error : n <= 1  in inssort_c()\n");
		return;
	}
	for(i = 1; i < n; i++)
	{
		x = a[i];
		j = i - 1;
		while(j >= 0 && strcomp(a[j], x) > 0)
		{
			a[j + 1] = a[j];
			j--;
		}
		a[j + 1] = x;
	}
}