【C】【吐血整理】你们要的C语言实例大全-综合应用篇

【C】【吐血整理】你们要的C语言实例大全-综合应用篇

目录

 

实例94 用C语言实现遗传算法

实例95 人工神经网络的C语言实现

实例96 K_均值算法

实例97 ISODATA算法

实例98 快速傅立叶变换

实例99 求解野人与传教士问题

实例100 简单专家系统


实例94 用C语言实现遗传算法

ga.c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

#define SUM 20            //总共的染色体数量
#define MAXloop 1200       //最大循环次数
#define error 0.01        //若两次最优值之差小于此数则认为结果没有改变
#define crossp 0.7        //交叉概率
#define mp 0.04           //变异概率

struct gen                //定义染色体结构
{
	int info;        
	float suitability;
};
struct gen gen_group[SUM];//定义一个含有20个染色体的组
struct gen gen_new[SUM];  

struct gen gen_result;    //记录最优的染色体
int result_unchange_time; //记录在error前提下最优值为改变的循环次数

struct log                //形成链表,记录每次循环所产生的最优的适应度
{
	float suitability;
	struct log *next;
}llog,*head,*end;
int log_num;              //链表长度

void initiate();          
void evaluation(int flag);
void cross();
void selection();
int  record();
void mutation();
void showresult(int);

int   randsign(float p);
int   randbit(int i,int j);
int   randnum();
int   convertionD2B(float x);
float convertionB2D(int x);
int   createmask(int a);

void main()
{
	int i,flag;
	flag=0;
	initiate();
    evaluation( 0 );
	for( i = 0 ; i < MAXloop ; i++ )
	{
		cross();
		evaluation( 1 );
		selection();
		if( record() == 1 )
		{
			flag = 1;
			break;
		}
		mutation();
	}
	showresult( flag );
}

void initiate()
{
	int i , stime;	
	long ltime;
	ltime=time(NULL);
	stime=(unsigned)ltime/2;
	srand(stime);
	for( i = 0 ; i < SUM ; i++ )
	{
		gen_group[i].info = randnum();		 
	}
	gen_result.suitability=1000;
	result_unchange_time=0;
	head=end=(struct log *)malloc(sizeof(llog));
	if(head==NULL)
	{
		printf("\n内存不够!\n");
		exit(0);
	}
	end->next = NULL;
	log_num = 1;
}

void evaluation(int flag)
{
	int i,j;
	struct gen *genp;
	int gentinfo;
	float gentsuitability;
	float x;
	if( flag == 0 )
		genp = gen_group;
	else genp = gen_new;
	for(i = 0 ; i < SUM ; i++)//计算各染色体对应的表达式值
	{
		x = convertionB2D( genp[i].info );
		genp[i].suitability = x*(x*(x*(x*(x*(x-10)-26)+344)+193)-1846)-1680;
	}
	for(i = 0 ; i < SUM - 1 ; i++)//按表达式的值进行排序,
	{
		for(j = i + 1 ; j < SUM ; j++)
		{
			if( genp[i].suitability > genp[j].suitability )
			{
				gentinfo = genp[i].info;
				genp[i].info = genp[j].info;
				genp[j].info = gentinfo;
				
				gentsuitability = genp[i].suitability;
				genp[i].suitability = genp[j].suitability;
				genp[j].suitability = gentsuitability;		
			}
		}
	}
}

void cross()
{
	int i , j , k ;
	int mask1 , mask2;
	int a[SUM];
	for(i = 0 ; i < SUM ; i++)  a[i] = 0;
	k = 0;
	for(i = 0 ; i < SUM ; i++)
	{
		if( a[i] == 0)
		{
			for( ; ; )//随机找到一组未进行过交叉的染色体与a[i]交叉
			{
   				j = randbit(i + 1 , SUM - 1);
				if( a[j] == 0)	break;
			}
			if(randsign(crossp) == 1)
			{
				mask1 = createmask(randbit(0 , 14));
				mask2 = ~mask1;
				gen_new[k].info = (gen_group[i].info) & mask1 + (gen_group[j].info) & mask2;
				gen_new[k+1].info=(gen_group[i].info) & mask2 + (gen_group[j].info) & mask1;
				k = k + 2;
			}
			else 
			{
				gen_new[k].info=gen_group[i].info;
				gen_new[k+1].info=gen_group[j].info;
				k=k+2;
			}
			a[i] = a[j] = 1;
		}
	}
}

void selection()
{
	int i , j , k;
	j = 0;
	i = SUM/2-1;
	if(gen_group[i].suitability < gen_new[i].suitability)
	{
		for(j = 1 ; j < SUM / 2 ; j++)
		{
			if(gen_group[i+j].suitability > gen_new[i-j].suitability)
				break;
		}
	}
	else
		if(gen_group[i].suitability>gen_new[i].suitability)
		{
			for(j=-1;j>-SUM/2;j--)
			{
				if(gen_group[i+j].suitability<=gen_new[i-j].suitability)
					break;
			}
		}
	for(k=j;k<SUM/2+1;k++)
	{
		gen_group[i+k].info = gen_new[i-k].info;
		gen_group[i+k].suitability = gen_new[i-k].suitability;
	}	
}

int record()
{
	float x;	
	struct log *r;
	r=(struct log *)malloc(sizeof(llog));
	if(r==NULL)
	{
		printf("\n内存不够!\n");
		exit(0);
	}
	r->next = NULL;
	end->suitability = gen_group[0].suitability;
	end->next = r;
	end = r;
	log_num++;

	x = gen_result.suitability - gen_group[0].suitability;
	if(x < 0)x = -x;
	if(x < error)
	{
		result_unchange_time++;
		if(result_unchange_time >= 20)return 1;
	}
	else
	{
		gen_result.info = gen_group[0].info;
		gen_result.suitability = gen_group[0].suitability;
		result_unchange_time=0;
	}
	return 0;
}

void mutation()
{
	int i , j , m;
	float x;
	float gmp;
	int gentinfo;
	float gentsuitability;
	gmp = 1 - pow(1 - mp , 11);//在基因变异概率为mp时整条染色体的变异概率
	for(i = 0 ; i < SUM ; i++)
	{
		if(randsign(gmp) == 1)
		{
			j = randbit(0 , 14);
			m = 1 << j;
			gen_group[i].info = gen_group[i].info^m;
			x = convertionB2D(gen_group[i].info);
			gen_group[i].suitability = x*(x*(x*(x*(x*(x-10)-26)+344)+193)-1846)-1680;
		}
	}
	for(i = 0 ; i < SUM - 1 ; i++)
	{
		for(j = i + 1 ; j < SUM ; j++)
		{
			if(gen_group[i].suitability > gen_group[j].suitability)
			{
				gentinfo = gen_group[i].info;
				gen_group[i].info = gen_group[j].info;
				gen_group[j].info = gentinfo;
				
				gentsuitability = gen_group[i].suitability;
				gen_group[i].suitability = gen_group[j].suitability;
				gen_group[j].suitability = gentsuitability;
			}
		}
	}
}

void showresult(int flag)//显示搜索结果并释放内存
{
	int i , j;
	struct log *logprint,*logfree;
	FILE *logf;
	if(flag == 0)
		printf("已到最大搜索次数,搜索失败!");
	else 
	{
		printf("当取值%f时表达式达到最小值为%f\n",convertionB2D(gen_result.info),gen_result.suitability);
		printf("收敛过程记录于文件log.txt");
		if((logf = fopen("log.txt" , "w+")) == NULL)
		{
			printf("Cannot create/open file");
			exit(1);
		}
		logprint=head;
		for(i = 0 ; i < log_num ; i = i + 5)//对收敛过程进行显示
		{
			for(j = 0 ; (j < 5) & ((i + j) < log_num-1) ; j++)
			{
				fprintf(logf , "%20f" , logprint->suitability);
				logprint=logprint->next;				
			}
			fprintf(logf,"\n\n");
		}
	}
	for(i = 0 ; i< log_num ; i++)//释放内存
	{
		logfree=head;
		head=head->next;
		free(logfree);
		fclose(logf);
	}
	getchar();
}

int randsign(float p)//按概率p返回1
{
	if(rand() > (p * 32768))
		return 0;
	else return 1;
}
int randbit(int i, int j)//产生在i与j之间的一个随机数
{
	int a , l;
	l = j - i + 1;
	a = i + rand() * l / 32768;
	return a;
}
int randnum()
{
	int x;
	x = rand() / 2;
	return x;
}
float convertionB2D(int x)
{
	float y;
	y = x;
	y = (y - 8192) / 1000;
	return y;
	
}
int convertionD2B(float x)
{
	int g;
	g = (x * 1000) + 8192;
	return g;
}
int createmask(int a)
{
	int mask;
	mask=(1 << (a + 1)) - 1;
	return mask;
}


实例95 人工神经网络的C语言实现

BP.C

