最初TWInClose3算法20170214

#include "function_c.h"
int AequalC(unsigned long *C, unsigned long *A);
void CtoD(unsigned long *D, unsigned long *C);
void CCNtoD(unsigned long *D, unsigned long *C, unsigned long *CN);
long long com_num = 0;
long long conceptNum = 0;
void InClose(unsigned long *B, unsigned long *A, unsigned long *AN, unsigned long start_ulong, int start_bit_j, int *start_ulongFlag, unsigned long **N, unsigned long ***N_stack);
clock_t start, finish;
void out_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD);
char choice='y',sort_choice;
int BisEmpty(unsigned long *D);
unsigned long concept_temp[2000000];
void MyTWconcepts(unsigned long*, long);
int file_out_num = 0;
int ANjtoCN(unsigned long *CN, unsigned long *AN, unsigned long *cols);
void out_easy_TWconcepts(unsigned long *setD);
void out_test_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD);
int i_temp = 0;

typedef struct {
	double start;
	double stop;
} stopWatch;

class CStopWatch {
private:
	stopWatch timer;
	double frequency;
	double LIToSecs(double & L);
public:
	CStopWatch();
	void startTimer();
	void stopTimer();
	double getElapsedTime();
};
int main(int argc, char ** argv)
{
	out_file = fopen("out_file.txt", "w");
	/* = 456654456464;
	printf("%d\t",sizeof(long long));
	printf("%d\t", sizeof(int));
	printf("com_num个数:%lld, ", com_num);
	printf("概念个数:%lld\n", conceptNum);*/
	
	system("color F0");
	read_file();
	printf("约简否?排序否(eg:y,y):");
	getchar();//读取上次输入余下的换行符????。。。
	scanf("%c,%c", &choice, &sort_choice);//少了取地址,数组才不用取地址。。。 且不可以scanf("%c\n", &choice);加回车。。。。
	create_context(); free(mybuf);//背景中32位每一位都有用,可是queue_Flag那块是为何可以用属性列的最后一位???????
	//现在可忽略背景的创建了,,,基本同自己的context,这儿只是单指针罢了。。。。//0-31context[row * anum_longSize+0], 32-63context[row * anum_longSize+1],,,...context[row * anum_longSize+anum_LongSize-1]//这种思想自己用过。。。。
	
	initialize_output();
	///WWWang排序背景。。。。。。。。。。。。
	/*if (sort_choice == 'y')
		sort_context();*/
	
	initialize_algorithm();	//用于给cols赋值 cols[0]..cols[onum_longSize-1]放属性1和所有对象的关系。。。cols[onum_longSize]..cols[2*onum_longSize-1]放属性2和所有对象的关系,并初始化输出即attributes[]
	unsigned long *A; unsigned long *AN; unsigned long *B; unsigned long *pA; int *start_ulongFlag;
	B = (unsigned long *)malloc(byte_anumLongSize + 2*byte_onumLongSize);  /* 分配一个概念占用的空间,包括内涵与外延 */
	A = B + anum_longSize;  /* 外延的起始位置 */
	AN = A + onum_longSize;
	memset(A, 0xFF, byte_onumLongSize);有问题。。。要再去掉对象为空的那几个1。。。。
	memset(AN, 0xFF, byte_onumLongSize);
	for (int i = objects % (ARCHBIT + 1); i <ARCHBIT + 1; i++)//重要,确保A AN C CN多余的那几位全为0
	{
		A[onum_longSize-1] -= (BIT << i);//重要
		AN[onum_longSize - 1] -= (BIT << i);//重要
	}
	memset(B, 0, byte_anumLongSize);//WWWang位全置0
	start_ulongFlag = (int *)malloc(sizeof(int) * (attributes + 1) * attributes);

	unsigned long **N; unsigned long ***N_stack;
	N = (unsigned long **)malloc(sizeof(unsigned long *) * attributes);
	/* 存储指向算法中的queue_Flag(即新生成且重复的内涵D)的地址。所用空间在本函数之外分配,只有一次调用所需空间,
	一个属性对应一个地址,共计n个单元。上层调用的地址信息保存在N_stack中,在递归返回时通过N_stack恢复 */
	memset(N, 0, sizeof(unsigned long *) * attributes);
	N_stack = (unsigned long ***)malloc(sizeof(unsigned long **) * (attributes + 1) * attributes);
	/* 堆栈,用于递归返回时恢复N。逻辑结构域大小同starts。
	共有n+...+1=n(n+1)/2组,每组2个单元;第一单元存储 当前属性对应的N单元的地址,第二单元存储其值 */
	start = clock();
	
	InClose(B, A,AN,0, ARCHBIT, start_ulongFlag, N, N_stack);

	finish = clock();


	FILE *out_result;
	out_result = fopen("wwwResults.txt", "a");
	if (sort_choice == 'y')
	{
		printf("排序后:");
		fprintf(out_result, "排序后:");
	}
	else
	{
		printf("不排序:");
		fprintf(out_result, "不排序:");
	}

	if (choice == 'y')
	{
		printf("约简:");
		fprintf(out_result, "约简:");
	}
	else
	{
		printf("全部:");
		fprintf(out_result, "全部:");
	}

	printf("%s:%d*%d, ", fname, objects, attributes);
	printf("时间:%lf秒, ", (double)(finish - start) / CLOCKS_PER_SEC);
	printf("com_num个数:%lld, ", com_num);
	printf("概念个数:%lld\n", conceptNum);

	fprintf(out_result, "TWInClose: %s:%d*%d, ", fname, objects, attributes);
	fprintf(out_result, "时间:%lf秒, ", (double)(finish - start) / CLOCKS_PER_SEC);
	fprintf(out_result, "com_num个数:%lld, ", com_num);
	fprintf(out_result, "概念个数:%lld\n", conceptNum);
	fclose(out_result);

	fclose(out_file);
	system("pause");
	return 0;
}

