文档库 最新最全的文档下载
当前位置:文档库 › 操作系统之LRU算法(C语言)

操作系统之LRU算法(C语言)

操作系统之LRU算法(C语言)
操作系统之LRU算法(C语言)

#include

#include

int a[20],b[5][20],c[20]; //a存放访存序列,b存放整个输出的单元中的数,c用来最后输出的缺页的下方的*号

int num1,num2,count;

void printit(int a)/*输出边框*/

{

printf("|");

for(int i=0;i

printf("---+");

printf("---|");

}

void init() //b数组的初始化,全赋初值-1

{

int i,j;

for(i=0;i<5;i++)

for(j=0;j<20;j++)

b[i][j]=-1;

}

void init1() //c数组的初始化,全赋初值-1

{

int i;

for(i=0;i<20;i++)

{

c[i]=-1;

}

}

void LRU()

{

int i,j,k;

int flag=0;

count=1;

init(); //b数组的初始化

b[0][0]=a[0]; //将序列的第一个元素赋给b[0][0]

c[0]=1;

for(j=1;j

{

flag=0; //标志量,若访问的页号在内存则flag=0,反之则为1

for(i=0;i

{

if(a[j]==b[i][j-1]) //若找到相等的,则说明该页在内存中

{

for(k=i;k>0;k--)

{

b[k][j]=b[k-1][j-1]; //前一列这点的前面元素错位移到下一列

}

for(k=i+1;k

{

b[k][j]=b[k][j-1];

}

b[0][j]=a[j]; //并将序列中的该数赋给这一列的第一个元素

flag=1; //标志量置为1;跳过下面的if语句,回到大得for循环

break;

}

}

if(flag==0) //内存中找不到序列中的该数

{

for(i=num2-1;i>0;i--)

{

b[i][j]=b[i-1][j-1]; // 则前一列错位移往这j列,该列中最后一个数被挤掉}

b[0][j]=a[j]; //并将序列中的该数赋给这一列的第一个元素

count++; //缺页次数加1

c[j]=1; //对应的c数组中的该单元被置为1,方便后来输出*号

}

}

}

int main()

{

int i,j,k;

double s;

printf("\t\t***************操作系统课程大实验****************\t\t\n");

printf("\t\t************最近最少LRU页面调度算法**************\t\t\n");

printf("\t\t************ 班级: 09计本(3)班**************\t\t\n");

printf("\t\t***** 姓名: 杨瑱方名吴培桃齐晓娟*********\t\t\n "); start:

init1();

printf("请输入访存的次数:");

scanf("%d",&num1);

printf("请输入这%d个访存序列:",num1);

for(i=0;i

scanf("%d",&a[i]);

printf("请输入分配的物理块数:");

scanf("%d",&num2);

printf("\t\t运行的结果为:\n");

printit(num1);

printf("\n");

for(j=0;j

printf("|%2d ",a[j]);

printf("|\n");

printit(num1);

printf("\n");

LRU();

for(i=0;i

{

for(j=0;j

{

if(b[i][j]==-1)

printf("|%2c ",32); //若b[i][j]=-1,则输出空格

else

printf("|%2d ",b[i][j]); //若b[i][j]!=-1,则输出相应的单元内容}

printf("|\n");

}

printit(num1);

printf("\n");

for(i=0;i

{

if(c[i]==-1)

printf("|%2c ",32); ////若c[i]=-1,则输出空格

else

printf("|%2c ",42); ////若c[i]=-1,则输出*号}

printf("|\n"); //边框输出

printit(num1);

printf("\n");

s=(count*1.0)/num1;

printf("缺页次数为:%3d\n",count);

printf("缺页率为:%f\n",s);

printf("是否继续(y/n)\n");

if(getche()=='y')

printf("\n");

goto start;

}

RC4加密算法C语言实现

RC4 加密算法 C 语言实现 代码文件名 RC4.cpp Encrypt.h (代码详见后文) 备注:将以上两个文件放在相同的路径(建议不要放在中文路径 下)编译执行!编译环境 Microsoft Visual C++ 6.0 C-Free 5.0 代码解释 RC4 加密算法是大名鼎鼎的RSA 三人组中的头号人物Ron Rivest 在1987 年设计的密钥长度可变的流加密算法簇。之所以称其为簇,是由于其核心部分的S-box 长度可为任意,但一般为256字节。该算法的速度可以达到DES 加密的10倍左右。 RC4 算法的原理很简单,包括初始化算法和伪随机子密码生成算法两大部分。假设S-box 长度和密钥长度均为为n。先来看看算法的初始化部分(用类C伪代码表示): for (i=0; i

} 得到的子密码sub_k用以和明文进行xor运算,得到密文,解密过程也完全相同。 RC4加密算法在C++中的实现: RC4函数(加密/解密):其实RC4只有加密,将密文再加密一次,就是解密了。 GetKey函数:随机字符串产生器。 ByteToHex函数:把字节码转为十六进制码,一个字节两个十六进制。十六进制字符串非常适合在HTTP中传输。 HexToByte函数:把十六进制字符串,转为字节码。。 Encrypt函数:把字符串经RC4加密后,再把密文转为十六进制字符串返回,可直接用于传输。 Decrypt函数:直接密码十六进制字符串密文,再解密,返回字符串明文。 源代码 以下为Encrypt.h文件代码 #ifndef _ENCRYPT_RC4_ #defi ne _ENCRYPT_RC4_ #in clude #defi ne BOX_LEN 256 int GetKey(c onst un sig ned char* pass, int pass_le n, un sig ned char *out); int RC4(c onst un sig ned char* data, int data_le n, const un sig ned char* key, int key_le n, un sig ned char* out, i nt* out_le n); static void swap_byte( un sig ned char* a, un sig ned char* b); char* En crypt(co nst char* szSource, const char* szPassWord); // 加密,返回加密结果 char* Decrypt(co nst char* szSource, con st char* szPassWord); // 解密,返回解密结果 char* ByteToHex(c onst un sig ned char* vByte, const int vLe n); // 把字节码pbBuffer转为十六进制字符串,方便传输 unsigned char* HexToByte(const char* szHex); // 把十六进制字符串转为字节码pbBuffer,解码 #e ndif // #ifndef _ENCRYPT_RC4_

补充全排列算法C语言实现

字符串全排列算法C语言实现 问题描述: 输入一个字符串,打印出该字符串中字符的所有排列。 输入: 123 输出: 123 132 213 231 312 321 问题分析: 现象分析: 这种问题,从直观感觉就是用递归方法来实现即:把复杂问题逐渐简单化,进而得出具体代码实现。(如何发现一个问题可以使用递归方式来解决?经分析可以发现:M 个数的排列方法与N(N>M)个数的排列方法没有区别,处理方法与数据的个数没有关系。 处理方法的一致性,就可以采用递归)。 3个数(123)排列,第一位1不动,剩下两个数(23)的排列,只要相互颠倒一下,就可以出现关于1开头的所有排列 123 132 把2换到第一位,保持不动,剩下的两个数(13)的排列,只要相互颠倒一下,就可以出现关于2开头的所有排列 213 231 同理,把3换到第一位,可得到 312 321 扩展: 把3个数的所有排列,前面加一个4,就可以得到关于4开头的所有的排列4123 4132 4213 4231 4312 4321 若把4与后续数据中的任意一个数据交换,通过完成对后续三个数的全排列,就可以得到相应的数开头的四数的排列。 总结: 对4个数的排列,可以转换成首位不动,完成对3个数的排列 对3个数的排列,可以转换成首位不动,完成对2个数的排列 对2个数的排列,可以转换成首位不动,完成对1个数的排列 对于1个数,无排列,直接输出结果 算法实现说明:

对n个数的排列,分成两步: (1)首位不动,完成对n-1个数的排列, (2)循环将后续其他数换到首位,再次进行n-1个数的排列 注:排列完成后,最终的串要与原串相同 C语言代码实现: #include #include //将串左移一位,首位存到末尾。 void shift( char *s ) { if ( !s||!s[0] ) return ; //security code . null string char ch=s[0]; int i=0; while( s[++i] ) s[i-1]=s[i] ; s[i-1]=ch; } //本函数对于一个已排序好的数据进行全排列 void permutation(char list[], int head ) { int i,len; len=strlen(list) ; if ( len-head == 1 ) //后续没有再排列的,则输出排列数据 { printf( "%s\n", list ); } else { for (i = k; i

Warshall算法C语言实现

Warshall算法求传递闭包 例:A = { a, b, c, d ,e} , R 为A 上的关系, R = { ,,< a,e> ,< b,a> ,< b ,b> ,< b,d > ,< b e> , < c, a> , < c,b> ,< c,d> , , ,< d,d> ,< e,a> ,< e ,c>, } ,用Warshall 算法程序求R 的传递闭包. 解:R 的关系矩阵为 MR 10101 11011 10101 11010 10101???????????????? 运行Warshall算法程序运行结果截图: C语言源程序: #include #include void main( ) { int A[10][10] ; int n,i,j,k; printf("请输入关系矩阵的维数n(n<10)\n"); scanf("%d",&n); printf("输入n* n 个数据( 0 or 1)\n"); for(i=1;i<=n;i++)

{ for(j=1;j<=n;j++) { scanf("%d",&A[i][j]); if(A[i][j]!=1&&A[i][j]) printf("There is an error"); } } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { for(k=1;k<=n;k++) { if(A[i][j]&&(A[i][k]||A[j][k])) A[i][k]=1; } } } printf("传递闭包的关系矩阵:\n"); for( i=1;i<=n;i++) { for(j=1;j<=n;j++) printf("%2d",A[i][j]); printf("\n"); } }

线性方程组的数值算法C语言实现(附代码)

线性方程组AX=B 的数值计算方法实验 一、 实验描述: 随着科学技术的发展,线性代数作为高等数学的一个重要组成部分, 在科学实践中得到广泛的应用。本实验的通过C 语言的算法设计以及编程,来实现高斯消元法、三角分解法和解线性方程组的迭代法(雅可比迭代法和高斯-赛德尔迭代法),对指定方程组进行求解。 二、 实验原理: 1、高斯消去法: 运用高斯消去法解方程组,通常会用到初等变换,以此来得到与原系数矩阵等价的系数矩阵,达到消元的目的。初等变换有三种:(a)、(交换变换)对调方程组两行;(b)、用非零常数乘以方程组的某一行;(c)、将方程组的某一行乘以一个非零常数,再加到另一行。 通常利用(c),即用一个方程乘以一个常数,再减去另一个方程来置换另一个方程。在方程组的增广矩阵中用类似的变换,可以化简系数矩阵,求出其中一个解,然后利用回代法,就可以解出所有的解。 2、选主元: 若在解方程组过程中,系数矩阵上的对角元素为零的话,会导致解出的结果不正确。所以在解方程组过程中要避免此种情况的出现,这就需要选择行的判定条件。经过行变换,使矩阵对角元素均不为零。这个过程称为选主元。选主元分平凡选主元和偏序选主元两种。平凡选主元: 如果()0p pp a ≠,不交换行;如果()0p pp a =,寻找第p 行下满足() 0p pp a ≠的第一 行,设行数为k ,然后交换第k 行和第p 行。这样新主元就是非零主元。偏序选主元:为了减小误差的传播,偏序选主元策略首先检查位于主对角线或主对角线下方第p 列的所有元素,确定行k ,它的元素绝对值最大。然后如果k p >,则交换第k 行和第p 行。通常用偏序选主元,可以减小计算误差。 3、三角分解法: 由于求解上三角或下三角线性方程组很容易所以在解线性方程组时,可将系数矩阵分解为下三角矩阵和上三角矩阵。其中下三角矩阵的主对角线为1,上三角矩阵的对角线元素非零。有如下定理: 如果非奇异矩阵A 可表示为下三角矩阵L 和上三角矩阵U 的乘积: A LU = (1) 则A 存在一个三角分解。而且,L 的对角线元素为1,U 的对角线元素非零。得到L 和U 后,可通过以下步骤得到X : (1)、利用前向替换法对方程组LY B =求解Y 。 (2)、利用回代法对方程组UX Y =求解X 。 4、雅可比迭代:

常用数学算法C语言实现

一、基本算法 1.交换(两量交换借助第三者) 例1、任意读入两个整数,将二者的值交换后输出。 main() {int a,b,t; scanf("%d%d",&a,&b); printf("%d,%d\n",a,b); t=a; a=b; b=t; printf("%d,%d\n",a,b);} 【解析】程序中加粗部分为算法的核心,如同交换两个杯子里的饮料,必须借助第三个空杯子。 假设输入的值分别为3、7,则第一行输出为3,7;第二行输出为7,3。 其中t为中间变量,起到“空杯子”的作用。 注意:三句赋值语句赋值号左右的各量之间的关系! 【应用】 例2、任意读入三个整数,然后按从小到大的顺序输出。 main() {int a,b,c,t; scanf("%d%d%d",&a,&b,&c); /*以下两个if语句使得a中存放的数最小*/ if(a>b){ t=a; a=b; b=t; } if(a>c){ t=a; a=c; c=t; } /*以下if语句使得b中存放的数次小*/ if(b>c) { t=b; b=c; c=t; } printf("%d,%d,%d\n",a,b,c);} 2.累加 累加算法的要领是形如“s=s+A”的累加式,此式必须出现在循环中才能被反复执行,从而实现累加功能。“A”通常是有规律变化的表达式,s在进入循环前必须获得合适的初值,通常为0。例1、求1+2+3+……+100的和。 main() {int i,s; s=0; i=1; while(i<=100) {s=s+i; /*累加式*/ i=i+1; /*特殊的累加式*/ } printf("1+2+3+...+100=%d\n",s);} 【解析】程序中加粗部分为累加式的典型形式,赋值号左右都出现的变量称为累加器,其中“i = i + 1”为特殊的累加式,每次累加的值为1,这样的累加器又称为计数器。

PID控制算法的C语言实现

PID控制算法的C语言实现一PID算法原理 最近两天在考虑一般控制算法的C语言实现问题,发现网络上尚没有一套完整的比较体系的讲解。于是总结了几天,整理一套思路分享给大家。 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单!简单的不是原始的,简单的也不是落后的,简单到了美的程度。先看看PID算法的一般形式: PID的流程简单到了不能再简单的程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻): 1.输入量为rin(t); 2.输出量为rout(t); 3.偏差量为err(t)=rin(t)-rout(t); pid的控制规律为

理解一下这个公式,主要从下面几个问题着手,为了便于理解,把控制环境具体一下: 1.规定这个流程是用来为直流电机调速的; 2.输入量rin(t)为电机转速预定值; 3.输出量rout(t)为电机转速实际值; 4.执行器为直流电机; 5.传感器为光电码盘,假设码盘为10线; 6.直流电机采用PWM调速转速用单位转/min表示; 不难看出以下结论: 1.输入量rin(t)为电机转速预定值(转/min); 2. 输出量rout(t)为电机转速实际值(转/min); 3.偏差量为预定值和实际值之差(转/min); 那么以下几个问题需要弄清楚: 1.通过PID环节之后的U(t)是什么值呢 2.控制执行器(直流电机)转动转速应该为电压值(也就是PWM占空比)。 3.那么U(t)与PWM之间存在怎样的联系呢

LRU算法C语言实现

实验二仿真LRU算法实验代码: #include #include #define M 5 #define N 12 typedef struct page { int num; //页面号 int time; //调入内存时间 }Page; Page b[M]; //内存单元数 int c[M][N]; int q[100]; //调入队列 int K; void Init(Page *b,int c[M][N]) { int i,j; for(i=0;imax) { max=b[i].time; tag=i; } } return tag; } int Equation(int r,Page *b) { int i;

for(i=0;i=0) { b[val].time=0; for(i=0;i

各种排序算法C语言实现

#include #include #define Max 20 //最大顶点数 //顺序存储方式使用的结构体定义 typedef struct vexType { char data; int indegree; }Vex; typedef struct Graph { int vexnum; //顶点数量 int arcnum; //边数 Vex vex_array[Max]; //存放顶点的数组 int arc_array[Max][Max]; //存放邻接矩阵的二维数组}Graph; //图的定义 //链式存储使用的结构体定义 typedef struct arcType { char vex1,vex2; //边所依附的两点 int arcVal; //边的权值 }Arc; //边的定义 typedef struct LinkType { int index; //在顶点表的下标 struct LinkType *nextarc; //指向下一个顶点结点 }LinkNode; //边表定义 typedef struct vexNode { char data; int add; //在顶点数组的下表位置 LinkNode *firstarc; //指向边表的第一个结点

int indegree; //入度 }VexNode; //顶点边定义 typedef struct LGraph { VexNode vex_array[Max]; //顶点数组 int vexnum; //图中顶点数 }LGraph; /*函数功能:图的创建 入口参数:图G 返回值:无 */ void Creat_G(Graph *G) { char v; int i=0; int j=0; G->vexnum=0; printf("输入说明。。。有权值请输入权值,无权值请输入1,无边请输入0\n"); printf("\n请输入所有顶点(不超过20个,按‘#’结束输入):\n"); do{ printf("输入第%d 个顶点:",G->vexnum+1); scanf(" %c",&v); G->vex_array[G->vexnum].data = v; G->vexnum++; }while(v!='#'); G->vexnum--; printf("输入邻接矩阵(%d * %d):",G->vexnum,G->vexnum); for(i=0; ivexnum; i++) { printf("输入%c 到以下各点的权值:\n",G->vex_array[i].data); for(j=0; jvexnum; j++) { printf("<%c, %c>: ",G->vex_array[i].data,G->vex_array[j].data); scanf("%d",&G->arc_array[i][j]); }

lzw压缩算法的c语言实现

标准的LZW压缩原理: ~~~~~~~~~~~~~~~~~~ 先来解释一下几个基本概念: LZW压缩有三个重要的对象:数据流(CharStream)、编码流(CodeStream)和编译 表(String Table)。在编码时,数据流是输入对象(图象的光栅数据序列),编码流 就是输出对象(经过压缩运算的编码数据);在解码时,编码流则是输入对象,数据 流是输出对象;而编译表是在编码和解码时都须要用借助的对象。 字符(Character):最基础的数据元素,在文本文件中就是一个字节,在光栅数据中就 是一个像素的颜色在指定的颜色列表中的索引值; 字符串(String):由几个连续的字符组成; 前缀(Prefix):也是一个字符串,不过通常用在另一个字符的前面,而且它的长度可以为0; 根(Root):单个长度的字符串; 编码(Code):一个数字,按照固定长度(编码长度)从编码流中取出,编译表的映射值; 图案:一个字符串,按不定长度从数据流中读出,映射到编译表条目. LZW压缩的原理:提取原始图象数据中的不同图案,基于这些图案创建一个编译表, 然后用编译表中的图案索引来替代原始光栅数据中的相应图案,减少原始数据大小。看 起来和调色板图象的实现原理差不多,但是应该注意到的是,我们这里的编译表不是事 先创建好的,而是根据原始图象数据动态创建的,解码时还要从已编码的数据中还原出 原来的编译表(GIF文件中是不携带编译表信息的),为了更好理解编解码原理,我们 来看看具体的处理过程: 编码器(Compressor) ~~~~~~~~~~~~~~~~ 编码数据,第一步,初始化一个编译表,假设这个编译表的大小是12位的,也就是最 多有4096个单位,另外假设我们有32个不同的字符(也可以认为图象的每个像素最多有32 种颜色),表示为a,b,c,d,e...,初始化编译表:第0项为a,第1项为b,第2项为c... 一直到第31项,我们把这32项就称为根。 开始编译,先定义一个前缀对象Current Prefix,记为[.c.],现在它是空的,然后 定义一个当前字符串Current String,标记为[.c.]k,[.c.]就为Current Prefix,k就 为当前读取字符。现在来读取数据流的第一个字符,假如为p,那么Current String就等 于[.c.]p(由于[.c.]为空,实际上值就等于p),现在在编译表中查找有没有Current String的值,由于p就是一个根字符,我们已经初始了32个根索引,当然可以找到,把p 设为Current Prefix的值,不做任何事继续读取下一个字符,假设为q,Current String 就等于[.c.]q(也就是pq),看看在编译表中有没有该值,当然。没有,这时我们要做下 面的事情:将Current String的值(也就是pq)添加到编译表的第32项,把Current Prefix 的值(也就是p)在编译表中的索引输出到编码流,修改Current Prefix为当前读取的字符(也就是q)。继续往下读,如果在编译表中可以查找到Current String的值([.c.]k), 则把Current String的值([.c.]k)赋予Current Prefix;如果查找不到,则添加Current String的值([.c.]k)到编译表,把Current Prefix的值([.c.])在编译表中所对应的索引 输出到编码流,同时修改Current Prefix为k ,这样一直循环下去直到数据流结束。伪代 码看起来就像下面这样:

数学表达式计算(c语言实现)

一、设计思想 计算算术表达式可以用两种方法实现: 1.中缀转后缀算法 此算法分两步实现:先将算术表达式转换为后缀表达式,然后对后缀表达式进行计算。具体实现方法如下: (1)中缀转后缀 需要建一个操作符栈op和一个字符数组exp,op栈存放操作符,字符数组用来存放转换以后的后缀表达式。首先,得到用户输入的中缀表达式,将其存入str数组中。 对str数组逐个扫描,如果是数字或小数点,则直接存入exp数组中,当扫描完数值后,在后面加一个#作为分隔符。 如果是操作符,并且栈为空直接入栈,如果栈不为空,与栈顶操作符比较优先等级,若比栈顶优先级高,入栈;如果比栈顶优先级低或相等,出栈将其操作符存到exp数组中,直到栈顶元素优先等级低于扫描的操作符,则此操作符入栈;如果是左括号,直接入栈,如果是右括号,出栈存入exp数组,直到遇到左括号,左括号丢掉。然后继续扫描下一个字符,直到遇到str中的结束符号\0,扫描结束。结束后看op栈是否为空,若不为空,继续出栈存入exp数组中,直到栈为空。到此在exp数组最后加结束字符\0。 我们就得到了后缀表达式。 (2)后缀表达式计算 此时需要一个数值栈od来存放数值。对exp数组进行逐个扫描,当遇到数字或小数点时,截取数值子串将其转换成double类型的小数,存入od栈中。当遇到操作符,从栈中取出两个数,进行计算后再放入栈中。继续扫描,知道扫描结束,此时值栈中的数值就是计算的结果,取出返回计算结果。 2.两个栈实现算法 此算法需要两个栈,一个值栈od,一个操作符栈op。将用户输入的数学表达式存入str数组中,对其数组进行逐个扫描。 当遇到数字或小数点,截取数值子串,将其转换成double类型的数值存入od栈中; 当遇到左括号,直接入op栈;遇到右括号,op栈出栈,再从值栈od中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到操作符栈栈顶为左括号,将左括号丢掉。 如果遇到操作符,若op栈为空,直接入栈;若栈不为空,与栈顶元素比较优先等级,若比栈顶操作符优先等级高,直接入op栈,如果低于或等于栈顶优先等级,op栈出栈,再从值栈中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到栈顶优先等级低于扫描的操作符等级,将此操作符入op栈。继续扫描直到遇到str中的结束字符\0,扫描结束。此时看操作符栈是否为空,若不为空,出栈,再从值栈中取出两个数值进行计算,将其结果存入值栈,一直进行此操作,直到操作符栈为空。此时把值栈中的数值取出,即为所得的最终计算结果。 二、算法流程图 第一种算法:中缀转后缀算法

RSA算法C语言实现 实验报告

广州大学学生实验报告开课学院及实验室:年月日 学院年级、专 业、班 姓名学号 实验课程名称成绩 实验项目名称实验4 非对称密码算法实验指导老师 实验目的 掌握产生RSA密钥对的程序设计方法 掌握产生RSA加密/解密的程序设计方法 实验内容 编写函数求出1~65535之间的全部素数 取8-bit的两个素数p,q,并用来生成一对RSA密钥 编写RSA加密/解密程序(可以限制N为16-bit,并利用上述的p,q) 加密你的学号+姓名并随后解密 实验步骤 【RSA算法流程】 加密: 1、取8-bit的两个素数p,q,并用来生成一对RSA密钥 2、根据欧拉函数,求得r=(p-1)(q-1) 3、选择一个小于r的整数e,求得e关于模r的模反元素,命名为d。(模反元素存在,当且仅当e与r互质) 4、(N,e)是公钥,(N,d)是私钥。Alice将她的公钥(N,e)传给Bob,而将她的私钥(N,d)藏起来。 5、利用公式将n加密为c,公式: ) (mod N c n e≡ ,其中e为公钥 解密:利用公式将c加密为n ,公式: ) (mod N n c d≡ ,其中d为私钥 RSA算法的C代码实现 1、判断是否为素数 2、随机产生素数p,q,最大为8bit 3、产生公钥e(根据欧拉函数r,从2开始遍历寻找符合条件的e,直到int变量溢出)

4、产生私钥d(从1开始遍历符合条件的d,直到变量溢出) 5、实现加解密公式的代码(a是加解密文本,b为公钥或私钥,c为N=pq) 运行结果截屏:实验中遇到的问题与解决方法: 1、p,q值过大,导致加密后数据溢出(将获得的p,q的结果mod 254后加1) 2、加密后的数据用char类型存储溢出 (char类型太小,改用int或更大的数据类型存储加密结果更好) 3、cin遇到空格直接返回结果,没有获取空格后的字符串,无法一次读取学号+空格+姓名(改用gets函数) 4、scanf函数与gets函数冲突 (这是因为二者使用的结束标记不同。输入字符串时,scanf()或cin>>遇到空格、回车、Tab 结束,但在缓冲区中还留着这些结束符,此后如果使用gets()想去获取下一行字符串,它碰到的却是前面遗留下来的回车(或者回车之前还有空格等空白符),那么这次gets()就直接失效了,解决方法:用一句while(getchar()!='\n'); 来处理掉缓冲区里的回车换行符,或者改用cin函数) 5、p,q值过小,导致N过小,加密后的字符无法被解密还原为原文 (这是因为公式mod N,结果的范围从0~N-1,所以假如N小于原文的值则解密将出错,解决方法为扩大p,q取值,所以p,q按课件的要求取8bit范围的数可能会出错,范围要扩大到涵盖原文取值,建议取值为逼近8bit的素数) 实验总结:略

PID控制算法的C语言实现(完整版)

PID控制算法的C语言实现一 PID算法原理 最近两天在考虑一般控制算法的C语言实现问题,发现网络上尚没有一套完整的比较体系的讲解。于是总结了几天,整理一套思路分享给大家。 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单!简单的不是原始的,简单的也不是落后的,简单到了美的程度。先看看PID算法的一般形式: PID的流程简单到了不能再简单的程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻): 1.输入量为rin(t); 2.输出量为rout(t); 3.偏差量为err(t)=rin(t)-rout(t); pid的控制规律为 理解一下这个公式,主要从下面几个问题着手,为了便于理解,把控制环境具体一下: 1.规定这个流程是用来为直流电机调速的;

2.输入量rin(t)为电机转速预定值; 3.输出量rout(t)为电机转速实际值; 4.执行器为直流电机; 5.传感器为光电码盘,假设码盘为10线; 6.直流电机采用PWM调速转速用单位转/min表示; 不难看出以下结论: 1.输入量rin(t)为电机转速预定值(转/min); 2. 输出量rout(t)为电机转速实际值(转/min); 3.偏差量为预定值和实际值之差(转/min); 那么以下几个问题需要弄清楚: 1.通过PID环节之后的U(t)是什么值呢? 2.控制执行器(直流电机)转动转速应该为电压值(也就是PWM占空比)。 3.那么U(t)与PWM之间存在怎样的联系呢? https://www.wendangku.net/doc/4b10721328.html,/user1/3407/archives/2006/33541.html(见附录1)这篇文章上给出了一种方法,即,每个电压对应一个转速,电压和转速之间呈现线性关系。但是我考虑这种方法的前提是把直流电机的特性理解为线性了,而实际情况下,直流电机的特性绝对不是线性的,或者说在局部上是趋于线性的,这就是为什么说PID调速有个范围的问题。具体看一下 https://www.wendangku.net/doc/4b10721328.html,/component/article90249.htm(见附录2)这篇文章就可以了解了。所以在正式进行调速设计之前,需要现有开环系统,测试电机和转速之间的特性曲线(或者查阅电机的资料说明),然后再进行闭环参数整定。这篇先写到这,下一篇说明连续系统的离散化问题。并根据离散化后的特点讲述位置型PID和增量型PID的用法和C语言实现过程。

卡尔曼滤波算法C语言实现

卡尔曼滤波算法及C 语言实现 摘要:本文着重讨论了卡尔曼滤波器的原理,典型算法以及应用领域。清晰地阐述了kalman filter 在信息估计方面的最优性能。着重介绍简单kalman filter algorithm 的编程,使用kalman filter 的经典5个体现最优化递归公式来编程。通过c 语言编写程序实现kalman filter 的最优估计能力。 关键词:kalman filter ;最优估计;C 语言 1 引言 Kalman Filter 是一个高效的递归滤波器,它可以实现从一系列的噪声测量中,估计动态系统的状态。起源于Rudolf Emil Kalman 在1960年的博士论文和发表的论文《A New Approach to Linear Eiltering and Prediction Problems 》(《线性滤波与预测问题的新方法》)。并且最先在阿波罗登月计划轨迹预测上应用成功,此后kalman filter 取得重大发展和完善。它的广泛应用已经超过30年,包括机器人导航,控制。传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等,近年来更被广泛应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。 2 kalman filter 最优化递归估计 Kalman filter 是一个“optimal recursive data processing algorithm (最优化递归数据处理方法)”。对于解决很大部分的问题,他是最优,效率最高甚至是最有用的方法。而kalman filter 最为核心的内容是体现它最优化估计和递归特点的5条公式。举一个例子来详细说明5条公式的物理意义。 假设我们要研究的对象是某一个房间的温度信号。对于室温来说,一分钟内或一小段时间内的值是基本上不变的或者变化范围很小。也就是说1t 时刻的温度1T 和2t 时刻的温度2T 基本不变,即12T T =。在这个过程中,因为毕竟温度还是有所改变的,设有几度的偏差。我们把这几度的偏差看成是高斯白噪声)(t w ,也就是说0)]([=t w E ,2)]([σ=t w D 。除此之外我们在用一个温度计来实时测量房间的温度值Z ,但由于量具本身的误差,所测得的温度值也是不准确的,也会和实际值偏差几度,把这几度的偏差看成是测量噪声)(t v 。即满足0)]([=t v E ,21)]([σ=t v D 。 此时我们对于这个房间的温度就得到了两个数据。一个是你根据经验得到的经验值12T T =,一个是从温度计上得到的测量值Z ,以及各自引入的高斯白噪声。下面就具体讲

dijkstra算法的C语言实现

#include "stdafx.h" #include "stdio.h" #include #define N 6 #define MAX 9999 void Path(int *p,int v,int i) { int que[N]; int t=v; que[t++]=i; int tmp=p[i]; while(tmp!=v) { que[t]=tmp; t++; tmp=p[tmp]; } que[t]=v; for(int k=t;k>=1;--k) if(k!=1) printf("%d-->",que[k]); else { printf("%d",que[k]); printf("\n"); } } int main() { int cost[N][N]={ {MAX,MAX,MAX,MAX,MAX,MAX}, {MAX,MAX,10,MAX,30,100}, {MAX,MAX,MAX,50,MAX,MAX}, {MAX,MAX,MAX,MAX,MAX,10}, {MAX,MAX,MAX,20,MAX,60}, {MAX,MAX,MAX,MAX,MAX,MAX} }; int S[N]; int dist[N]; int p[N]; int i,j,u,min;

for(i=1;i%d:%d",i,dist[i]); printf("顶点遍历:"); Path(p,1,i); } system("pause"); }

神经网络的BP算法C语言实现

//BP算法简单实现,C语言代码可运行,详细注释 //代码存放文件本文用的绝对路径,会报错,请自行更改路径或者改成相对路径 /////////////////////////////////////////// #include #include #include #include #define input 2 //输入层 #define hidden 10 //隐层 #define output 1 //输出层 #define sampleNum 90 //样本容量 #define test 10 //测试集容量 #define nr 0.1 //学习效率 #define EPS 0.00001 float x[sampleNum][input],d[sampleNum][output],whi[input][hidden],wij[hidden][output],thi[hidden], thj[output]; //x是输入的值,d是输出的值,whi是权值, int h,i,j,k,ff; double testdata[1][2]; float xmin[input],xmax[input],dmin[output],dmax[output]; FILE *fp1,*fp2,*fp3,*fp4; void init(void); void startleaning(void); void testsample(void); void readw(void); void readt(void); void writew(void); float sigmoid(float a); double ranu(void); void init(void) { int min,max; if(fp1==0) { system("cls"); printf("Can not find the learning sample file!\n"); exit(0); }

RC4流密码算法之C语言实现

RC4流密码算法之C语言实现 RC4加密算法 RC4算法的原理很简单,包括初始化算法(KSA)和伪随机子密码生成算法(PRGA)两大部分。假设S-box长度和密钥长度均为为n。先来看看算法的初始化部分(用类C伪代码表示): for (i=0; i

sub_k=s((s+s[j])%n); } 位长可以自己随意设置,将256设置为你希望的即可我的C语言源码: 平台:windowsXP,VC++6.0 有什么大家可以讨论的地方请留言或发邮件至我邮箱: #include #include #include void swap(unsigned char *s1,unsigned char *s2) { char temp; temp=*s1; *s1=*s2; *s2=temp; } void re_S(unsigned char *S) { unsigned int i; for(i=0;i<256;i++) S[i]=i; } void re_T(unsigned char *T,char *key) { int i; int keylen; keylen=strlen(key); for(i=0;i<256;i++) T[i]=key[i%keylen]; } void re_Sbox(unsigned char *S,unsigned char *T) { int i; int j=0; for(i=0;i<256;i++) { j=(j+S[i]+T[i])%256;

bm算法,C语言实现

算法设计与分析基础 实验报告 实验名称 BM算法的实现 学院计算机学院 专业班级计算机科学与技术09(2)班学号 3109005933 姓名黄进杰 指导教师顾国生 2012年12 月03 日

一、实验目的与要求 理解Boyer-Moore算法的思想 掌握用Boyer-Moore算法来查找字符或字符串的方法 二、实验内容 #include #include #include #define TMax 10000 //文本串最大值 #define PMax 200 //模式串最大值 /* 函数:int* MakeSkip(char *, int) 目的:根据坏字符规则做预处理,建立一张坏字符表 参数: ptrn => 模式串P PLen => 模式串P长度 返回: int* - 坏字符表 */ int* MakeSkip(char *ptrn, int pLen) { int i; //为建立坏字符表,申请256个int的空间 /*PS:之所以要申请256个,是因为一个字符是8位, 所以字符可能有2的8次方即256种不同情况*/ int *skip = (int*)malloc(256*sizeof(int)); if(skip == NULL) { fprintf(stderr, "malloc failed!"); return 0; } //初始化坏字符表,256个单元全部初始化为pLen for(i = 0; i < 256; i++) { *(skip+i) = pLen; } //给表中需要赋值的单元赋值,不在模式串中出现的字符就不用再赋值了 while(pLen != 0) { *(skip+(unsigned char)*ptrn++) = pLen--;

相关文档
相关文档 最新文档