#include "math.h"
#include "time.h"
#include "stdio.h"
#include "stdlib.h"
#define Ni 1
#define Nm 4
#define No 1
#define L 100
#define Enom 0.02
#define loopmax 100000
#define e 2.71828
double E;
double a,u,n;
double W1[Ni][Nm],D1[Ni][Nm],W2[Nm][No],D2[Nm][No];
double D22[Nm][No],D11[Ni][No];
double a1[Ni][Nm],a2[Nm][No];
double Pi[L][Ni],Pm[L][Nm],Po[L][No],T[L][No];
double Xm[L][Nm],Xo[L][No];
double Qm[L][Nm],Qo[L][No];
void proceed();
void proceedR();
void forQ();
void amend();
void initiate();
double newa(double a,double D);
double cal(double d);
double vcal(double d);
main()
{
    long int i;
	int flag;
	char choice;
    for(;;)
	{
		flag=0;
		initiate();
		for(i=0;;i++)
		{
			proceed();
			if( E < Enom )
			{ 
				flag=1;
				break;
			}
			if( i >= loopmax)
			{
				flag = -1;
				break;
			}
			if(i%2500==0)
				printf("第%10d轮误差:%20f,学习速率:%10f\n",i,E,a1[0][0]);
			forQ();
			amend();
		}
		if(flag>0)proceedR();
		else printf("训练失败!\n");
		for(;;)
		{
			choice=getchar();
			printf("是否继续?(Y/N)\n");
			choice=getchar();
			choice=toupper(choice);
			if(choice=='Y')break;
			if(choice=='N')exit(0);
		}
	}
}
void initiate()
{
	int i,j;
	int random;
	double x;
	double step;
	int stime;	
	long ltime;
	ltime=time(NULL);
	stime=(unsigned)ltime/2;
	srand(stime);
	a=0.02;
	u=1;
    n=1;
	printf("本程序将用BP神经网络拟合函数:Y=sin(X)\n\n");
	for( i=0; i<Nm; i++)
	{
		for( j=0; j<Ni; j++)
		{
			random=rand()%100-50;
			x=random;
			x=x/100;
			W1[j][i]=x;
			D11[j][i]=0;
			D1[j][i]=0;
			a1[j][i]=0.01;
		}
		for( j=0; j<No; j++)
		{
			random=rand()%100-50;
			x=random;
			x=x/100;
			W2[i][j]=x;
			D22[i][j]=0;
			D2[i][j]=0;
			a2[i][j]=0.01;
		}
	}
    step=1.0/L;
	for(i=0;i<L;i++)
	{
		x=i;
		Pi[i][0]=x*step;
		T[i][0]=sin(Pi[i][0]);
	}
	printf("初始化成功!\n\n下面将对神经网络进行训练请稍候。\n");
}
void proceed()
{
	int i, j, k;
	E=0 ;
	for( i=0; i<L; i++ )
	{
		for( j=0; j<Nm; j++ )
		{
			Pm[i][j] = 0;
			for( k=0; k<Ni; k++ )
			{
				Pm[i][j] = Pi[i][k] * W1[k][j] + Pm[i][j];
			}
			Xm[i][j] = cal( Pm[i][j] );
		}
		for( j=0; j<No; j++)
		{
			Po[i][j] = 0;
			for( k=0; k<Nm; k++)
			{
				Po[i][j] = Xm[i][k] * W2[k][j] + Po[i][j];
			}
			Xo[i][j] = cal( Po[i][j] );
		    E = E + ( Xo[i][j] - T[i][j] ) * ( Xo[i][j] - T[i][j] ) / 2;
		}
	}
}
void forQ()
{
	int i,j,k;
	for( i=0; i<L; i++ )
	{
		for( j=0; j<No; j++)
		{
			Qo[i][j] = ( T[i][j] - Xo[i][j] )* vcal( Xo[i][j] );
		}
		for(j=0; j<Nm; j++)
		{
			Qm[i][j]=0;
			for( k=0; k<No; k++)
			{
				Qm[i][j] = Qo[i][k] * W2[j][k] + Qm[i][j];
			}
			Qm[i][j] = Qm[i][j] * vcal( Xm[i][j] );
		}
	}
}
void amend()
{
	int i,j,k;
	double D;
	for( i=0; i<Nm; i++)
	{
		for( j=0; j<Ni; j++)
		{
			D1[j][i]=0;
		}
		for( j=0; j<No; j++)
		{
			D2[i][j]=0;
		}
	}
	for( i=0; i<Ni; i++)
	{
		for( j=0; j<Nm; j++)
		{
			for( k=0; k<L; k++)
			{
				D1[i][j] = Qm[k][j] * Pi[k][i] + D1[i][j];
			}
             D = D1[i][j] * D11[i][j]  ;//为D11付初值
			 a1[i][j] = newa( a1[i][j] , D );  // a 付初值
			 W1[i][j] = W1[i][j] + a1[i][j] * ( n * D1[i][j] + ( 1 - n ) * D11[i][j] );
			 D11[i][j] = D1[i][j];
		}
	}
    for( i=0; i<Nm; i++)
	{
		for( j=0; j<No; j++)
		{
			for( k=0; k<L; k++)
			{
				D2[i][j] = Qo[k][j] * Xm[k][i] + D2[i][j];
			}
			D = D2[i][j] * D22[i][j]  ;//为D11付初值
            a2[i][j] = newa( a2[i][j] , D ); 
			W2[i][j] = W2[i][j] + a2[i][j] * ( n * D2[i][j] + ( 1 - n ) * D22[i][j] );
			D22[i][j] = D2[i][j];
		}
	}
}
 void proceedR()
{
	int i, j;
	float x;
	double input,output;
	char choice;
	for(;;)
	{
		for(;;)
		{
			printf("在此输入需要计算的值(0,1):\n");
			scanf("%f",&x);
			input=(double)x;
			if((input>=0)&(input<=1))break;			
			printf("注意输入值应介于0、1之间!\n");
			for(;;)
			{
				choice=getchar();
				printf("是否继续?(Y/N)\n");
				choice=getchar();
				choice=toupper(choice);
				if(choice=='Y')break;
				if(choice=='N')exit(0);			
			}
		}
		for(i=0;i<Nm;i++)
		{
			Pm[0][i]=0;
			for( j=0; j<Ni; j++ )
			{
				Pm[0][i] =  input* W1[j][i]+Pm[0][i] ;
			}
			Xm[0][i] = cal( Pm[0][i] );
		}
		for( i=0; i<No; i++)
		{
			Po[0][i] = 0;
			for( j=0; j<Nm; j++)
			{
				Po[0][i] = Xm[0][j] * W2[j][i]+Po[0][i];
			}
		}
		output=cal( Po[0][0] );
		printf("输入值为%20f对应的结果为%f\n",input,output);
		printf("输入值为%20f对应的正常结果为%f\n",input,sin(input));
		for(;;)
		{
			choice=getchar();
			printf("是否继续?(Y/N)\n");
			choice=getchar();
			choice=toupper(choice);
			if(choice=='Y')break;
			if(choice=='N')exit(0);			
		}
	}
}

double newa(double a, double D)
{
	if( D > 0 )
	{
		{
			if(a<=0.04)
				a = a * 2;
			else a=0.08;
		}
	}
	else
		if ( D < 0)
		{
			if(a>=0.02)
			{
				a = a / 2;
			}
			else a=0.01;
		}
	return a;
}
double cal(double d)
{
	d =  - (d * u);                                //              chushihua 
	d = exp( d );
	d = 1 / ( 1 + d );
	return d;
}
double vcal(double d)
{
	return u * d * ( 1 - d );
}

trust100@ubuntu:~/test/clanguage$ ./a.out 
本程序将用BP神经网络拟合函数:Y=sin(X)

初始化成功!

下面将对神经网络进行训练请稍候。
第         0轮误差:            3.182817,学习速率:  0.010000
第      2500轮误差:            3.182817,学习速率:  0.010000
第      5000轮误差:            3.182817,学习速率:  0.010000
第      7500轮误差:            3.182817,学习速率:  0.010000
第     10000轮误差:            3.182817,学习速率:  0.010000
第     12500轮误差:            3.182817,学习速率:  0.010000
第     15000轮误差:            3.182817,学习速率:  0.010000
第     17500轮误差:            3.182817,学习速率:  0.010000
第     20000轮误差:            3.182817,学习速率:  0.010000
第     22500轮误差:            3.182817,学习速率:  0.010000
第     25000轮误差:            3.182817,学习速率:  0.010000
第     27500轮误差:            3.182817,学习速率:  0.010000
第     30000轮误差:            3.182817,学习速率:  0.010000
第     32500轮误差:            3.182817,学习速率:  0.010000
第     35000轮误差:            3.182817,学习速率:  0.010000
第     37500轮误差:            3.182817,学习速率:  0.010000
第     40000轮误差:            3.182817,学习速率:  0.010000
第     42500轮误差:            3.182817,学习速率:  0.010000
第     45000轮误差:            3.182817,学习速率:  0.010000
第     47500轮误差:            3.182817,学习速率:  0.010000
第     50000轮误差:            3.182817,学习速率:  0.010000
第     52500轮误差:            3.182817,学习速率:  0.010000
第     55000轮误差:            3.182817,学习速率:  0.010000
第     57500轮误差:            3.182817,学习速率:  0.010000
第     60000轮误差:            3.182817,学习速率:  0.010000
第     62500轮误差:            3.182817,学习速率:  0.010000
第     65000轮误差:            3.182817,学习速率:  0.010000
第     67500轮误差:            3.182817,学习速率:  0.010000
第     70000轮误差:            3.182817,学习速率:  0.010000
第     72500轮误差:            3.182817,学习速率:  0.010000
第     75000轮误差:            3.182817,学习速率:  0.010000
第     77500轮误差:            3.182817,学习速率:  0.010000
第     80000轮误差:            3.182817,学习速率:  0.010000
第     82500轮误差:            3.182817,学习速率:  0.010000
第     85000轮误差:            3.182817,学习速率:  0.010000
第     87500轮误差:            3.182817,学习速率:  0.010000
第     90000轮误差:            3.182817,学习速率:  0.010000
第     92500轮误差:            3.182817,学习速率:  0.010000
第     95000轮误差:            3.182817,学习速率:  0.010000
第     97500轮误差:            3.182817,学习速率:  0.010000
训练失败!


实例96 K_均值算法

k_algorithm.c

#include  <stdio.h>

#include  <stdlib.h>

