C统计1-49的数字出现的次数

/*
 *  main.c
 *
 *  Created on: Jan 23, 2013
 *      Author: linux 杨志永
 *      QQ    : 929168233
 *      Email : ljy520zhiyong@163.com
 *
 */

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

//数组的长度(一共49个数字,所以定义了50个元素,第一个元素为0,以后的一一对应
#define LENGTH 50

//定义输出时,在一行中最多打印的数字
#define ROWSIZE 15

//定义随机产生数字的个数
#define TESTSIZE 500000

#define FILE_IN_NAME "input.txt"

#define FILE_OUT_NAME "out.txt"

void initNums(int initNumbers[], int length);
int count(int initNumbers[], int length, int number);
void writeToFile(int countNumber[], int initNumbers[], int copyInit[],
		int differentCountArray[], FILE * file_out);
void generate();
void getDifferentCount(int arrays[], const int original[]);
void copyArray(int destination[], const int original[], int length);
int my_compare(const void *x, const void *y);

int main(int argc, char * argv[]) {
	FILE *file_in = fopen(FILE_IN_NAME, "r");
	if (file_in == NULL ) {
		perror("No input.txt file!");
		exit(1);
	}

	FILE *file_out = fopen(FILE_OUT_NAME, "w+");
	if (file_out == NULL ) {
		perror("Create or open out.txt file error!");
		exit(1);
	}

	//统计数字i出现的次数为countNumber[i]
	int countNumber[LENGTH] = { 0 };

	//初始化数据
	int initNum[LENGTH] = { 0 };

	//这个用来保存出现0次的数字。如果copyInit[i] == 0,表示数字i的次数不为0
	int copyInit[LENGTH] = { 0 };

	//这个用来保存不同次数的数字
	int differentCountArray[LENGTH] = { 0 };

	initNums(initNum, LENGTH);
	initNums(copyInit, LENGTH);

	char * read_num = calloc(10, sizeof(char));
	if (read_num == NULL ) {
		perror("分配内存在read_num失败!!");
		exit(1);
	}
	fscanf(file_in, "%s", read_num);
	while (feof(file_in) == 0) {
		//printf("read_num = %s\n", read_num);
		if (atoi(read_num) != 0) {
			int index = count(initNum, LENGTH, atoi(read_num));
			if (index != -1 && index < LENGTH) {
				countNumber[index]++;
			}
		}
		fscanf(file_in, "%s", read_num);
	}

	getDifferentCount(differentCountArray, countNumber);

	writeToFile(countNumber, initNum, copyInit, differentCountArray, file_out);

	//释放内存
	free(read_num);
	fflush(file_out);
	fflush(file_in);
	fclose(file_in);
	fclose(file_out);

	//产生测试使用的随机数
	//generate();

	return 0;
}

/**
 * 初始化数字,0,1,2....到49
 */
void initNums(int initNumbers[], int length) {
	int i = 0;
	for (i = 0; i < length; i++) {
		initNumbers[i] = i;
	}
}

/**
 * 统计数字number在initNumbers中出现的索引位置,并返回该位置。方便将该位置的值加1,即累加该位置的次数
 */
int count(int initNumbers[], int length, int number) {
	int index = -1;
	int i = 0;

	for (i = 0; i < length; i++) {
		if (initNumbers[i] == number) {
			index = i;
			break;
		}
	}
	return index;
}

/**
 *将结果写入out.txt文件中
 */
void writeToFile(int countNumber[], int initNumbers[], int copyInit[],
		int differentCountArray[], FILE * file_out) {
	int i = 0;
	int j = 0;

	//rowSize用来控制一行中最多输出的数字的个数
	int rowSize = 0;

	//首先输出的是次数不为0的数字及它的次数
	for (i = 1; i < LENGTH; i++) {
		if (countNumber[i] > 0) {
			fprintf(file_out, "数字 [%02d] 出现的次数为 <%d次>\n", i, countNumber[i]);
		}
	}
	fprintf(file_out, "\n");
	fflush(file_out);

	for (i = 0; i < LENGTH; i++) {
		rowSize = 0;
		if (differentCountArray[i] > 0) {
			//这里输出的是具有相同次数的数字
			fprintf(file_out, "出现的次数为 <%d次>的数字有:\n", differentCountArray[i]);
			for (j = 0; j < LENGTH; j++) {
				if (countNumber[j] == differentCountArray[i]) {
					fprintf(file_out, "%02d  ", j);

					//将曾经出现过的数字标记为0,表示该数字已经出现过了
					copyInit[j] = 0;

					rowSize++;
					if (rowSize == ROWSIZE) {
						fprintf(file_out, "\n");
						rowSize = 0;
					}
				}
			}
			fprintf(file_out, "\n");
			fprintf(file_out, "\n");
			fflush(file_out);
		}
	}

	fprintf(file_out, "\n");

	//下面输出出现0次的数字
	fprintf(file_out, "出现的次数为 <0次>的数字有:\n");
	rowSize = 0;
	for (j = 0; j < LENGTH; j++) {
		// copyInit[j] != 0 表示还没有出现过的数字,即表示是0次的数字
		if (copyInit[j] != 0) {
			fprintf(file_out, "%02d  ", copyInit[j]);
			rowSize++;
			if (rowSize == ROWSIZE) {
				fprintf(file_out, "\n");
				rowSize = 0;
			}
		}
	}
	fflush(file_out);
}

/**
 * 用于产生测试数据,并将数据保存在tmp.txt文件中
 */
void generate() {
	FILE * tmp = fopen("tmp.txt", "w+");
	if (tmp == NULL ) {
		perror("error on tmp file open");
		exit(1);
	}

	int i = 0;
	int count = 0;
	srand((int) time(0));
	for (i = 0; i < TESTSIZE; i++) {
		fprintf(tmp, "%d ", ((rand() % 49) + 1));
		count++;
		if (count == ROWSIZE) {
			fprintf(tmp, "\n");
			count = 0;
		}
	}

	fclose(tmp);
}

//获取不同出现的次数并保存在arrays[]数组中
void getDifferentCount(int arrays[], const int original[]) {
	int i = 0;
	int j = 0;
	int k = 0;
	int tmp[LENGTH] = { 0 };
	copyArray(tmp, original, LENGTH);

	//排序,升序
	qsort(tmp, LENGTH, sizeof(int), my_compare);

	//去除重复
	for (i = 0; i < LENGTH; i++) {
		for (j = i + 1; j < LENGTH; j++) {
			if (tmp[i] == tmp[j]) {
				tmp[j] = 0;
			}
		}
	}

	//然后将临时数组中保存的次数不为0的数据复制到arrays[]数组中
	for (i = 0; i < LENGTH; i++) {
		if (tmp[i] != 0) {
			for (k = 0; k < LENGTH; k++) {
				if (arrays[k] == 0) {
					arrays[k] = tmp[i];
					break;
				}
			}
		}
	}

}

//复制数组
void copyArray(int destination[], const int original[], int length) {
	int i = 0;
	for (i = 0; i < length; i++) {
		destination[i] = original[i];
	}
}

//void qsort(void *base, size_t nmemb, size_t size, int(*compare) (const void *, const void *));
int my_compare(const void *x, const void *y) {
	const int *a = x;
	const int *b = y;
	return (*a - *b)*(-1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值