/*
请输入文件名:cdat_lung-cancer.dat
约简否?排序否(eg:y,y):y,y
supp:10
supp:100
supp:1000
supp:10000
supp:100000
supp:200000
supp:300000
supp:400000
supp:500000
supp:600000
supp:700000
supp:800000
supp:900000
supp:1000000
supp:1100000
!!!:概念格式:(({0,1,2,3},{0,1,2,3}),{})
排序后:约简:cdat_lung-cancer.dat:32*162, 时间:10.115000秒, com_num个数:3127560, 概念个数:1120807
请按任意键继续. . .

//不输出概念的话:
排序后:约简:cdat_lung-cancer.dat:32*162, 时间:1.284000秒, com_num个数:3127560, 概念个数:1120807
*/

void MyTWconcepts(unsigned long*concept, long num)
{
	for (int k = 0; k < num; k++)
	{
		int i, j, c;
		int first = 1;
		fprintf(out_file, "(({");
		for (c = j = 0; j < onum_longSize; j++)
		{
			int flag_wan = 0;
			for (i = 0; i <= ARCHBIT; i++)
			{
				if (concept[j + (onum_longSize * 2 + anum_longSize)*k] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
				{
					if (!first)//标志位,输出空格
					{
						fprintf(out_file, ",");
					}
					fprintf(out_file, "%d", object_numbers[c]);
					first = 0;
				}
				c++;//每处理一个对象c要加一
				if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
				{
					flag_wan = 1;
					break;
				}
			}
			if (flag_wan == 1)
				break;
		}
		fprintf(out_file, "},{");
		first = 1;
		for (c = j = 0; j < onum_longSize; j++)
		{
			int flag_wan = 0;
			for (i = 0; i <= ARCHBIT; i++)
			{
				if (concept[j + (onum_longSize * 2 + anum_longSize)*k +onum_longSize] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
				{
					if (!first)//标志位,输出空格
					{
						fprintf(out_file, ",");
					}
					fprintf(out_file, "%d", object_numbers[c]);
					first = 0;
				}
				c++;//每处理一个对象c要加一
				if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
				{
					flag_wan = 1;
					break;
				}
			}
			if (flag_wan == 1)
				break;
		}
		fprintf(out_file, "}),{");
		//int i, j, c;
		//int first = 1;
		//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);
		first = 1;
		for (c = j = 0; j < anum_longSize; j++)
		{
			int flag_wan = 0;
			for (i = ARCHBIT; i >= 0; i--)
			{
				//printf("BIT<<i:%x, ",BIT<<i);
				if (concept[j + (onum_longSize * 2 + anum_longSize)*k +onum_longSize*2] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
				{
					if (!first)//标志位,输出空格
					{
						fprintf(out_file, ",");
					}
					fprintf(out_file, "%d", attrib_numbers[c]);
					first = 0;
				}
				c++;//每处理一个属性c要加一
				if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
				{
					flag_wan = 1;
					break;
				}
			}
			if (flag_wan == 1)
				break;
		}
		fprintf(out_file, "})");
		fprintf(out_file, "\n");
	}
}
void InClose(unsigned long *B, unsigned long *A, unsigned long *AN, unsigned long start_ulong, int start_bit_j, int *start_ulongFlag, unsigned long **N, unsigned long ***N_stack)// start_ulong ,start_bit_j 二者组合在一起表示本次调用的起始属性,即算法中的y。 start_ulong是y所在单元(一个unsigned long),start_bit_j是y的位序号 
{
	int i, j_numAttri;	unsigned long *C,*CN, *D, *temp_D;	int *start_ulongFlagtemp = start_ulongFlag;
	j_numAttri = start_ulong * (ARCHBIT + 1) + (ARCHBIT - start_bit_j);//WWWang,赋初值OK了。。。j_numAttri为当前属性的序号(也表示前面已经处理了j_numAttri个属性)
	unsigned long *D_head;
	D = temp_D = D_head = (unsigned long *)malloc((byte_anumLongSize + byte_onumLongSize*2) * (attributes - j_numAttri));
	C = D + anum_longSize; //第一个概念的外延的起始位置。。。
	CN = C + onum_longSize;
	unsigned long ***N_stack_temp = N_stack;
	for (; start_ulong < anum_longSize; start_ulong++)//遍历所有属性。。。
	{
		com_num++;
		int flag_bianliwan = 0;
		for (; start_bit_j >= 0; start_bit_j--, j_numAttri++)//遍历每个longSize(32个对象)中的所有对象。。。
		{
			if (j_numAttri >= attributes)  //因为最后一个longSize空间中放的属性个数很可能不满,所以特殊处理下。。。。
			{
				flag_bianliwan = 1;
				break;
			}
			if (!(B[start_ulong] & (BIT << start_bit_j)))  /* 算法中的j属于B */
			{
				int flag_imply = 0;
				if (N[j_numAttri] != NULL)//若为空,则直接计算新概念进入一般测试
				{
					if (N[j_numAttri][start_ulong] & ~(B[start_ulong]) & Yj[start_bit_j])
					{	//若集合A的某些元素不在集合B中,则A一定不包含于B。判断Nj是否包含于B。Yj[start_bit_j]用于屏蔽start_bit_j及start_bit_j右边的bit
						flag_imply = 1;
					}
					if (flag_imply == 0)
					{
						for (i = 0; i < start_ulong; i++)
						{
							if (N[j_numAttri][i] & ~(B[i]))
							{
								flag_imply = 1;
								break;
							}
						}
					}
				}
				if (flag_imply == 0)
				{
					
					printf("j=%d\n", j_numAttri);
					int result1 = AjtoC(C, A, cols[j_numAttri]);
					if (result1 == 2)
						continue;
					//if (result1 != 2)//表示C不空,C大小>0.。。。。
					{
						int result2 = ANjtoCN(CN, AN, cols[j_numAttri]);
						if (result2 == 2)
							continue;
						//if (result2 != 2)//表示CN不空,CN大小>0.。。。。
						{
							if ((result1 == 1) && (result2 == 1))
							{
								B[start_ulong] |= (BIT << start_bit_j);//将属性j加入B中。。。。
							}
							if (AjtoC(C, A, cols[j_numAttri]) == 2)
							if ((result1 == 0) || (result2 == 0))//((result1 == 1) && (result2 == 1))不成立。。
							{
								//CtoD(D, C);//WWWang 为了求D。。。。。
								CCNtoD(D, C, CN);
								if (!((D[start_ulong] ^ B[start_ulong]) & Yj[start_bit_j]))//初步判断最接近j的那个longSize的B和D中属性的关系是否满足Bqueue_Flagj等于Dqueue_Flagj...,自己分步试了,没问题。。。
								{
									int flag_skiptoelse = 1;
									for (i = 0; i < start_ulong; i++)//为了测试剩余属性0,1...(start_ulong-1)*4中的属性是否有:Bqueue_Flagj=Dqueue_Flagj成立与否。。。WWWang*********
									{
										if (D[i] ^ B[i])//B和D不同,因为D[i]和B[i]中的属性都在Yj中,所以有Bqueue_Flagj不等于Dqueue_Flagj
										{
											flag_skiptoelse = 0;
											*N_stack_temp = &(N[j_numAttri]);
											N_stack_temp++;
											*N_stack_temp = (unsigned long **)N[j_numAttri];//强制类型转换
											N_stack_temp++;
											N[j_numAttri] = D;
											D[anum_longSize - 1] |= BIT;// //WWWang 初始化时anum_longSize多给了(1位到31位,就是为了这里queue_Flag用的最右边那个标志位。。。)
											break;
										}
									}
									if (flag_skiptoelse == 1)
									{
										//**************入队。。。。。。。。。
										//入队对应的start_ulong,start_bit值。。。。。
										//当然D通过标志位queueFlag,,,初始化全0即都入队,当正则检测失败时置为1,表示不入队。。。。
										*start_ulongFlagtemp = start_ulong;	start_ulongFlagtemp++;
										*start_ulongFlagtemp = start_bit_j;	start_ulongFlagtemp++;
									}
								}
								else//正则检测失败。。。。。。。。。
								{
									*N_stack_temp = &(N[j_numAttri]);
									N_stack_temp++;
									*N_stack_temp = (unsigned long **)N[j_numAttri];//强制类型转换
									N_stack_temp++;
									N[j_numAttri] = D;
									D[anum_longSize - 1] |= BIT;  //WWWang 初始化时anum_longSize多给了(1位到31位,就是为了这里queue_Flag用的最右边那个标志位。。。)
								}
								D = CN + onum_longSize;//D指向新概念的起始地址。。。。
								C = D + anum_longSize;//C在D地址上加anum_longSize,同初始化解释。。。WWWang
								CN = C + onum_longSize;
							}
						}
					}
				}
			}
			/j_numAttri++;//统计已遍历属性的个数,主要为了控制最后一个anum_longSize中的属性,因为它很可能不满,不等遍历32个就要退出。。。
		}
		if (flag_bianliwan == 1)//通过j_numAttri和attribe比对,判断属性遍历完否。。。
			break;
		else
			start_bit_j = ARCHBIT;//下一个anum_longSize中的起始位,设置为31。。。。。
	}

	if (choice=='y')
	{
		//out_easy_TWconcepts(B);
		out_TWconcepts(A, AN, B);
		conceptNum++;	
		if (conceptNum <= 100000)
		{
			if (conceptNum == 10 * countConcept)
			{
				printf("supp:%lld\n", conceptNum);
				countConcept *= 10;
			}
		}
		else
		{
			i_temp++;
			if (i_temp == 100000)
			{
				printf("supp:%lld\n", conceptNum);
				i_temp = 0;
			}
		}
	}
	if (choice == 'n')
	{
		//out_easy_TWconcepts(B);
		out_TWconcepts(A, AN, B);
		conceptNum++;	

		if (conceptNum <= 100000)
		{
			if (conceptNum == 10 * countConcept)
			{
				printf("supp:%lld\n", conceptNum);
				countConcept *= 10;
			}
		}
		else
		{
			i_temp++;
			if (i_temp == 100000)
			{
				printf("supp:%lld\n", conceptNum);
				i_temp = 0;
			}
		}
	}
	for (; temp_D != D; temp_D = CN + onum_longSize)//temp_D != D这个条件用于处理所有的计算出的概念
	{
		C = temp_D + anum_longSize;//队列中的第一个概念外延
		CN = C + onum_longSize;
		if (temp_D[anum_longSize - 1] & BIT) //WWWang 当前概念没有入队,所以不用遍历子概念。。。。是queue_Flag中的失败概念,即树中的方块节点,不递归 
			continue;
		//执行InClose的D=BUj  但是j没有入队啊。。。。当时的j如何保存,,额有了*(start_ulongFlag + 1)就是了。。。。
		//当时的D[Bchildren[0]]即D[*start_ulongFlag], D[Bchildren[1]]即D[*(start_ulongFlag+2)],D[Bchildren[j]]即D[*(start_ulongFlag+2*j)]当然 *start_ulongFlag,*(start_ulongFlag+2)等可能相等
		temp_D[*start_ulongFlag] = B[*start_ulongFlag] | (BIT << *(start_ulongFlag + 1));//刚开始两个D只有一个改为temp_D,两一个忘记改,一定程度影响com_num

		if (*(start_ulongFlag + 1) == 0)
			InClose(temp_D, C, CN, *start_ulongFlag + 1, ARCHBIT, start_ulongFlagtemp, N, N_stack_temp);//走下一anum_longSize,ARCHBIT为下一anum_longSize中的属性31,
		else  //还没到longSize的最后一位,start_ulong不变,start_bit_j-1即可 
			InClose(temp_D, C, CN, *start_ulongFlag, *(start_ulongFlag + 1) - 1, start_ulongFlagtemp, N, N_stack_temp);//看下一个属性即start_bit_j-1,即*(start_ulongFlag + 1) - 1
		start_ulongFlag += 2;//WWWang(指向下一个,为了和D0,D1,D2等的切换一直,切换到同一个概念。。。。
	}

	for (; N_stack != N_stack_temp; N_stack += 2)
	{
		**N_stack = (unsigned long *)*(N_stack + 1);  /* 把N恢复到刚进入本次调用时的状态,注意这里必须强制转换回来 */
	}

	free(D_head);
	return;
}
int BisEmpty(unsigned long *B)
{

	for (int k = 0; k < anum_longSize; k++)
	{
		if (B[k]>0)
			return 0;
	}
	return 1;
}
int AjtoC(unsigned long *C, unsigned long *A, unsigned long *cols)//cols初始值为cols[j_numAttri]
{
	int i, j, k;
	int flag = 1;
	int flagC_empty = 0;
	if (cols)//cols属性外延即为j',也即程序中的cols[j_numAttri]????但有问题啊,cols[0...onumLongsize-1]才是属性1和所有对象的关系。。
	{
		for (k = 0; k < onum_longSize; k++)//为了遍历cols[j_numAttri+0],cols[j_numAttri+1],..cols[j_numAttri+onum_longSize-1]
		{
			///printf("cols[%d]:%x\n:",k,cols[k]);
			C[k] = A[k] & (cols[k]);//A与j'的交集,计算新的外延
			if ((choice == 'y') && (C[k] == 0))
			{
				flagC_empty++;
			}
			if ((flag == 1) && (C[k]!=A[k]))//如果二者不相等。。。
			{
				flag = 0;
			}
		}
	}
	
	if (flag == 1)//A等于C
		return 1;
	else //A不等于C
	{
		if (flagC_empty == onum_longSize)//C为空。。。不进行正则判断
			return 2;
		else //C不空。。进行正则判断
			return 0;
	}
}
int ANjtoCN(unsigned long *CN, unsigned long *AN, unsigned long *cols)//cols初始值为cols[j_numAttri]
{
	int i, j, k;
	int flag = 1;
	int flagC_empty = 0;
	if (cols)//cols属性外延即为j',也即程序中的cols[j_numAttri]????但有问题啊,cols[0...onumLongsize-1]才是属性1和所有对象的关系。。
	{
		for (k = 0; k < onum_longSize; k++)//为了遍历cols[j_numAttri+0],cols[j_numAttri+1],..cols[j_numAttri+onum_longSize-1]
		{
			///printf("cols[%d]:%x\n:",k,cols[k]);
			CN[k] = AN[k] & (~cols[k]);//AN与jn'的交集,计算新的外延
			if ((choice == 'y') && (CN[k] == 0))
			{
				flagC_empty++;
			}
			if ((flag == 1) && (CN[k] != AN[k]))//如果二者不相等。。。
			{
				flag = 0;
			}
		}
	}

	if (flag == 1)//A等于C
		return 1;
	else //A不等于C
	{
		if (flagC_empty == onum_longSize)//C为空。。。不进行正则判断
			return 2;
		else //C不空。。进行正则判断*/
			return 0;
	}
}

void CCNtoD(unsigned long *D, unsigned long *C, unsigned long *CN)
{
	int i, j, k, l;
	memset(D, 0xFF, byte_anumLongSize);//WWWang位全置1
	if (D[anum_longSize - 1] % 2 == 1)//如果最后一位位1则初始为0,即默认入队的。。。。???  但考虑到作者没写,且程序几个数据的结果都没问题,暂时不加
		D[anum_longSize - 1]--;
	for (k = 0; k < onum_longSize; k++)
	{
		if (C[k])//如果外延不为空,求C'即D
		{
			for (l = 0; l <= ARCHBIT; l++)//该循环实现了外延中的所有对象属性相交
			{
				if (C[k] >> l)//如果移位后为0,则没有更多的对象处理,跳出for循环
				{
					if ((C[k] >> l) & BIT)//对外延中的对象l处理
					{
						for (i = 0, j = anum_longSize * (k * (ARCHBIT + 1) + l); i < anum_longSize; i++, j++)
						{
							D[i] = D[i] & (context[j]);
						}
					}
				}
				else
				{
					break;
				}
			}
		}

		if (CN[k])//如果外延不为空,求CN'即D
		{
			for (l = 0; l <= ARCHBIT; l++)//该循环实现了外延中的所有对象属性相交
			{
				if (CN[k] >> l)//如果移位后为0,则没有更多的对象处理,跳出for循环
				{
					if ((CN[k] >> l) & BIT)//对外延中的对象l处理
					{
						for (i = 0, j = anum_longSize * (k * (ARCHBIT + 1) + l); i < anum_longSize; i++, j++)
						{
							D[i] = D[i] & (~context[j]);
						}
					}
				}
				else
				{
					break;
				}
			}
		}

	}
}

void CtoD(unsigned long *D, unsigned long *C)//cols初始值为cols[j_numAttri]
{
	int i, j, k, l;
	memset(D, 0xFF, byte_anumLongSize);//WWWang位全置1
	if (D[anum_longSize - 1] % 2 == 1)//如果最后一位位1则初始为0  但考虑到作者没写,且程序几个数据的结果都没问题,暂时不加
		D[anum_longSize - 1]--;
	for (k = 0; k < onum_longSize; k++)
	{
		if (C[k])//如果外延不为空,求C'即D
		{
			for (l = 0; l <= ARCHBIT; l++)//该循环实现了外延中的所有对象属性相交
			{
				if (C[k] >> l)//如果移位后为0,则没有更多的对象处理,跳出for循环
				{
					if ((C[k] >> l) & BIT)//对外延中的对象l处理
					{
						for (i = 0, j = anum_longSize * (k * (ARCHBIT + 1) + l); i < anum_longSize; i++, j++)
						{
							D[i] = D[i] & (context[j]);
						}
					}
				}
				else
				{
					break;
				}
			}
		}
	}
}

function_c.h

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define BIT		((unsigned long) 1)  
#define zero_LONG	((unsigned long) 0)
#define INT_SIZE	(sizeof (int))
#define LONG_SIZE	(sizeof (unsigned long))
#define ARCHBIT		((LONG_SIZE * 8) - 1)  /* 最高位序号 */
#define byte_anumLongSize	(LONG_SIZE * anum_longSize)  // 属性占用的字节数,一个属性一bit,对的其实就是4*(attributes/32+1) 
#define byte_onumLongSize	(LONG_SIZE * onum_longSize)
#define bufBlock1024	1024
int attributes = 0;  //属性的总个数
int objects = 0;	 //对象的总个数
int anum_longSize = 0;  //存储属性所需要的LONG_SIZE个数
int onum_longSize = 0;  //存储对象所需要的LONG_SIZE个数
int table_ones = 0;//形式背景表格中1的个数
int intData[1000];
unsigned long *context;//用于存储形式背景的指针
/*宏定义一个函数用来存储形式背景中1对应的属性,存储在mybuf开始的地址空间中*/

FILE *in_file;
FILE *out_file;

int *mybuf = NULL;//一个一维数组,大小除了多存放行结束标志-1则该多少是多少,一点不多malloc.
int mybuf_index = 0;
int mybuf_size = bufBlock1024;
void create_context();
void read_file();
void allocate_mybufer(int **mybufer, int size);
int getNextInt(FILE *file, int *value);

void initialize_algorithm();
unsigned long **cols;//属性列,双指针。。。
unsigned long Yj[ARCHBIT + 1];  /* 第i个元素的右边i位全是0,从第i+1位向左全为1。用于屏蔽右边i位 。为了实现和集合Yj的相交*/

int AjtoC(unsigned long *C, unsigned long *A, unsigned long *cols);
int *attrib_numbers,*object_numbers;
long long countConcept = 1;
#define PushNewInterger(__value) \
  { \
	if (mybuf_index >= mybuf_size) { \
      mybuf_size += bufBlock1024; \
      allocate_mybufer (&mybuf, mybuf_size); \
								} \
	mybuf[mybuf_index] = (__value); \
	mybuf_index ++; \
  }

void print_concepts(unsigned long *setC, unsigned long *setD);
void print_A(unsigned long *setA);
void print_B(unsigned long *setB);
void out_concepts(unsigned long *setC, unsigned long *setD);
char fname[100];
void sort_context();
int min_support = 0;
int *supps;
int rows_compar(const void *a, const void *b);
int cols_compar(const void *a, const void *b);
void initialize_output();


void initialize_output()
{
	//初始化输出。。。。
	int q;
	attrib_numbers = (int *)malloc(sizeof(int) * attributes);
	for (q = 0; q < attributes; q++)
		attrib_numbers[q] = q;

	int p;
	object_numbers = (int *)malloc(sizeof(int) * objects);
	for (p = 0; p < objects; p++)
		object_numbers[p] = p;
}
void initialize_algorithm()
{
	//用于给cols赋值。。。。
	cols[0]..cols[onum_longSize-1]放属性1和所有对象的关系。。。cols[onum_longSize]..cols[2*onum_longSize-1]放属性2和所有对象的关系
	int i, j, k, x, y;
	unsigned long *temp_colmybuf, mask, *cols_mybuf;
	for (i = 0; i <= ARCHBIT; i++)//下面两个for循环对Yj[i]初始化
	{
		Yj[i] = zero_LONG;//zero_LONG是unsigned long型的0
		for (j = ARCHBIT; j > i; j--)
		{
			Yj[i] |= (BIT << j);  //通过for循环、或的作用。。。 第i个元素的右边i位全是0,从第i+1位向左全为1,因为Bit是unsigned long型1。。。。 
		}
	}
	//Yj[i]现在第i个元素的右边i位全是0,从第i+1位向左全为1。用于屏蔽右边i位 。为了实现和集合Yj的相交*/

	cols_mybuf = (unsigned long *)malloc(LONG_SIZE * onum_longSize * attributes);//单指针。。。。存储背景,这时换成。。。以列为单位
	memset(cols_mybuf, 0, LONG_SIZE * onum_longSize * attributes);//初始化为0
	cols = (unsigned long **)malloc(sizeof(unsigned long *) * attributes);//双指针。。。。 存储列地址
	temp_colmybuf = cols_mybuf;

	for (k = j = 0; j < anum_longSize; j++)//anum_longSize属性用的long的个数。。。
	{
		for (i = ARCHBIT; i >= 0; i--, k++)
		{
			
			if (k >= attributes)//如果所有属性处理完毕,则退出
				return;

			mask = (BIT << i);//mask=1左移i位。。。即1*2^i
			cols[k] = temp_colmybuf;
			for (x = 0, y = j; x < objects; x++, y += anum_longSize)
			{
				if (context[y] & mask)//判断x对象是否具有属性i????
				{
					temp_colmybuf[x / (ARCHBIT + 1)] |= BIT << (x % (ARCHBIT + 1));//对象x是否具有属性i....
				}
			}
			temp_colmybuf += onum_longSize;//cols[0]..cols[onum_longSize-1]放属性1和所有对象的关系。。。cols[onum_longSize]..cols[2*onum_longSize-1]放属性2和所有对象的关系
			//与context不同,cols[0][0]中的存放12345678,1放对象28-31,2放对象24-27,3放对象20-23,4放。。。7放4-7位,8放对象0-3 但是也是32位全用来存放有效的属性。。。 为何queue_Flag中要用属性列的最后一位作标志位判断重复失败与否。。。
			//printf("cols[%d][0]:%x\n", k, cols[k][0]);
			//printf("cols[%d][1]:%x\n", k, cols[k][1]);
		}
	}
}


void read_file()//读取形式背景文件
{
	
	printf("请输入文件名:");
	scanf("%s", fname);
	FILE *file = fopen(fname, "r");
	int last_value = -1, value = 0, last_attribute = -1, last_object = -1;

	allocate_mybufer(&mybuf, mybuf_size);//为mybuf重新申请更大的空间。。。

	while (getNextInt(file, &value))//依次获得文件中的属性值 每次仅读取一个数字。。。
	{
		if ((value < 0) && (last_value < 0))//某一行为空,不作处理,不影响。。。
			continue;
		if (value < 0)//行末情况发生,last_object计数加1,用-1来分割地址中不同对象的属性
		{
			last_object++;//统计非空行的行数,即对象的个数。。。。
			PushNewInterger(-1);
		}
		else
		{
			if (value > last_attribute)
			{
				last_attribute = value;//为了找到最大的属性值,即属性的个数。。。。
			}
			PushNewInterger(value);
		}
		last_value = value;
	}
	if (last_value >= 0)
	{
		last_object++;
		PushNewInterger(-1);//地址中最后一个元素赋值为-1
	}
	objects = last_object + 1;//
	attributes = last_attribute + 1;//所有属性从0开始。。。。 背景从0开始
	//attributes = last_attribute;
	fclose(file);
}

int getNextInt(FILE *file, int *value)
{
	//通过value传值,return仅仅返回真假,是否读取到了数值。。。。
	int ch = ' ';
	*value = -1;//初始化为-1,若ch到行末但不是文件尾,那么value为默认值-1
	while ((ch != EOF) && ((ch < '0') || (ch > '9')))//文件没到末尾且ch不为数字,即空格时
	{
		ch = fgetc(file);
		if (ch == '\n')
			return 1;//走到行尾了。。。。
	}

	if (ch == EOF)
		return 0;//走到文件尾了。。。。

	*value = 0;
	while ((ch >= '0') && (ch <= '9'))//ch为数字的情况,计算value的值
	{
		*value *= 10;
		*value += ch - '0';
		ch = fgetc(file);
	}
	//能走到这说明正好走到一个数字又读取了一个字符,该ch应放回文件流中,待下次判断。。。
	ungetc(ch, file);//相当于撤销上一次的fgetc调用
	return 1;
}

///********************************************************************************************************

int cols_compar(const void *a, const void *b)
{
	int x, y;
	x = supps[*(int const *)a];
	y = supps[*(int const *)b];
	if (x >= min_support)
	{
		if (y >= min_support)
			return (x < y) ? -1 : ((x > y) ? 1 : 0);
		else
			return -1;
	}
	else
	{
		if (y >= min_support)
			return 1;
		else
			return (x < y) ? -1 : ((x > y) ? 1 : 0);
	}
}

int rows_compar(const void *a,const void *b)
{
	int i;
	for (i = 0; i < anum_longSize; i++)
		if (((unsigned long *)a)[i] < ((unsigned long *)b)[i])
			return -1;
		else if (((unsigned long *)a)[i] > ((unsigned long *)b)[i])
			return 1;
	return 0;
}

void sort_context()
{
	int i, j, k, x, y, z, ii, jj, a, aa;
	unsigned long *new_context;

	for (a = i = 0; i < attributes; i++)
		if (supps[i] >= min_support)
			a++;

	qsort(attrib_numbers, attributes, sizeof(int), cols_compar);
	aa = attributes;
	attributes = a;
	a = anum_longSize;
	anum_longSize = (attributes / (ARCHBIT + 1)) + 1;
	new_context = (unsigned long *)malloc(LONG_SIZE * anum_longSize * objects);
	memset(new_context, 0, LONG_SIZE * anum_longSize * objects);
	for (k = jj = 0, ii = ARCHBIT; k < aa; k++)
	{
		if (supps[attrib_numbers[k]] < min_support)
			continue;
		j = attrib_numbers[k] / (ARCHBIT + 1);
		i = ARCHBIT - (attrib_numbers[k] % (ARCHBIT + 1));
		for (x = 0, y = j, z = jj; x < objects; x++, y += a, z += anum_longSize)
			if (context[y] & (BIT << i))
				new_context[z] |= (BIT << ii);
		if (ii > 0)
			ii--;
		else
		{
			ii = ARCHBIT;
			jj++;
		}
	}
	free(context);
	context = new_context;
	qsort(context, objects, byte_anumLongSize, rows_compar);
}

void create_context()//用位数组存储背景
{
	int i = 0, row = 0;
	//31个属性的话就用1个longSize.queue_Flag标志位(用1位),多给了(32-31)=1位,用于queue_Flag,最佳空间利用的很好
	//32个属性的话就用2个longSize.本来一个就Ok了,为了queue_Flag标志位(用1位),多给了(32)=32位,用于queue_Flag
	//33个属性的话就用2个longSize.queue_Flag标志位(用1位),多给了(32-1)=31位,用于queue_Flag
	anum_longSize = (attributes / (ARCHBIT + 1)) + 1;//WWWang 这里多给了(1位到32位,就是为了queue_Flag用的最右边那个标志位。。。)计算存储属性需要的LONG_SIZE个数
	//onum_longSize = (objects / (ARCHBIT + 2))+1;//WWWang计算存储对象需要的LONG_SIZE个数,1位也不多给。。。
	onum_longSize = (objects / (ARCHBIT + 1)) + 1;//这个也多给了(1-32位。。。目前没作用,但是先不动它。。)
	context = (unsigned long *)malloc(LONG_SIZE * anum_longSize * objects);//context是一维数组哈。。。。例如context[0]=??
	supps = (int *)malloc(sizeof(int) * attributes);
	memset(supps, 0, sizeof(int) * attributes);
	if (!context)
	{
		fprintf(stderr, "不能给背景申请空间.\n");
		exit(5);
	}
	memset(context, 0, LONG_SIZE * anum_longSize * objects);//先初始化为0
	//memset(contextN, 0xFF, LONG_SIZE * anum_longSize * objects);
	for (i = 0; i < mybuf_index; i++)//对mybuf数组中的每个元素处理
	{
		if (mybuf[i] < 0)//-1的情况说明一个对象的属性处理完毕,也就是文件中的一行属性处理完毕
		{
			row++;
			continue;
		}
		//0-31context[row * anum_longSize+0], 32-63context[row * anum_longSize+1],,,...context[row * anum_longSize+anum_LongSize-1]//这种思想自己用过。。。。
		context[row * anum_longSize + (mybuf[i] / (ARCHBIT + 1))] |= (BIT << (ARCHBIT - (mybuf[i] % (ARCHBIT + 1)))); //(ARCHBIT - (mybuf[i] % (ARCHBIT + 1)))属性0对应31-0 30对应31-30 31对应31-31。。。
		supps[mybuf[i]]++;
		table_ones++;
		//背景是属性0代表31位,属性1代表30位。。。。属性31代表0位。。    属性32代表31位(因为32%32=0)。。。。
		//printf("context[%d]:%x\n", row * anum_longSize + (mybuf[i] / (ARCHBIT + 1)),context[row * anum_longSize + (mybuf[i] / (ARCHBIT + 1))]);
	}
}

void allocate_mybufer(int **mybufer, int size)//该函数为*mybufer开始的地址分配空间
{
	if (*mybufer)
	{
		*mybufer = (int *)realloc(*mybufer, INT_SIZE * size);
	}
	else
	{
		*mybufer = (int *)malloc(INT_SIZE * size);
	}
	if (!*mybufer)
	{
		fprintf(stderr, "不能重新分配内存\n");
		exit(3);
	}
}

void print_A(unsigned long *setA)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{
	int i, j, c;
	int first = 1;
	for (c = j = 0; j < onum_longSize; j++)
	{
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setA[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					printf(" ");
				}
				printf("%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				break;
			}
		}
	}
}
void print_B(unsigned long *setB)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{
	printf("%x,", setB[0]);
	int i, j, c;
	int first = 1;
	for (c = j = 0; j < anum_longSize; j++)
	{
		for (i = ARCHBIT; i >= 0; i--)
		{
			if (setB[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					printf(" ");
				}
				printf("%d", attrib_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				break;
			}
		}
	}
	printf("\n");
}

void out_concepts(unsigned long *setC, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{
	out_file = fopen("out_file.txt", "a");
	int i, j, c;
	int first = 1;
	for (c = j = 0; j < onum_longSize; j++)
	{
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, " ");
				}
				fprintf(out_file, "%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				fprintf(out_file, " , ");
				break;
			}
		}
	}

	//int i, j, c;
	//int first = 1;
	first = 1;
	for (c = j = 0; j < anum_longSize; j++)
	{
		for (i = ARCHBIT; i >= 0; i--)
		{
			if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, " ");
				}
				fprintf(out_file, "%d", attrib_numbers[c]);
				first = 0;
			}
			c++;//每处理一个属性c要加一
			if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				fprintf(out_file, "\n");
				fclose(out_file);
			}
		}
	}
}