#include  <string.h>

#include  <math.h>

int  vectornum;

int  vectorsize;

float  * datafield;

float  * tempcenter;

struct  GROUP

{

	float  * center;//聚类中心坐标
	
	int  groupsize;//聚类包含的样本个数

} g ,  * group;

int  K;//聚类中心个数



void  initiate ();//读入数据,初始化聚类中心,参数设定默认值

int  allocate ();//将模式样本分配给最近的聚类

void  showresult ();//显示分类结果



float  distance (float  * x , float  * y);//计算两个向量间的欧氏距离

float  data (int i , int j);//从datafield中读取指定位置的值

float  * vector (int i);//从datafield中读取指定的样本向量

void  write (int i , int j , float data);//向datafield中指定位置写入值



void  main ()

{

	int  i;
	
	initiate ();
    
	for (i = 1 ; i < 50 ; i++)
	
	{
	
		showresult ();
		
		if (allocate () == 1)break;
	
	}	
	
	showresult ();

	free (datafield);
	
	free (tempcenter);
	
	for (i = 0 ; i < K ; i++)
	
		free (group[i].center);

}



void  initiate ()

{

	int  i , j , size;
	
	float  d;
	
	FILE  * df;
	
	K = 2;
	
	if ((df = fopen ("data.txt" , "r")) == NULL)
	
	{
	
		printf ("Cannot open file\n");
		
		exit (1);
	
	}
	
	fscanf (df , "%5d" , &vectornum);
	
	fscanf (df , "%5d" , &vectorsize);
	
	size = vectornum * (vectorsize + 1);
	
	datafield = (float *) calloc (size , sizeof (d));
	
	tempcenter = (float *) calloc (vectorsize , sizeof (d));
	
	for (i = 0 ; i < vectornum ; i++)
	
	{
	
		for (j = 0 ; j < vectorsize ; j++)
		
		{
		
			fscanf (df , "%10f" , &d);
			
			write (i , j + 1 , d);
		
		}
		
		write (i , 0 , -1);
	
	}
	
	if (feof (df)) printf (" File read error! ");
	
	fclose (df);	
	
	printf ("请输入聚类数:\n");
	
	scanf ("%d" , &K);
	
	group = (struct GROUP *) calloc (K , sizeof (g));	
	
	for (i = 0 ; i < K ; i++)
	
	{
	
		group[i].center = (float*) calloc ((vectorsize) , sizeof (d));
		
		group[i].groupsize = 0;
	
	}
	
	for (i = 0 ; i < K ; i++)
	
	{
	
		for (j = 0 ; j < vectorsize ; j++)
		
		{
		
			*(group[i].center + j) = data (i , j + 1);

		}
	
	}

}


	
int  allocate()

{

	int  i , j , k , flag , index;
	
	float  D , D1 , sum;	
	
	for (i = 0 ; i < K ; i++)
	
	{
	
		group[i].groupsize = 0;
	
	}
	
	for (i = 0 ; i < vectornum ; i++)//按距离分配到各聚类域
	
	{
	
		D = distance (group[0].center , vector(i));
		
		k = 0;
		
		for(j = 1 ; j < K ; j++)
		
		{
		
			D1 = distance (group[j].center , vector(i));
			
			if(D > D1)
			
			{
			
				k = j;
				
				D = D1;
			
			}
		
		}

		write (i , 0 , (float) k);		
		
		group[k].groupsize++;
	
	}
	
	flag = 1;
	
	for (index = 0 ; index < K ; index++)//计算新的聚类中心
	
	{
	
		for (j = 0 ; j < vectorsize ; j++)
		
			tempcenter[j] = 0.0;
		
		sum = (float) group[index].groupsize;
		
		for (i = 0 ; i < vectornum ; i++)
		
		{
		
			if (index == (int) data (i , 0))
			
				for (j = 0 ; j < vectorsize ; j++)
				
					tempcenter[j] += data (i , j + 1) / sum;
		
		}
		
		for (j = 0 ; j < vectorsize ; j++)
		
		{
		
			if ( tempcenter[j] != group[index].center[j])
			
			{
			
				group[index].center[j] = tempcenter[j];
				
				flag = 0;
			
			}
		
		}

	}
	
	return flag;	

}



void  showresult()

{

	int  i , j , k;
	
	for (i = 0 ; i < K ; i++)
	
	{	
	
		printf ("\n第%3d组聚类中心坐标为:" , i + 1);
		
		for (j = 0 ; j < vectorsize ; j++)
		
			printf (" %10f " , group[i].center[j]);
		
		printf (" \n聚类包含的样本点的坐标为:\n ");
		
		for (j = 0 ; j < vectornum ; j++)
		
		{
		
			if (data (j , 0) == i)
			
			{
			
				for (k = 0 ; k < vectorsize ; k++)
				
				{
				
					printf (" %10f " , data (j , k + 1));
				
				}
				
				printf (" \n ");
			
			}
	
		}	
		
	}

	printf (" \n ");

}



float  data (int i , int j)

{

	return *(datafield + i * (vectorsize + 1) + j);

}



void  write (int i , int j , float data)

{

	*(datafield + i * (vectorsize + 1) + j) = data;

}



float  * vector (int i)

{ 

	return datafield + i * (vectorsize + 1) + 1;

}



float  distance (float  * x , float  * y)
{

	int  i;
	
	float  z;
	
	for (i = 0 , z = 0 ; i < vectorsize ; i++)
	
		z = z + ((* (x + i)) - (* (y + i)))*((* (x + i))-(* (y + i)));
	
	return (float) sqrt (z);

}

数据文件 data.txt

    8    2  0.000000  0.000000  1.000000  1.000000  2.000000  2.000000  4.000000  3.000000  5.000000  3.000000  4.000000  4.000000  5.000000  4.000000  6.000000  5.000000       end

运行

 trust100@ubuntu:~/test/clanguage$ ./a.out 
请输入聚类数:
10

第  1组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
 
第  2组聚类中心坐标为:   1.000000    1.000000  
聚类包含的样本点的坐标为:
 
第  3组聚类中心坐标为:   2.000000    2.000000  
聚类包含的样本点的坐标为:
 
第  4组聚类中心坐标为:   4.000000    3.000000  
聚类包含的样本点的坐标为:
 
第  5组聚类中心坐标为:   5.000000    3.000000  
聚类包含的样本点的坐标为:
 
第  6组聚类中心坐标为:   4.000000    4.000000  
聚类包含的样本点的坐标为:
 
第  7组聚类中心坐标为:   5.000000    4.000000  
聚类包含的样本点的坐标为:
 
第  8组聚类中心坐标为:   6.000000    5.000000  
聚类包含的样本点的坐标为:
 
第  9组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
 
第 10组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
  
 
第  1组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
    0.000000    0.000000  
 
第  2组聚类中心坐标为:   1.000000    1.000000  
聚类包含的样本点的坐标为:
    1.000000    1.000000  
 
第  3组聚类中心坐标为:   2.000000    2.000000  
聚类包含的样本点的坐标为:
    2.000000    2.000000  
 
第  4组聚类中心坐标为:   4.000000    3.000000  
聚类包含的样本点的坐标为:
    4.000000    3.000000  
 
第  5组聚类中心坐标为:   5.000000    3.000000  
聚类包含的样本点的坐标为:
    5.000000    3.000000  
 
第  6组聚类中心坐标为:   4.000000    4.000000  
聚类包含的样本点的坐标为:
    4.000000    4.000000  
 
第  7组聚类中心坐标为:   5.000000    4.000000  
聚类包含的样本点的坐标为:
    5.000000    4.000000  
 
第  8组聚类中心坐标为:   6.000000    5.000000  
聚类包含的样本点的坐标为:
    6.000000    5.000000  
 
第  9组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
 
第 10组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
  
 
第  1组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
    0.000000    0.000000  
 
第  2组聚类中心坐标为:   1.000000    1.000000  
聚类包含的样本点的坐标为:
    1.000000    1.000000  
 
第  3组聚类中心坐标为:   2.000000    2.000000  
聚类包含的样本点的坐标为:
    2.000000    2.000000  
 
第  4组聚类中心坐标为:   4.000000    3.000000  
聚类包含的样本点的坐标为:
    4.000000    3.000000  
 
第  5组聚类中心坐标为:   5.000000    3.000000  
聚类包含的样本点的坐标为:
    5.000000    3.000000  
 
第  6组聚类中心坐标为:   4.000000    4.000000  
聚类包含的样本点的坐标为:
    4.000000    4.000000  
 
第  7组聚类中心坐标为:   5.000000    4.000000  
聚类包含的样本点的坐标为:
    5.000000    4.000000  
 
第  8组聚类中心坐标为:   6.000000    5.000000  
聚类包含的样本点的坐标为:
    6.000000    5.000000  
 
第  9组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
 
第 10组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:


实例97 ISODATA算法

isogroup.c

#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <math.h>
float  * datafield;
int  vectornum;
int  vectorsize;
struct  GROUP
{
	float  * center;
	float  D;
	float  variance;
	int  groupsize;
	int  flag;//代表这个数组单元是否被占用
};
struct  GROUP  group[100];
int  maxindex;//最大聚类号
int  groupnum;
struct  CCD//记录各聚类中心的距离
{
	float  dst;
	int  g1 , g2;//聚类编号
}ccd  ,  * ccdhead;
float  Dst;

void  write (int i , int j , float data);//
float  data (int i , int j);//
float  * vector (int  i);//

void  initiate ();//
void  input ();//
void  allocate ();//将模式样本分配给最近的聚类
void  converge ();//
void  diverge ();//
void  renum ();//重新分配聚类号
void  showresult ();

