158 lines
3.9 KiB
C
158 lines
3.9 KiB
C
#define _CRT_SECURE_NO_WARNINGS
|
||
#include <stdio.h>
|
||
#include <math.h>
|
||
#define OK 1
|
||
#define ERROR 0
|
||
#define true 1
|
||
#define false 0
|
||
#define MAXSIZE 65535
|
||
typedef int Status;
|
||
typedef int bool;
|
||
/*
|
||
* 前两个预处理语句及第一个typedef语句用于标示文件读写结果
|
||
* 后两个预处理语句及第二个typedef语句用于自定义一个简单bool类型
|
||
*/
|
||
int Primes[50000]; //用以存储质数库
|
||
|
||
Status fileInit(FILE* file)
|
||
{
|
||
file = fopen("质数库存.txt", "w+"); //读写模式
|
||
if(!file) return ERROR; //文件未打开判错,因演示需求未关闭程序
|
||
fprintf(file, "从2起共 50000 个质数。\n");
|
||
fclose(file);
|
||
printf("这是**的期末课程设计\n");
|
||
printf("已创建'质数库存.txt'文件\n");
|
||
return OK;
|
||
}
|
||
|
||
void fileWrite(FILE* file, int d) //写质数文件函数
|
||
{
|
||
fprintf(file, "%d\t", d);
|
||
}
|
||
|
||
bool isPrime(int m) //快速判断质数函数
|
||
{
|
||
int flag = 0;
|
||
for (int i = 2; i <= (int)sqrt((double)m); i++)
|
||
{
|
||
if (m % i == 0)
|
||
{
|
||
flag = 1;
|
||
break;
|
||
}
|
||
}
|
||
return flag == 0; //如果flag等于0则返回1
|
||
}
|
||
|
||
Status getPrimes(FILE* file) //算出50000个质数并存入文件
|
||
{
|
||
file = fopen("质数库存.txt", "a+"); //设为追加模式
|
||
if (!file)return ERROR;
|
||
int count = 0; //计数变量
|
||
for(int i = 2; count < 50000; i++)
|
||
{
|
||
if (isPrime(i))
|
||
{
|
||
fileWrite(file, i);
|
||
count++;
|
||
}
|
||
else continue;
|
||
}
|
||
fclose(file);
|
||
printf("已将2开始的50000个质数写入文件\n");
|
||
return OK;
|
||
}
|
||
|
||
Status PrimeFileRead(FILE* file)
|
||
{
|
||
int i = 0;
|
||
file = fopen("质数库存.txt", "r+");
|
||
if (!file) return ERROR;
|
||
char buff[1000];
|
||
fgets(buff, sizeof(buff), file); //跳过第一行
|
||
while (i < 50000)
|
||
{
|
||
fscanf(file, "%d\t", &Primes[i++]);
|
||
}
|
||
printf("已读取质数文件,并将其存入内存中的数组Primes\n");
|
||
return OK;
|
||
}
|
||
|
||
Status divide(int n, FILE *output) //使用筛选法,利用打表生成的质数字典一一试除
|
||
{
|
||
int factor[MAXSIZE]; //存储因子的数组
|
||
int count = 0; //计数变量
|
||
int temp = sqrt((double)n); //只需试到根号n
|
||
for(int i = 0; i < 50000; i++) //依次取质数表中的数
|
||
{
|
||
if (Primes[i] > temp) break; //如果质因数大于根号n,停止取数
|
||
while (n % Primes[i] == 0) //如果是一个质因数
|
||
{
|
||
factor[++count] = Primes[i]; //则将质数存储入数组
|
||
n /= Primes[i]; //n除以质因数进行下一步分解
|
||
}
|
||
}
|
||
if(n != 1) //若循环结束后,n>1,那么此时n本身也是质数因子
|
||
{
|
||
factor[++count] = n;
|
||
}
|
||
for (int i = 1; i <= count - 1; i++) //控制输出格式,避免最后的乘号
|
||
{
|
||
fprintf(output,"%d × ", factor[i]);
|
||
printf("%d × ", factor[i]);
|
||
}
|
||
fprintf(output, "%d\n", factor[count]);
|
||
printf("%d\n", factor[count]); //输出最后一个
|
||
return OK;
|
||
}
|
||
|
||
Status MakeDivideList(FILE *file)
|
||
{
|
||
file = fopen("待分解.txt", "w+");
|
||
if (!file) return ERROR;
|
||
for (int i = 1; i <= 30; i++)
|
||
fprintf(file, "%d\n", i+182015000);
|
||
fclose(file);
|
||
printf("已生成待分解序列。\n");
|
||
return OK;
|
||
}
|
||
|
||
Status DivideProcess(FILE *file)
|
||
{
|
||
int temp = 0, count = 1;
|
||
int l = 0, r = 0;
|
||
|
||
printf("开始分解...\n\n");
|
||
file = fopen("待分解.txt", "r+"); //读入待分解序列
|
||
FILE* output = fopen("结果.txt", "w+"); //打开结果.txt输出模式
|
||
if (!file || !output) return ERROR; //判断文件能否打开
|
||
|
||
printf("请输入分解左右区间:");
|
||
scanf("%d %d", &l, &r);
|
||
int amount = r - l + 1;
|
||
|
||
printf("从 %d 到 %d 共分解 %d 个:\n", l, r, amount); //输出文件头
|
||
fprintf(output, "从 % d 到 % d 共分解 % d 个:\n", l, r, amount); //输出文件头
|
||
|
||
while (count <= amount) //未到文件尾时
|
||
{
|
||
printf("第 %d 个:%d = ", count, l);
|
||
fprintf(output,"第 %d 个:%d = ", count, l);
|
||
divide(l, output);
|
||
l++;
|
||
count++;
|
||
}
|
||
printf("运行结束,结果同时输出至'结果.txt'\n");
|
||
return OK;
|
||
}
|
||
|
||
int main()
|
||
{
|
||
FILE* file = NULL; //初始化文件指针
|
||
fileInit(file); //利用指针参数,实现修改及同步
|
||
getPrimes(file);
|
||
PrimeFileRead(file);
|
||
MakeDivideList(file);
|
||
DivideProcess(file);
|
||
return 0;
|
||
} |