void print_concepts(unsigned long *setC, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{
	int i, j, c;
	int first = 1;
	for (c = j = 0; j < onum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					printf(" ");
				}
				printf("%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				printf(" , ");
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}

	//int i, j, c;
	//int first = 1;
	//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);
	first = 1;
	for (c = j = 0; j < anum_longSize; j++)
	{
		for (i = ARCHBIT; i >= 0; i--)
		{
			//printf("BIT<<i:%x, ",BIT<<i);
			if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					printf(" ");
				}
				printf("%d", attrib_numbers[c]);
				first = 0;
			}
			c++;//每处理一个属性c要加一
			if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				printf("\n");
				break;
			}
		}
	}

}

void print_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{
	int i, j, c;
	int first = 1;
	printf("(({");
	for (c = j = 0; j < onum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					printf(",");
				}
				printf("%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	printf("},{");
	first = 1;
	for (c = j = 0; j < onum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setCN[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					printf(",");
				}
				printf("%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	printf("}),{");
	//int i, j, c;
	//int first = 1;
	//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);
	first = 1;
	for (c = j = 0; j < anum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = ARCHBIT; i >= 0; i--)
		{
			//printf("BIT<<i:%x, ",BIT<<i);
			if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					printf(",");
				}
				printf("%d", attrib_numbers[c]);
				first = 0;
			}
			c++;//每处理一个属性c要加一
			if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	printf("})");
	printf("\n");
}

void out_TWconcepts(unsigned long *setC, unsigned long *setCN, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{

	int i, j, c;
	int first = 1;
	fprintf(out_file, "(({");
	for (c = j = 0; j < onum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, ",");
				}
				fprintf(out_file, "%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	fprintf(out_file, "},{");
	first = 1;
	for (c = j = 0; j < onum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setCN[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, ",");
				}
				fprintf(out_file, "%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	fprintf(out_file, "}),{");
	//int i, j, c;
	//int first = 1;
	//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);
	first = 1;
	for (c = j = 0; j < anum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = ARCHBIT; i >= 0; i--)
		{
			//printf("BIT<<i:%x, ",BIT<<i);
			if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, ",");
				}
				fprintf(out_file, "%d", attrib_numbers[c]);
				first = 0;
			}
			c++;//每处理一个属性c要加一
			if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	fprintf(out_file, "})");
	fprintf(out_file, "\n");

}