float  distance (float  * x , float  * y);
void  split (int i , int j);//
void  insert (int i , int j , float D);

int  K;//预期的聚类中心数目
int  Nmin;//每一聚类中最少的样本数目,即如少于此数就不作为一个孤立的聚类
float  Ds;//一个聚类域中样本距离分布的标准差
float  Dm;//两个聚类中心之间的最小距离,如小于此数,两个聚类进行合并
int  L;//在于此迭代运算中可以合并的聚类中心的最多对数
int  I;//迭代运算的次数序号

void  main ()
{
	int  i;
	initiate ();//读入数据,初始化聚类中心,参数设定默认值
	for (i = 1 ; ; i++)
	{
		input ();//显示、修改参数
		allocate ();//完成第2-6步
		if (i == I)
		{
			Dm = 0;
			converge ();
			break;
		}
		if (groupnum <= K / 2)  diverge ();
		else 
		{
			if ((groupnum >= K * 2) | ( i % 2 == 0))
				converge ();
			else 
				diverge ();
		}		
		renum ();		
	}
	showresult ();
	free (datafield);
	free (ccdhead);
	for (i = 0 ; i < 100 ; i++)
		free (group[i].center);
}
void  initiate ()
{
	int  i , j , size;
	FILE  * df;
	char  s[10];
	float  d;
	K = 2;
	Nmin = 1;
	Ds = 1;
	Dm = 4;
	L = 1;
	I = 5;
	maxindex = groupnum = 1;
	if ((df = fopen("data.txt" , "r")) == NULL)
	{
		printf ("Cannot open file\n");
		exit (1);
	}
	fscanf (df , "%5d" , &vectornum);
	fscanf (df , "%5d" , &vectorsize);
	size = vectornum * (vectorsize + 1);
	datafield = (float *) malloc (size * sizeof (float));
	for (i = 0 ; i < vectornum ; i++)
	{
		for (j = 0 ; j < vectorsize ; j++)
		{
			fscanf (df , "%10f" , &d);
			write (i , j + 1 , d);
		}
		write (i , 0 , -1);
	}
	fscanf (df , "%10s" , s);
	if (strcmp (s , "end") != 0)
	{
		printf ("\n程序初始化失败!");
		exit (1);
	}
	fclose (df);
	for (i = 0 ; i < 100 ; i++)
	{
		group[i].flag = 0;
		group[i].center = (float *) malloc ((vectorsize) * sizeof (float));
		group[i].groupsize = 0;
		group[i].variance = 0;
		group[i].D = 0;
	}
	for (i = 0 ; i < groupnum ; i++)
	{
		for (j = 0 ; j < vectorsize ; j++)
		{
			* (group[i].center + j) = data(i , j + 1);///////////////////////////////////////////
		}
		group[i].flag = 1;
	}
}
void  input ()
{
	char  choice;
	printf ("\n\n现用的参数取值:\n");
	printf ("K = %d\n,Nmin=%d\n,Ds=%f\n,Dm=%f\n,L=%d\n,I=%d\n",K,Nmin,Ds,Dm,L,I);
	showresult();
	printf ("是否需要进行修改?(Y/N)\n");
	scanf("%s" , & choice);
	choice = toupper (choice);
	if (choice == 'Y')
	{
		printf ("\n请输入预期的聚类中心数目:");
		scanf ("%d" , &K);
		printf ("\n请输入每一聚类域中最少样本数:");
		scanf ("%d" , &Nmin);
		printf ("\n请输入一个聚类域中样本距离分布的标准差:");
		scanf ("%f" , &Ds);
		printf("\n请输入两聚类中心之间的最小距离:");
		scanf ("%f" , &Dm);
		printf ("\n请输入一次迭代运算中可以合并的聚类中心的最多数目:");
		scanf ("%d" , &L);
		printf ("\n请输入最大迭代次数:");
		scanf ("%d" , &I);
	}
}
void  allocate ()
{
	int  i , j , k , num , index;
	float  D , D1 , sum;
	for (i = 0 ; i < 100 ; i++)//为各聚类中心值清零
	{
		group[i].D = 0;
		group[i].groupsize = 0;
		group[i].variance = 0;
	}
	for (i=0 ; i < vectornum ; i++)//按距离分配到各聚类域
	{
		D = distance (group[0].center , vector (i));
		k = 0;
		for (j = 1 ; j < groupnum ; j++)
		{
			D1 = distance (group[j].center , vector (i));
			if (D > D1)
			{
				k = j;
				D = D1;
			}
		}
		write (i , 0 , (float) k);		
		group[k].groupsize++;
	}
	num = groupnum;
	for (i = 0 ; i < num ; i++)//当聚类中样本个数小于规定值时撤销聚类
	{
		if (group[i].groupsize < Nmin)
		{
			group[i].flag = 0;
			group[i].groupsize = 0;
			for (j = 0 ; j < vectornum ; j++)
			{
				if (data (j , 0) == i)
				{
					write (j , 0 , -1.0);
				}
			}
			groupnum--;
		}
	}	
	for (i = 0 ; i < 100 ; i++)//为各聚类中心值清零
	{
		for (j = 0 ; j < vectorsize ; j++)
			* (group[i].center + j) = 0;
	}
	for (i = 0 ; i < vectornum ; i++)//计算新的聚类中心
	{
		index = (int) data (i , 0);
		if (index != -1)
		{
			sum = (float) group[index].groupsize;
			for (j = 0 ; j < vectorsize ; j++)
			{
				* (group[index].center + j) = * (group[index].center + j) + data(i , j + 1) / sum;
			}
		}
	}
	for (i = 0 ; i < vectornum ; i++)//计算各样点到聚类中心距离
	{
		index = (int) data (i , 0);
		if (index != -1)
		{
			sum = (float) group[index].groupsize;
			D = distance (group[index].center , vector (i));
			group[index].D = group[index].D + D / sum;
		}
	}
	Dst = 0;
	for (i = 0 ; i < maxindex ; i++)
	{
		if (group[i].flag != 0)
			Dst = Dst + group[i].D;
	}	
	Dst = Dst / groupnum;
}
void  diverge ()
{
	float  newvar , oldvar , center;
	int  i , j , k , l , flag;
	flag = 0;
	for (i = 0 ; i < maxindex ; i++)
	{
		if (group[i].flag != 0)
		{
			oldvar = 0;//标准差
			for (j = 0 , l = 0 ; j < vectorsize ; j++)
			{//计算同一聚类域中各分量对应的标准差中的最大值		
				newvar = 0;
				center = * (group[i].center + j);
				for (k = 0 ; k < vectornum ; k++)
				{
					if (data (k , 0) == i)
						newvar = newvar +(center - data(k , j+1))*(center - data(k , j+1));
				}
				if (newvar > oldvar)
				{
					oldvar = newvar;
					l = j;
				}
			}
			group[i].variance = (float) sqrt( oldvar / group[i].groupsize);
			if (group[i].variance > Ds)
			{
				if ((groupnum <= K/2) | ((group[i].D > Dst) & (group[i].groupsize > 2 * (Nmin + 1))))
				{
					split (i , l);
					flag = 1;	
				}
			}
		}
	}
	if (flag == 0)
		converge ();
}
void  split (int i , int j)
{
	int  k , l;
	k = maxindex;
	group[k].flag = 1;
	for (l = 0 ; l < vectorsize ; l++)
	{
		* (group[k].center + l) = (* (group[i].center + l));
	}
	* (group[k].center + j) = (* (group[k].center + j) + group[i].variance);
	* (group[i].center + j) = (* (group[i].center + j) - group[i].variance);			
	maxindex++;
	groupnum++;
}
void  converge ()
{	
	int  i , j , k , h , l;
	float  D , c1 , c2 , n1 , n2;
	ccdhead = (struct CCD *) malloc (sizeof (ccd) * L);
	for (i = 0 , k = 0 ; i < maxindex - 1 ; i++)
	{
		if (group[i].flag != 0)
		{
			for (j = i + 1 ; j < maxindex ; j++)
			{
				if (group[j].flag != 0)
				{
					D = distance (group[i].center , group[j].center);
					if (D < Dm)
					{
						if (k < L)
						{
							(ccdhead + k)->dst = D;
							(ccdhead + k)->g1 = i;
							(ccdhead + k)->g2 = j;
							k++;
						}
						else
						{
							insert (i,j,D);							
						}
						break;
					}
				}
			}
		}
	}		
	for (h = 0 ; h < k ;h++)
	{
		i = (ccdhead + h)->g1;
		j = (ccdhead + h)->g2;
		n1 = (float) group[i].groupsize;
		n2 = (float) group[j].groupsize;
		for (l = 0 ; l < vectorsize ; l++)
		{
			c1 = (* (group[i].center + l));
			c2 = (* (group[j].center + l));
			* (group[i].center + l) = (n1 * c1 + n2 * c2) / (n1 + n2);
		}
		group[i].groupsize = (int) (n1 + n2);
		for (l = 0 ; l < vectornum ; l++)
			if (data(l , 0) == j)
				write (l , 0 , (float) i);
		group[j].flag = 0;
		group[j].groupsize = 0;
		groupnum--;
	}
}
void  insert (int i , int j , float D)
{
	int  h , l;
	for (h = 0 ; h < L ; h++)
	{
		if (D < (ccdhead + h)->dst)
		{
			for (l = L - 1 ; l > h ; l--)
			{
				(ccdhead + l)->dst = (ccdhead + l - 1)->dst;
				(ccdhead + l)->g1 = (ccdhead + l - 1)->g1;
				(ccdhead + l)->g2 = (ccdhead + l - 1)->g2;
			}
			(ccdhead + h)->dst = D;
			(ccdhead + h)->g1 = i;
			(ccdhead + h)->g2 = j;
		}
	}
}

