中国剩余定理2020
又到了熟悉的环节,把代码贴出来自己有时间修改,最终的代码将会在验收后进行公开。
/*
creator:bur@n
date:2020-10-20
*/
extern "C" {
#include "miracl.h"
}
#include <stdio.h>
#include <stdlib.h>
//设置组数的数量是GROUP
#define GROUP_NUM 3
#define ARRAY_SIZE 500
//声明结构体
struct each_group_info {
char a[ARRAY_SIZE];
char m[ARRAY_SIZE];
}Each_group_info[GROUP_NUM];
//一些供主函数调用的函数
//欢迎界面
void print_welcome();
//手动输入
void input_by_hand();
//读文件函数
int read_file(char str[]);
//核心函数
int chinese_last_fun(struct each_group_info Each_group_info[]);
//欢迎界面
void print_welcome() {
printf("---------------------------------------------------\n");
printf("欢迎使用中国剩余定理计算\n");
printf("---------------------------------------------------\n\n");
printf("请选择您要使用的功能\n 1手动输入 2读取文件 3退出\n");
}
//手动输入
void input_by_hand() {
int i, flag = 0;
//声明了这个类型数组
for (i = 0; i < GROUP_NUM; i++) {
printf("输入Each_group_info[%d].a\n", i);
scanf("%s", Each_group_info[i].a);
//遇到空格就把信息存入到m中
printf("输入Each_group_info[%d].m\n", i);
scanf("%s", Each_group_info[i].m);
printf("\n");
}
//将输入文件信息列出来
printf("\n文件信息如下:\n");
for (i = 0; i < GROUP_NUM; i++) {
printf("%s,%s\n", Each_group_info[i].a, Each_group_info[i].m);
}
printf("\n");
//开始调用核心函数
flag = chinese_last_fun(Each_group_info);
}
//读文件函数
int read_file(char str[]) {
FILE *fp;
int i, flag = 0;
if ((fp = fopen(str, "r+")) == NULL) {
printf("打开文件%s失败", str);
return 0;
}
else {
//printf("打开文件%s成功!\n", str);
//打开文件成功后进行后续操作
for (i = 0; i < GROUP_NUM; i++) {
fscanf(fp, "%s %s", Each_group_info[i].a, Each_group_info[i].m);
}
fclose(fp);
//将读取的文件数据列出来
printf("\n文件信息如下:\n");
for (i = 0; i < GROUP_NUM; i++) {
printf("%s,%s\n", Each_group_info[i].a, Each_group_info[i].m);
}
printf("\n");
//开始调用核心函数
flag = chinese_last_fun(Each_group_info);
return 0;
}
}
//核心函数
int chinese_last_fun(struct each_group_info Each_group_info[GROUP_NUM]) {
//传进来的是一个结构体数组,我们需要对数组进行操作
int i, j;
char str[ARRAY_SIZE],str1[ARRAY_SIZE];
//我们需要设置一些大数变量
big a[GROUP_NUM], m[GROUP_NUM], Xj[GROUP_NUM], Mj[GROUP_NUM], Mj_1[GROUP_NUM];
big one, temp, temp1, m_factor, m_mult, m_mult_temp;
miracl *mip = mirsys(ARRAY_SIZE, 10);
mip->IOBASE = 10;
one = mirvar(1);
m_mult = mirvar(1);
m_mult_temp = mirvar(1);
temp = mirvar(1);
temp1 = mirvar(0);
m_factor = mirvar(1);
//初始化变量
for (i = 0; i < GROUP_NUM; i++) {
a[i] = mirvar(0);
m[i] = mirvar(0);
Xj[i] = mirvar(0);
Mj[i] = mirvar(0);
Mj_1[i] = mirvar(0);
}
//将字符型变量转换成大数
for (i = 0; i < GROUP_NUM; i++) {
cinstr(a[i], Each_group_info[i].a);
cinstr(m[i], Each_group_info[i].m);
//cotnum(a[i], stdout);
//cotnum(m[i], stdout);
}
//判断是否两两互素
for (i = 0; i < GROUP_NUM; i++) {
for (j = i + 1; j < GROUP_NUM; j++) {
//判断m[i]和m[j]的最大公因数
egcd(m[j], m[i], m_factor);
if (compare(m_factor, one) != 0) {
printf("不能直接利用中国剩余定理\n");
return 0;
}
}
}
//计算所有m的乘积值
for (i = 0; i < GROUP_NUM; i++) {
multiply(m[i], m_mult, m_mult);
}
copy(m_mult, m_mult_temp);
//打印输出m的值
printf("计算得到的m是:");
cotnum(m_mult, stdout);
printf("\n");
//计算所有的Mj_1和Mj
for (i = 0; i < GROUP_NUM; i++) {
divide(m_mult, m[i], Mj[i]);
cotstr(m[i], str1);
//xgcd函数需要仔细使用
xgcd(Mj[i], m[i], Mj_1[i], temp1, temp);
cotstr(Mj_1[i], str);
printf("M%d(-1)分别为:",i+1);
printf("%s(mod %s)\n",str,str1);
copy(m_mult_temp, m_mult);
}
printf("\n");
//计算Xj
temp = mirvar(0);
for (i = 0; i < GROUP_NUM; i++) {
multiply(Mj[i], Mj_1[i], m_factor);
multiply(m_factor, a[i], Xj[i]);
//cotnum(Xj[i], stdout);
//计算最终的累和
cotstr(Xj[i], str);
cotstr(m_mult, str1);
printf("分别获得的X%d是:",i + 1);
printf("%s(mod %s)\n", str, str1);
add(Xj[i], temp, temp);
}
temp1 = mirvar(1);
powmod(temp, temp1, m_mult_temp, temp);
cotstr(temp, str);
printf("\n计算得到X是:");
printf("%s(mod %s)\n\n", str, str1);
mirexit();
return 1;
}
//主函数
int main()
{
/* code */
int flag, flag1;
char str[] = "info.txt";
while (1) {
print_welcome();
//输入进行的操作
scanf("%d", &flag);
//选择函数来判断将进行哪一个操作
switch (flag) {
case 1:printf("\n您选择了手动输入数据!\n\n"); input_by_hand(); break;
case 2:printf("\n您选择了读取文件数据!\n\n"); flag1 = read_file(str); break;
case 3:printf("\n您选择了退出!\n"); return 0;
}
}
return 0;
}