void out_TWconcepts_C_CN_D(unsigned long *setC, unsigned long *setCN, unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{

	int i, j, c;
	int first = 1;
	fprintf(out_file, "");
	for (c = j = 0; j < onum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setC[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, " ");
				}
				fprintf(out_file, "%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	fprintf(out_file, ",");
	first = 1;
	for (c = j = 0; j < onum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = 0; i <= ARCHBIT; i++)
		{
			if (setCN[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, " ");
				}
				fprintf(out_file, "%d", object_numbers[c]);
				first = 0;
			}
			c++;//每处理一个对象c要加一
			if (c >= objects)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	fprintf(out_file, "|");
	//int i, j, c;
	//int first = 1;
	//printf(", ConceptNum=%d,%x:", conceptNum, setD[0]);
	first = 1;
	for (c = j = 0; j < anum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = ARCHBIT; i >= 0; i--)
		{
			//printf("BIT<<i:%x, ",BIT<<i);
			if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, " ");
				}
				fprintf(out_file, "%d", attrib_numbers[c]);
				first = 0;
			}
			c++;//每处理一个属性c要加一
			if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}

	fprintf(out_file, "\n");

}

void out_TWconcepts_D(unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{

	int i, j, c;
	int first = 1;
	fprintf(out_file, "|");
	//printf("|");
	first = 1;
	for (c = j = 0; j < anum_longSize; j++)
	{
		int flag_wan = 0;
		for (i = ARCHBIT; i >= 0; i--)
		{
			//printf("BIT<<i:%x, ",BIT<<i);
			if (setD[j] & (BIT << i))//先移位,处理的是第ARCHBIT-i属性
			{
				if (!first)//标志位,输出空格
				{
					fprintf(out_file, " ");
					//printf(" ");
				}
				fprintf(out_file, "%d", attrib_numbers[c]);
				//printf("%d", attrib_numbers[c]);
				first = 0;
			}
			c++;//每处理一个属性c要加一
			if (c >= attributes)//所有的属性处理完毕,则输出回车符,打印完毕
			{
				flag_wan = 1;
				break;
			}
		}
		if (flag_wan == 1)
			break;
	}
	fprintf(out_file, "\n");
	//printf("\n");
}


void out_easy_TWconcepts(unsigned long *setD)//输出概念的属性,也就是内涵。set指针指向的就是内涵的地址,通过位运算来输出背景中为1的属性
{
	int j, num_str = 0;

	for (j = 0; j < anum_longSize; j++)
	{
		fprintf(out_file, "%x ", setD[j]);
	}
		
	fprintf(out_file, "\n");
	
	/*int j,num_str = 0;
	
	for (j = 0; j < anum_longSize; j++)
	{
			intData[num_str++] = setD[j];
	}
	for (int i = 0; i < num_str; i++)
		fprintf(out_file, "%x ", intData[i]);
	fprintf(out_file, "\n");*/
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值