void  renum ()
{
	int  i , j , k;
	for (i = 0 ; i < maxindex - 1 ; i++)
	{
		if (group[i].flag == 0)
		{
			for (j = maxindex ; j > i ; j--)
			{
				if (group[j].flag == 1)
				{
					group[i].flag = 1;
					group[j].flag = 0;					
					for (k = 0 ; k < vectorsize ; k++)
					{
						* (group[i].center + k) = (* (group[j].center + k));
						* (group[j].center + k) = 0;
					}
				}
			}
		}
	}
	maxindex = groupnum;
}

void  showresult ()
{
	int  i , j , k , l;
	for (j = 1 , i = 0 ; i < maxindex ; i++)
	{
		if (group[i].flag != 0)
		{
			printf ("第%3d组聚类中心坐标为:" , j ++);
			for (k = 0 ; k < vectorsize ; k++)
				printf (" %10f " , *(group[i].center + k));
			printf (" \n聚类包含的样本点的坐标为:\n ");
			for (k = 0 ; k < vectornum ; k++)
			{
				if (data(k , 0) == i)
				{
					for (l = 0 ; l < vectorsize ; l++)
					{
						printf (" %10f " , data(k , l + 1));
					}
					printf (" \n ");
				}
			}
		}
	}
}
float  data (int i , int j)
{
	return  * (datafield + i * (vectorsize + 1) + j);
}
void  write (int i , int j , float data)
{
	* (datafield + i * (vectorsize + 1) + j) = data;
}
float  * vector (int i)
{ 
	return  datafield + i * (vectorsize + 1) + 1;
}
float  distance (float  * x , float  * y)
{
	int  i;
	float  z;
	for (i = 0 , z = 0 ; i < vectorsize ; i++)
		z = z + ((* (x + i)) - (* (y + i))) * ((* (x + i))-(* (y + i)));
	return  (float) sqrt(z);
}

运行

trust100@ubuntu:~/test/clanguage$ ./a.out 


现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   0.000000    0.000000  
聚类包含的样本点的坐标为:
 是否需要进行修改?(Y/N)
N


现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.378910    2.750000  
聚类包含的样本点的坐标为:
    0.000000    0.000000  
    1.000000    1.000000  
    2.000000    2.000000  
    4.000000    3.000000  
    5.000000    3.000000  
    4.000000    4.000000  
    5.000000    4.000000  
    6.000000    5.000000  
 第  2组聚类中心坐标为:   5.371090    2.750000  
聚类包含的样本点的坐标为:
 是否需要进行修改?(Y/N)
N


现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.000000    1.000000  
聚类包含的样本点的坐标为:
    0.000000    0.000000  
    1.000000    1.000000  
    2.000000    2.000000  
 第  2组聚类中心坐标为:   4.800000    3.800000  
聚类包含的样本点的坐标为:
    4.000000    3.000000  
    5.000000    3.000000  
    4.000000    4.000000  
    5.000000    4.000000  
    6.000000    5.000000  
 是否需要进行修改?(Y/N)
N


现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.000000    1.000000  
聚类包含的样本点的坐标为:
    0.000000    0.000000  
    1.000000    1.000000  
    2.000000    2.000000  
 第  2组聚类中心坐标为:   4.800000    3.800000  
聚类包含的样本点的坐标为:
    4.000000    3.000000  
    5.000000    3.000000  
    4.000000    4.000000  
    5.000000    4.000000  
    6.000000    5.000000  
 是否需要进行修改?(Y/N)
N


现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.000000    1.000000  
聚类包含的样本点的坐标为:
    0.000000    0.000000  
    1.000000    1.000000  
    2.000000    2.000000  
 第  2组聚类中心坐标为:   4.800000    3.800000  
聚类包含的样本点的坐标为:
    4.000000    3.000000  
    5.000000    3.000000  
    4.000000    4.000000  
    5.000000    4.000000  
    6.000000    5.000000  
 是否需要进行修改?(Y/N)
N
第  1组聚类中心坐标为:   1.000000    1.000000  
聚类包含的样本点的坐标为:
    0.000000    0.000000  
    1.000000    1.000000  
    2.000000    2.000000  
 第  2组聚类中心坐标为:   4.800000    3.800000  
聚类包含的样本点的坐标为:
    4.000000    3.000000  
    5.000000    3.000000  
    4.000000    4.000000  
    5.000000    4.000000  
    6.000000    5.000000  


实例98 快速傅立叶变换

fft.c

#include  <stdio.h>

#include  <stdlib.h>

#include  <math.h>

#define  PI  3.14159265358979323846


struct  COMPLEX

{

	float  re;

	float  im;

} cplx , * Hfield , * S , * R , * w;


int  n , m;

int  ln , lm;


void  initiate ();

void  dfft ();

void  rdfft ();

void  showresult ();



void  fft (int l , int k);

int  reverse (int t , int k);

void  W (int l);

int  loop (int l);

void  conjugate ();



void  add (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);

void  sub (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);

void  mul (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);

struct  COMPLEX  * Hread(int i , int j);

void  Hwrite (int i , int j , struct  COMPLEX x);



void  main ()

{

	initiate ();
	
	printf("\n原始数据:\n");
	
	showresult();
	
	getchar ();
	
	dfft ();
	
	printf("\n快速复利叶变换后的结果:\n");
	
	showresult ();
	
	getchar ();
	
	rdfft ();
	
	printf("\n快速复利叶逆变换后的结果:\n");
	
	showresult ();
	
	getchar ();
	
	free (Hfield);
}



void  initiate ()

{//程序初始化操作,包括分配内存、读入要处理的数据、进行显示等

	
	FILE  * df;
    
	df = fopen ("data.txt" , "r");
	
	fscanf (df , "%5d" , &n);
	
	fscanf (df , "%5d" , &m);
	
	if ((ln = loop (n)) == -1)
	
	{
	
		printf (" 列数不是2的整数次幂 ");
		
		exit (1);
	}

	
	if ((lm = loop (m)) == -1)
	
	{
	
		printf (" 行数不是2的整数次幂 ");
		
		exit (1);
	}

	
	Hfield = (struct  COMPLEX *) malloc (n * m * sizeof (cplx));
	
	if (fread (Hfield , sizeof (cplx) , m * n , df) != (unsigned) (m * n))
	
	{
	
		if (feof (df)) printf (" Premature end of file ");
		
		else printf (" File read error ");
	}

	
	fclose (df);

}



void  dfft ()

{//进行二维快速复利叶变换

	int  i , j;	
	
	int  l , k;
    

	l = n;
	
	k = ln;
	
	w = (struct  COMPLEX *) calloc (l , sizeof (cplx));
	
	R = (struct  COMPLEX *) calloc (l , sizeof (cplx));
	
	S = (struct  COMPLEX *) calloc (l , sizeof(cplx));
	
	W (l);
	
	for ( i = 0 ; i < m ; i++ )
	
	{//按行进行快速复利叶变换
	
		for (j = 0 ; j < n ; j++)
		
		{			
		
			S[j].re = Hread (i , j)->re;
			
			S[j].im = Hread (i , j)->im;

		}
	
		fft(l , k);
		
		for (j = 0 ; j < n ; j++)
		
			Hwrite (i , j , R[j]);
	
	}
	
	free (R);
	
	free (S);
	
	free (w);
	

	
	l = m;
	
	k = lm;
	
	w = (struct  COMPLEX *) calloc (l , sizeof (cplx));
	
	R = (struct  COMPLEX *) calloc (l , sizeof (cplx));
	
	S = (struct  COMPLEX *) calloc (l , sizeof (cplx));
	
	W (l);
	
	for (i = 0 ; i < n ; i++)
	
	{//按列进行快速复利叶变换
	
		for(j = 0 ; j < m ; j++)
		
		{
		
			S[j].re = Hread(j , i)->re;
			
			S[j].im = Hread(j , i)->im;

		}

		fft(l , k);
		
		for (j = 0 ; j < m ; j++)
		
			Hwrite (j , i , R[j]);
	}
	
	free (R);
	
	free (S);
	
	free (w);

}


void  rdfft ()

{

	conjugate ();
	
	dfft ();
	
	conjugate ();

}



void  showresult ()

{

	int  i , j;
	
	for (i = 0 ; i < m ; i++)
	
	{
	
		printf ( " \n第%d行\n " , i);
		
		for (j = 0 ; j < n ; j++)
		
		{
		
			if (j % 4 == 0) printf (" \n ");
			
			printf(" (%5.2f,%5.2fi) " , Hread (i , j)->re , Hread (i , j)->im);

		}

	}

}



void  fft (int l , int k)

{

	int  i , j , s , nv , t;
	
	float  c;
	
	struct  COMPLEX  mp , r;
	
	nv = l;
	
	c = (float) l;
	
	c = pow (c , 0.5);
	
	for (i = 0 ; i < k ; i++)
	
	{
	
		for (t = 0 ; t < l ; t += nv)
		
		{
		
			for (j = 0 ; j < nv / 2 ; j++)
			
			{
			
				s = (t + j) >> (k - i -1);
				
				s = reverse(s , k);
				
				r.re = S[t + j].re;
				
				r.im = S[t + j].im;
				
				mul (&w[s] , &S[t + j + nv / 2] , &mp);/////////讲解传递结构指针和结构本身的区别
				
				add (&r , &mp , &S[t + j]);
				
				sub (&r , &mp , &S[t + j + nv / 2]);				
			}

		}
		
		nv = nv >> 1;		
	}


	
	for (i = 0 ; i < l ; i++)
	
	{
	
		j = reverse(i , k);
		
		R[j].re = S[i].re / c;
		
		R[j].im = S[i].im / c;
	
	}

}



int  reverse (int t , int k)

{

	int  i , x , y;
	
	y = 0;
	
	for (i = 0 ; i < k ; i++)
	
	{
	
		x = t & 1;
		
		t = t >> 1;
		
		y = (y << 1) + x;		

	}

	return y;
}



void  W (int l)

{

	int i;
	
	float c , a;
	
	c = (float) l;
	
	c = 2 * PI / c;
	
	for (i = 0 ; i < l ; i++)
	
	{		
	
		a = (float) i;
		
		w[i].re = (float) cos(a * c);
	    
		w[i].im = -(float) sin(a * c);

	}

}



int  loop (int l)

{//检验输入数据是否为2的整数次幂,如果是返回用2进制表示时的位数

	int  i , m;
	
	if (l != 0)
	
	{
	
		for (i = 1 ; i < 32 ; i++)
		
		{
		
			m = l >> i;
			
			if (m == 0)
			
				break;

		}
		
		if (l == (1 << (i - 1)))
		
			return i - 1;

	}
	
	return -1;

}



void  conjugate ()

{//求复数矩阵的共轭矩阵

	int  i , j;

	for (i = 0 ; i < m ; i++)
	
	{
		for (j = 0 ; j < n ; j++)
	
		{
		
			Hread (i , j)->im *= -1;

		}

	}

}



struct  COMPLEX  * Hread (int i , int j)

{//按读矩阵方式返回Hfield中指定位置的指针

	return (Hfield + i * n + j);

}



void  Hwrite (int i , int j , struct  COMPLEX x)
{//按写矩阵方式将复数结构x写到指定的Hfield位置上

	(Hfield + i * n + j)->re = x.re;
	
	(Hfield + i * n + j)->im = x.im;

}



void  add (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z)

{//定义复数加法

	z->re = x->re + y->re;

	z->im = x->im + y->im;	

}



void  sub (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z)

{//定义复数减法

	z->re = x->re - y->re;

	z->im = x->im - y->im;

}


void  mul (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z)

{//定义复数乘法

    z->re = (x->re) * (y->re) - (x->im) * (y->im);
	
	z->im = (x->im) * (y->re) + (x->re) * (y->im);

}

data.txt

    8    4              €?       @      @@      €@      燖      繞      郂  €?      €?  €?  €?   @  €?  @@  €?  €@  €?  燖  €?  繞  €?  郂   @       @  €?   @   @   @  @@   @  €@   @  燖   @  繞   @  郂  @@      @@  €?  @@   @  @@  @@  @@  €@  @@  燖  @@  繞  @@  郂

运行

trust100@ubuntu:~/test/clanguage$ ./a.out 

原始数据:
 
第0行
  
  ( 0.00, 0.00i)  ( 0.00, 1.00i)  ( 0.00, 2.00i)  ( 0.00, 3.00i)  
  ( 0.00, 4.00i)  ( 0.00, 5.00i)  ( 0.00, 6.00i)  ( 0.00, 7.00i)  
第1行
  
  ( 1.00, 0.00i)  ( 1.00, 1.00i)  ( 1.00, 2.00i)  ( 1.00, 3.00i)  
  ( 1.00, 4.00i)  ( 1.00, 5.00i)  ( 1.00, 6.00i)  ( 1.00, 7.00i)  
第2行
  
  ( 2.00, 0.00i)  ( 2.00, 1.00i)  ( 2.00, 2.00i)  ( 2.00, 3.00i)  
  ( 2.00, 4.00i)  ( 2.00, 5.00i)  ( 2.00, 6.00i)  ( 2.00, 7.00i)  
第3行
  
  ( 3.00, 0.00i)  ( 3.00, 1.00i)  ( 3.00, 2.00i)  ( 3.00, 3.00i)  
  ( 3.00, 4.00i)  ( 3.00, 5.00i)  ( 3.00, 6.00i)  ( 3.00, 7.00i) 

快速复利叶变换后的结果:
 
第0行
  
  ( 8.49,19.80i)  (-6.83,-2.83i)  (-2.83,-2.83i)  (-1.17,-2.83i)  
  ( 0.00,-2.83i)  ( 1.17,-2.83i)  ( 2.83,-2.83i)  ( 6.83,-2.83i)  
第1行
  
  (-2.83, 2.83i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  
  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  
第2行
  
  (-2.83, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  
  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  
第3行
  
  (-2.83,-2.83i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  
  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i) 

快速复利叶逆变换后的结果:
 
第0行
  
  ( 0.00, 0.00i)  ( 0.00, 1.00i)  ( 0.00, 2.00i)  (-0.00, 3.00i)  
  ( 0.00, 4.00i)  (-0.00, 5.00i)  ( 0.00, 6.00i)  ( 0.00, 7.00i)  
第1行
  
  ( 1.00, 0.00i)  ( 1.00, 1.00i)  ( 1.00, 2.00i)  ( 1.00, 3.00i)  
  ( 1.00, 4.00i)  ( 1.00, 5.00i)  ( 1.00, 6.00i)  ( 1.00, 7.00i)  
第2行
  
  ( 2.00, 0.00i)  ( 2.00, 1.00i)  ( 2.00, 2.00i)  ( 2.00, 3.00i)  
  ( 2.00, 4.00i)  ( 2.00, 5.00i)  ( 2.00, 6.00i)  ( 2.00, 7.00i)  
第3行
  
  ( 3.00, 0.00i)  ( 3.00, 1.00i)  ( 3.00, 2.00i)  ( 3.00, 3.00i)  
  ( 3.00, 4.00i)  ( 3.00, 5.00i)  ( 3.00, 6.00i)  ( 3.00, 7.00i) 


实例99 求解野人与传教士问题

AI.C

#include <stdio.h>
#include <stdlib.h>
#define maxloop 100    //最大层数,对于不同的扩展方法自动调整取值
#define pristnum 3
#define slavenum 3
struct SPQ
{
	int sr,pr;             //船运行一个来回后河右岸的野人、传教士的人数 
	int sl,pl;             //船运行一个来回后河左岸的野人、传教士的人数 
	int ssr,spr;           //回来(由左向右时)船上的人数
	int sst,spt;           //去时(由右向左时)船上的人数
	int loop;               //本结点所在的层数                 
	struct SPQ *upnode ,*nextnode;//本结点的父结点和同层的下一个结点的地址
}spq;  
int loopnum;//记录总的扩展次数
int openednum;//记录已扩展节点个数
int unopenednum;//记录待扩展节点个数
int resultnum;
struct SPQ *opened;
struct SPQ *oend;
struct SPQ *unopened;          
struct SPQ *uend;
struct SPQ *result;
void initiate();
void releasemem();
void showresult();
void addtoopened(struct SPQ *ntx);
int search();
void goon();
int stretch(struct SPQ* ntx);
void recorder();
void main()
{
	int flag;       //标记扩展是否成功	
	for( ; ; )
	{
		initiate();
		flag = search ();
		if(flag == 1)
		{
			recorder();
			releasemem();
			showresult();
			goon();
		}
		else
		{
			printf("无法找到符合条件的解");
			releasemem();
			goon();
		}
	}
}
void initiate()
{
	int x;
	char choice;
	uend = unopened = (struct SPQ*)malloc(sizeof(spq));
	if(uend==NULL)
	{
		printf("\n内存不够!\n");
		exit(0);
	}
	unopenednum=1;
	openednum=0;
	unopened -> upnode = unopened;       //保存父结点的地址以成链表
	unopened -> nextnode = unopened;
	unopened -> sr = slavenum;
	unopened -> pr = pristnum;
	unopened -> sl = 0;
	unopened -> pl = 0;
	unopened -> sst = 0;
	unopened -> spt = 0;
	unopened -> ssr = 0;
	unopened -> spr = 0;
	unopened -> loop = 0;
	printf("题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。\n");
	printf("该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人\n");
	printf("就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?\n");
	printf("\n默认的n、m值皆为3\n");
    for(;;)
	{
		printf("\n是否修改?(Y/N)");
		scanf("%s",&choice);
		choice=toupper(choice);
		if(choice=='Y')
		{			
			printf("\n请输入传教士人数");
			for(;;)
			{
				scanf("%d",&x);
				if(x>0)	
				{
					unopened -> pr = x;
					break;
				}
				else printf("\n输入值应大于0!\n请重新输入");
			}
			printf("\n请输入野人人数");
			for(;;)
			{
				scanf("%d",&x);
				if(x>0)
				{
					unopened -> sr = x;
					break;
				}
				else printf("\n输入值应大于0!\n请重新输入");
			}	
			break;
		}
		if(choice=='N')break;
	}
	
}
int search()
{
	int flag;
	struct SPQ *ntx;               //提供将要扩展的结点的指针
	for( ; ; )
	{
		ntx = unopened;        //从待扩展链表中提取最前面的一个
		if(ntx->loop == maxloop)
			return 0; 
		addtoopened(ntx);       //将ntx加入已扩展链表,并将这个节点从待扩展链表中去掉
		flag = stretch(ntx);    //对ntx进行扩展,返回-1,0,1
		if(flag == 1)
			return 1; 		
	}
}
int stretch(struct SPQ *ntx)
{
	int fsr , fpr ; //在右岸上的人数
	int fsl , fpl ; //在左岸上的人数
	int	sst , spt ; //出发时在船上的人数
	int ssr , spr ; //返回时船上的人数
	struct SPQ *newnode;
	for (sst = 0 ; sst <=  2 ; sst++) //讨论不同的可能性并判断是否符合条件
	{
		fsr = ntx -> sr;
		fpr = ntx -> pr;
		fsl = ntx -> sl;
		fpl = ntx -> pl;
		if ((sst <=  fsr) && (( 2 - sst) <=  fpr))//满足人数限制
		{
			spt = 2 - sst;
			fsr = fsr - sst;
			fpr = fpr - spt;
			if((fpr ==  0) && (fsr ==  0))//搜索成功
			{ 
				newnode = (struct SPQ*) malloc (sizeof(spq));
				if(newnode==NULL)
				{
					printf("\n内存不够!\n");
					exit(0);
				}
				newnode -> upnode = ntx;       //保存父结点的地址以成链表
				newnode -> nextnode = NULL;
				newnode -> sr = 0;
				newnode -> pr = 0;
				newnode -> sl = opened -> sr;
				newnode -> pl = opened -> pr;
				newnode -> sst = sst;
				newnode -> spt = spt;
				newnode -> ssr = 0;
				newnode -> spr = 0;
				newnode -> loop = ntx -> loop + 1;
				oend -> nextnode = newnode;
				oend = newnode;
				openednum++;
				return 1;
			}   
			else if ((fpr - fsr) * fpr >= 0) //判断是否满足传教士人数必须大于或等于野人人数
			{
				fsl = fsl + sst;
				fpl = fpl + spt;
				for (ssr = 0 ; ssr <= 1 ; ssr++)                  //返回
				{
					int ffsl , ffpl;
					if ((ssr <= fsl) && ((1 - ssr) <= fpl))
					{
						spr = 1 - ssr;
						ffsl = fsl - ssr;
						ffpl = fpl - spr;
						if ((ffpl - ffsl) * ffpl >= 0)
						{	//若符合条件则分配内存并付值	
							int  ffsr , ffpr;
							ffsr = fsr + ssr;
							ffpr = fpr + spr;							                        
							newnode = (struct SPQ*) malloc (sizeof(spq));
							if(newnode==NULL)
							{
								printf("\n内存不够!\n");
								exit(0);
							}
							newnode -> upnode = ntx;       //保存父结点的地址以成链表
							newnode -> sr = ffsr;
							newnode -> pr = ffpr;
							newnode -> sl = ffsl;
							newnode -> pl = ffpl;
							newnode -> sst = sst;
							newnode -> spt = spt;
							newnode -> ssr = ssr;
							newnode -> spr = spr;
							newnode -> loop = ntx -> loop + 1;
							uend -> nextnode = newnode;
							uend = newnode;
							unopenednum++;								
							
						}
					}
				}
			}
		}
	} 
	return 0;
}
void addtoopened(struct SPQ *ntx)
{
	unopened = unopened -> nextnode;
	unopenednum--;
	if (openednum == 0 )
		oend = opened = ntx;
	oend -> nextnode = ntx;
	oend = ntx;
	openednum++;
}
void recorder()
{
	int i , loop;
	struct SPQ *newnode;
	struct SPQ *ntx;
	loop = oend -> loop;
	ntx = oend;
	resultnum = 0;
	for( i = 0 ; i <= loop ; i++ )
	{
		newnode = (struct SPQ*) malloc (sizeof(spq));
		if(newnode==NULL)
		{
			printf("\n内存不够!\n");
			exit(0);
		}
		newnode -> sr = ntx -> sr;
		newnode -> pr = ntx -> pr;
		newnode -> sl = ntx -> sl;
		newnode -> pl = ntx -> pl;
		newnode -> sst = ntx -> sst;
		newnode -> spt = ntx -> spt;
		newnode -> ssr = ntx -> ssr;
		newnode -> spr = ntx -> spr;
		newnode -> nextnode = NULL;
		ntx = ntx -> upnode;				
		if(i == 0)
			result = newnode;
		newnode -> nextnode = result;
		result = newnode;
		resultnum++;
	}
}
void releasemem()
{
	int i;
	struct SPQ* nodefree;
	for ( i = 1 ; i < openednum ; i++ )
	{
		nodefree = opened;
		opened = opened -> nextnode;
		free(nodefree);
	}
	for ( i = 0 ; i < unopenednum ; i++ )
	{
		nodefree = unopened;
		unopened = unopened -> nextnode;
		free(nodefree);
	}
}
void showresult()
{
	int i;
    int fsr , fpr ; //在右岸上的人数
	int fsl , fpl ; //在左岸上的人数
	struct SPQ* nodefree;
	printf("%d个传教士",result -> pr);
	printf("%d个野人",result -> sr);
    printf("%d个传教士",result -> pl);
    printf("%d个野人",result -> sl);
	for ( i = 1 ; i < resultnum ; i++ )
	{
		nodefree = result;
		result = result -> nextnode;
		free(nodefree);
		printf("\n\n\t左岸人数 船上人数及方向 右岸人数\n");
		printf("第%d轮\n",i);
		fpl = result -> pl - result -> spt + result -> spr;
		fpr = result -> pr - result -> spr;
		fsl = result -> sl - result -> sst + result -> ssr;
        fsr = result -> sr - result -> ssr;
		printf("传教士%8d%8d\t<-\t%8d\n",fpl,result -> spt,fpr);
		printf("野  人%8d%8d\t<-\t%8d\n",fsl,result -> sst,fsr);
		printf("传教士%8d%8d\t->\t%8d\n",result -> pl,result -> spr,result -> pr - result -> spr);
		printf("野  人%8d%8d\t->\t%8d\n",result -> sl,result -> ssr,result -> sr - result -> ssr);
	}
	printf("\n全体传教士和野人全部到达对岸");
	free(result);
}
void goon()
{
	char choice;
	for(;;)
	{
		printf("是否继续?(Y/N)\n");
	    scanf ("%s" , &choice);
		choice=toupper(choice);
		if(choice=='Y')break;
		if(choice=='N')exit(0);
	}
}

运行

trust100@ubuntu:~/test/clanguage$ ./a.out 
题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。
该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人
就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?

默认的n、m值皆为3

是否修改?(Y/N)N
3个传教士3个野人0个传教士0个野人

	左岸人数 船上人数及方向 右岸人数
第1轮
传教士       0       1	<-	       2
野  人       0       1	<-	       2
传教士       0       1	->	       2
野  人       1       0	->	       2


	左岸人数 船上人数及方向 右岸人数
第2轮
传教士       0       1	<-	       2
野  人       1       1	<-	       1
传教士       0       1	->	       2
野  人       2       0	->	       1


	左岸人数 船上人数及方向 右岸人数
第3轮
传教士       0       2	<-	       1
野  人       2       0	<-	       1
传教士       2       0	->	       1
野  人       1       1	->	       1


	左岸人数 船上人数及方向 右岸人数
第4轮
传教士       2       1	<-	       0
野  人       1       1	<-	       1
传教士       2       1	->	       0
野  人       2       0	->	       1


	左岸人数 船上人数及方向 右岸人数
第5轮
传教士       2       1	<-	       0
野  人       2       1	<-	       0
传教士       3       0	->	       0
野  人       3       0	->	       0

全体传教士和野人全部到达对岸是否继续?(Y/N)
Y
题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。
该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人
就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?

默认的n、m值皆为3

是否修改?(Y/N)N
3个传教士3个野人0个传教士0个野人

	左岸人数 船上人数及方向 右岸人数
第1轮
传教士       0       1	<-	       2
野  人       0       1	<-	       2
传教士       0       1	->	       2
野  人       1       0	->	       2


	左岸人数 船上人数及方向 右岸人数
第2轮
传教士       0       1	<-	       2
野  人       1       1	<-	       1
传教士       0       1	->	       2
野  人       2       0	->	       1


	左岸人数 船上人数及方向 右岸人数
第3轮
传教士       0       2	<-	       1
野  人       2       0	<-	       1
传教士       2       0	->	       1
野  人       1       1	->	       1


	左岸人数 船上人数及方向 右岸人数
第4轮
传教士       2       1	<-	       0
野  人       1       1	<-	       1
传教士       2       1	->	       0
野  人       2       0	->	       1


	左岸人数 船上人数及方向 右岸人数
第5轮
传教士       2       1	<-	       0
野  人       2       1	<-	       0
传教士       3       0	->	       0
野  人       3       0	->	       0


实例100 简单专家系统

classify.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

struct SUBLINK

{

	int index;
	
	struct SUBLINK *next;

}sublink;

struct NODE

{

	char feature[20];
	
	int upnnum;
	
	struct SUBLINK *upnode;
	
	int fullfill;
	
	int type;
	
	int state;
	
	int sonnum;
	
	struct SUBLINK *sonnode;

}node;

#define MAXNUM 1000

struct NODE *nodelink[MAXNUM];

int nodenum;

void initiate();

void quarry();

void modify();

int extend(struct NODE *ntx);

int showfault() ;

void store();

void main()

{

	int flag;
	
	initiate();
	
	for(;;)
	
	{
	
		printf("\n\t请选择操作:\n\n\t1、查询;\n\n\t2、添加新知识;\n\n\t3、退出程序.\n\n\t");
		
		scanf("%d",&flag);
		
		switch(flag)
		
		{
		
		case 1:
		
			quarry();
			
			break;
		
		case 2:
		
			modify();
			
			break;
		
		case 3:
		
			store();
		
		default:
		
			printf("\n输入错误,请重新输入\n");
		
		}
	
	}

}



void initiate()//初始化

{

	int i , j;
	
	char s[10];
	
	FILE *kf;
	
	struct NODE *newnode;
	
	struct SUBLINK *newlink , *oldlink;
	
	if((kf = fopen("knowledgestore.txt" , "r")) == NULL)
	
	{
	
		printf("Cannot create/open file");
		
		exit(1);
	
	}
	
	fscanf(kf , "%5d" , &nodenum);
	
	for(i=0 ; i < nodenum ; i++)
	
	{
	
		newnode = (struct NODE*)malloc (sizeof(node));
		
		if(newnode == NULL)
		
		{
		
			printf("\n内存不够!\n");
			
			exit(0);
		
		}
		
		fscanf(kf , "%20s" , newnode->feature);
		
		fscanf(kf , "%5d" , &newnode->upnnum);
		
		for(j=0 ; j<newnode->upnnum ; j++)
		
		{
		
			newlink = (struct SUBLINK*) malloc (sizeof(sublink));
			
			if(newlink == NULL)
			
			{
			
				printf("\n内存不够!\n");
				
				exit(0);
			
			}
			
			fscanf(kf , "%5d" , &newlink->index);
			
			if(j == 0)
			
				newnode->upnode = oldlink = newlink;
			
			newlink->next = NULL;
			
			oldlink->next = newlink;
			
			oldlink = newlink;
		
		}
		
		newnode->fullfill = 0;
		
		newnode->state = 0;
		
		fscanf(kf , "%5d" , &newnode->type);
		
		fscanf(kf , "%5d" , &newnode->sonnum);
		
		for(j=0 ; j < newnode->sonnum ; j++)
		
		{
		
			newlink = (struct SUBLINK*)malloc(sizeof(sublink));
			
			if(newlink == NULL)
			
			{
			
				printf("\n内存不够!\n");
				
				exit(0);
			
			}
			
			fscanf(kf , "%5d" , &newlink->index);
			
			if(j == 0)
			
				newnode->sonnode = oldlink = newlink;
			
			newlink->next = NULL;
			
			oldlink->next = newlink;
			
			oldlink = newlink;
		
		}
		
		nodelink[i] = newnode;	
	
	}
	
	fscanf(kf , "%10s" , s);
	
	if(strcmp(s , "end") != 0)
	
	{
	
		printf("\n程序初始化失败!");
		
		exit(0);
	
	}	

}



void quarry()

{

	struct NODE *ntx;
	
	char feature[100];
	
	int i , flag;
	
	for(;;)
	
	{
	
		flag = 0;
		
		printf("\n请输入动物的特征:");
		
		scanf("%s" , feature);
		
		for(i = 0 ; i < nodenum ; i++)
		
		{
		
			ntx = nodelink[i];
			
			if(strstr(feature,ntx->feature) != NULL)
			
			{
			
				ntx->state = 1;
				
				flag = extend(ntx);				
			
			}
		
		}		
		
		if(flag >= 1)
		
		{
		
			for(i = 0 ; i < nodenum ; i++)
			
			{
			
				nodelink[i]->fullfill = 0;
				
				nodelink[i]->state = 0;				
			
			}
			
			break;
		
		}
		
		if(flag == 0)
		
			if(showfault() == 0)break;
	
	}

}

int extend(struct NODE *ntx)

{

	int i , index;
	
	int flag;
	
	struct NODE *nextone;
	
	struct SUBLINK *son;
	
	if(ntx->sonnum == 0)
	
	{
	
		printf("\n结果为%20s\n" , ntx->feature);
		
		return 1;
	
	}
	
	son = ntx->sonnode;
	
	flag = 0;
	
	for(i = 0 ; i < (ntx->sonnum) ; i++)
	
	{
	
		index = son->index;
		
		nextone = nodelink[index];
		
		if(nextone->type == 0)//或节点
		
		{
		
			if(nextone->state != 1)
			
			{
			
				nextone->state = 1;
				
				printf("\n表明具有%20s特征" , nextone->feature);
				
				flag += extend(nextone);
			
			}
		
		}
		
		else
		
		{
		
			nextone->fullfill++;
			
			if(nextone->fullfill == nextone->upnnum)
			
			{
			
				nextone->state = 1;
				
				printf("\n表明具有%20s特征" , nextone->feature);
				
				flag =+ extend(nextone);
			
			}
		
		}

		son = son->next;
	
	}
	
	return flag;

}



void modify()

{

	int i ;
	
	char choice , feature[100];
	
	struct NODE *ntx , *newnode;
	
	struct SUBLINK *endl , *newl;
	
	newnode = (struct NODE*)malloc(sizeof(node));
	
	if(newnode == NULL)
	
	{
	
		printf("\n内存不够!\n");
		
		exit(0);
	
	}
	
	newnode->sonnum = 0;
	
	newnode->upnnum = 0;
	
	newnode->fullfill = 0;
	
	printf("\n请输入新特征\n");
	
	scanf("%s",newnode->feature);
	
	printf("新特征类型:\n与节点(1),或节点(0)");
	
	scanf("%d" , &newnode->type);
	
	newnode->state = 0;
	
	newnode->fullfill = 0;
	
	for(;;)
	
	{
			
		printf("\n是否为叶节点?(Y/N)\n");
		
	    scanf("%s" , &choice);
		
		choice = toupper(choice);
		
		if(choice == 'N')
		
		{
		
			printf("\n请输入新特征描述的对象\n");
			
			scanf("%s" , feature);
			
			for(i = 0 ; i < nodenum ; i++)
			
			{
			
				ntx = nodelink[i];
				
				if(strstr(feature,ntx->feature) != NULL)
				
				{
				
					newl = (struct SUBLINK*) malloc (sizeof(sublink));
					
					if(newl == NULL)
					
					{
					
						printf("\n内存不够!\n");
						
						exit(0);
					
					}

					if(newnode->sonnum == 0)
					
						newnode->sonnode = endl = newl;
					
					newl->index = i;
					
					endl->next = newl;
					
					endl = newl;
					
					newl->next = NULL;
					
					newnode->sonnum++;
					
/////////////////////////////////将信息写入子节点
					
					newl = (struct SUBLINK*) malloc (sizeof(sublink));

					if(newl == NULL)
					
					{
					
						printf("\n内存不够!\n");
						
						exit(0);
					
					}

					if(ntx->upnnum == 0)
					
						ntx->upnode = endl = newl;
					
					newl->index = nodenum;
					
					newl->next = ntx->upnode;
					
					ntx->upnode = newl;
					
					ntx->upnnum++;
				
				}

			}
			
			break;
		
		}
		
		if(choice == 'Y')break;
	
	}
	
	for(;;)
	
	{
		
		printf("\n是否为顶点?(Y/N)\n");
		
		scanf("%s" , &choice);
		
		choice = toupper(choice);
		
		if(choice == 'N')
		
		{		
		
			printf("\n请输入对新对象的描述\n");
			
			scanf("%s" , feature);
			
			for(i = 0 ; i < nodenum ; i++)
			
			{
			
				ntx = nodelink[i];
				
				if(strstr(feature , ntx->feature)!=NULL)
				
				{			
				
					newl = (struct SUBLINK*) malloc (sizeof(sublink));
					
					if(newl == NULL)
					
					{
					
						printf("\n内存不够!\n");
						
						exit(0);
					
					}
					
					if(newnode->upnnum == 0)
					
						newnode->upnode = endl = newl;
					
					newl->index = i;
					
					endl->next = newl;
					
					endl = newl;
					
					newl->next = NULL;
					
					newnode->upnnum++;
		
///////////////////////////////将信息写入父节点
					
					newl = (struct SUBLINK*) malloc (sizeof(sublink));
					
					if(newl == NULL)
					
					{
					
						printf("\n内存不够!\n");
						
						exit(0);
					
					}
					
					if(ntx->sonnum == 0)
					
						ntx->sonnode = endl = newl;
					
					newl->index = nodenum;
					
					newl->next = ntx->sonnode;
					
					ntx->sonnode = newl;
					
					ntx->sonnum++;
				
				}

			}
		
			break;

		}

		
		if(choice == 'Y')break;
	
	}	
	
	nodelink[nodenum] = newnode;
	
	nodenum++;

}



void store()

{

	int i , j;	
	
	char s[10];
	
	FILE *kf;
	
	struct NODE *writenode;
	
	struct SUBLINK *newlink , *oldlink;
	
	if((kf = fopen("knowledgestore.txt" , "w")) == NULL)
	
	{
	
		printf("Cannot create/open file");
		
		exit(1);
	
	}

	fprintf(kf , "%5d" , nodenum);
	
	for(i = 0 ; i < nodenum ; i++)
	
	{
	
		writenode = nodelink[i];
		
		fprintf(kf , "%20s" , writenode->feature);
		
		fprintf(kf , "%5d" , writenode->upnnum);
		
		newlink = writenode->upnode;
		
		for(j = 0 ; j < writenode->upnnum ; j++)
		
		{
		
			fprintf(kf , "%5d" , newlink->index);
			
			oldlink = newlink;
			
			newlink = newlink->next;
			
			free(oldlink);
		
		}

		
		fprintf(kf , "%5d" , writenode->type);
		
		fprintf(kf , "%5d" , writenode->sonnum);
		
		newlink = writenode->sonnode;
		
		for(j = 0 ; j < writenode->sonnum ; j++)
		
		{
		
			fprintf(kf , "%5d" , newlink->index);
			
			oldlink = newlink;
			
			newlink = newlink->next;
			
			free(oldlink);
		
		}

		free(writenode);
	
	}

	strcpy(s , "end");
	
	fprintf(kf , "%10s" , s);
	
	fclose(kf);
	
	exit(0);

}



int showfault()

{

	char choice;
	
	for(;;)
	
	{
	
		printf("是否继续?(Y/N)\n");
		
		scanf("%s" , &choice);
		
		while(choice == '10');
		
		choice = toupper(choice);
		
		if(choice == 'Y')return 1;
		
		if(choice == 'N')exit(0);
	
	}	

}
发布了201 篇原创文章 · 获赞 46 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/rong11417/article/details/104755665