精华内容
下载资源
问答
  • 数据结构 Hash(哈希

    万次阅读 多人点赞 2018-05-20 01:23:34
    什么是Hash 要想知道什么是哈希,那得先了解哈希函数 哈希函数 对比之前博客讨论的二叉排序树 二叉平衡树 红黑树 B B+树,它们的查找都是先从根节点进行查找,从节点取出数据或索引与查找值进行比较。那么...

    参考链接:数据结构(严蔚敏)
    文章发布很久了,具体细节已经不清晰了,不再回复各种问题
    文章整理自严蔚敏公开课视频
    可以参考
    https://www.bilibili.com/video/av22258871/
    如果链接失效 可以自行搜索 数据结构严蔚敏视频
    @2021/07/12

    一、什么是Hash表

    要想知道什么是哈希表,那得先了解哈希函数
    哈希函数

    对比之前博客讨论的二叉排序树 二叉平衡树 红黑树 B B+树,它们的查找都是先从根节点进行查找,从节点取出数据或索引与查找值进行比较。那么,有没有一种函数H,根据这个函数和查找关键字key,可以直接确定查找值所在位置,而不需要一个个比较。这样就**“预先知道”**key所在的位置,直接找到数据,提升效率。

    地址index=H(key)
    说白了,hash函数就是根据key计算出应该存储地址的位置,而哈希表是基于哈希函数建立的一种查找表

    二、哈希函数的构造方法

    根据前人经验,统计出如下几种常用hash函数的构造方法:
    直接定制法
    哈希函数为关键字的线性函数如 H(key)=a*key+b
    这种构造方法比较简便,均匀,但是有很大限制,仅限于地址大小=关键字集合的情况
    使用举例:
    假设需要统计中国人口的年龄分布,以10为最小单元。今年是2018年,那么10岁以内的分布在2008-2018,20岁以内的分布在1998-2008……假设2018代表2018-2008直接的数据,那么关键字应该是2018,2008,1998……
    那么可以构造哈希函数H(key)=(2018-key)/10=201-key/10
    那么hash表建立如下

    index key 年龄 人数(假设数据)
    0 2018 0-10 200W
    1 2008 10-20 250W
    2 1998 20-30 253W
    3 1988 30-40 300W
    ……

    数字分析法
    假设关键字集合中的每个关键字key都是由s位数字组成(k1,k2,,knk_1,k_2,……,k_n),分析key中的全体数据,并从中提取分布均匀的若干位或他们的组合构成全体

    使用举例
    我们知道身份证号是有规律的,现在我们要存储一个班级学生的身份证号码,假设这个班级的学生都出生在同一个地区,同一年,那么他们的身份证的前面数位都是相同的,那么我们可以截取后面不同的几位存储,假设有5位不同,那么就用这五位代表地址。
    H(key)=key%100000
    此种方法通常用于数字位数较长的情况,必须数字存在一定规律,其必须知道数字的分布情况,比如上面的例子,我们事先知道这个班级的学生出生在同一年,同一个地区。
    平方取中法
    如果关键字的每一位都有某些数字重复出现频率很高的现象,可以先求关键字的平方值,通过平方扩大差异,而后取中间数位作为最终存储地址。
    使用举例
    比如key=1234 1234^2=1522756 取227作hash地址
    比如key=4321 4321^2=18671041 取671作hash地址
    这种方法适合事先不知道数据并且数据长度较小的情况
    折叠法
    如果数字的位数很多,可以将数字分割为几个部分,取他们的叠加和作为hash地址
    使用举例
    比如key=123 456 789
    我们可以存储在61524,取末三位,存在524的位置
    该方法适用于数字位数较多且事先不知道数据分布的情况
    除留余数法用的较多
    H(key)=key MOD p (p<=m m为表长)
    很明显,如何选取p是个关键问题。

    使用举例
    比如我们存储3 6 9,那么p就不能取3
    因为 3 MOD 3 == 6 MOD 3 == 9 MOD 3
    p应为不大于m的质数或是不含20以下的质因子的合数,这样可以减少地址的重复(冲突)

    比如key = 7,39,18,24,33,21时取表长m为9 p为7 那么存储如下

    index 0 1 2 3 4 5 6 7 8
    key 7 21(冲突后移) 24 *39* 18(冲突后移) 33冲突后移)
    **随机数法** H(key) =Random(key) 取关键字的随机函数值为它的散列地址

    hash函数设计的考虑因素

    1.计算散列地址所需要的时间(即hash函数本身不要太复杂)
    2.关键字的长度
    3.表长
    4.关键字分布是否均匀,是否有规律可循
    5.设计的hash函数在满足以上条件的情况下尽量减少冲突

    三、哈希冲突

    即不同key值产生相同的地址,H(key1)=H(key2)
    比如我们上面说的存储3 6 9,p取3是
    3 MOD 3 == 6 MOD 3 == 9 MOD 3
    此时3 6 9都发生了hash冲突

    哈希冲突的解决方案

    不管hash函数设计的如何巧妙,总会有特殊的key导致hash冲突,特别是对动态查找表来说。
    hash函数解决冲突的方法有以下几个常用的方法
    1.开放定制法
    2.链地址法
    3.公共溢出区法
    建立一个特殊存储空间,专门存放冲突的数据。此种方法适用于数据和冲突较少的情况。
    4.再散列法
    准备若干个hash函数,如果使用第一个hash函数发生了冲突,就使用第二个hash函数,第二个也冲突,使用第三个……
    重点了解一下开放定制法和链地址法

    开放定制法

    首先有一个H(key)的哈希函数
    如果H(key1)=H(keyi)
    那么keyi存储位置Hi=(H(key)+di)MODmH_i=(H(key)+d_i)MOD mm为表长
    did_i有三种取法
    1)线性探测再散列
    di=cid_i=c*i
    2)平方探测再散列
    di=12,12,22,22d_i=1^2,-1^2,2^2,-2^2……
    3)随机探测在散列(双探测再散列)
    did_i是一组伪随机数列
    注意
    增量di应该具有以下特点(完备性):产生的Hi(地址)均不相同,且所产生的s(m-1)个Hi能覆盖hash表中的所有地址

    • 平方探测时表长m必须为4j+3的质数(平方探测表长有限制)
    • 随机探测时m和di没有公因子(随机探测di有限制)
      三种开放定址法解决冲突方案的例子

    废话不多说,上例子就明白了
    有一组数据
    19 01 23 14 55 68 11 86 37要存储在表长11的数组中,其中H(key)=key MOD 11
    那么按照上面三种解决冲突的方法,存储过程如下:
    (表格解释:从前向后插入数据,如果插入位置已经占用,发生冲突,冲突的另起一行,计算地址,直到地址可用,后面冲突的继续向下另起一行。最终结果取最上面的数据(因为是最“占座”的数据))
    线性探测再散列
    我们取di=1,即冲突后存储在冲突后一个位置,如果仍然冲突继续向后

    index 0 1 2 3 4 5 6 7 8 9 10
    key 55 1 14 19 86
    23冲突 23
    68冲突 68冲突 68
    11冲突 11冲突 11冲突 11冲突 11冲突 11
    37冲突 37冲突 37
    最终存储结果 55 1 23 14 68 11 37 19 86
    **平方探测再散列**
    index 0 1 2 3 4 5 6 7 8 9 10
    key 55 1 14 37 19 86
    23冲突 H(23)+1
    H(68)-1冲突 68冲突 H(68)+1冲突 H(68)+4
    11冲突 H(11)+1冲突 H(11)-1
    最终存储结果 55 1 23 14 37 68 19 86 11
    **随机探测在散列(双探测再散列)** 发生冲突后 H(key)‘=(H(key)+di)MOD m 在该例子中 H(key)=key MOD 11 我们取di=key MOD 10 +1 则有如下结果:
    index 0 1 2 3 4 5 6 7 8 9 10
    key 55 1 68 14 19 86
    23冲突 H(23)+3+1
    11冲突 H(11)+1+1冲突 H(11)+1+1+1+1
    (H(37)+8)模11冲突 37冲突 (H(37)+8+8+8)模11 (H(37)+8+8)模11冲突
    最终存储结果 55 1 68 14 23 11 37 19 86

    链地址法

    产生hash冲突后在存储数据后面加一个指针,指向后面冲突的数据
    上面的例子,用链地址法则是下面这样:

    这里写图片描述
    四、hash表的查找

    查找过程和造表过程一致,假设采用开放定址法处理冲突,则查找过程为:
    对于给定的key,计算hash地址index = H(key)
    如果数组arr【index】的值为空 则查找不成功
    如果数组arr【index】== key 则查找成功
    否则 使用冲突解决方法求下一个地址,直到arr【index】== key或者 arr【index】==null

    hash表的查找效率

    决定hash表查找的ASL因素:
    1)选用的hash函数
    2)选用的处理冲突的方法
    3)hash表的饱和度,装载因子 α=n/m(n表示实际装载数据长度 m为表长)
    一般情况,假设hash函数是均匀的,则在讨论ASL时可以不考虑它的因素
    hash表的ASL是处理冲突方法和装载因子的函数
    前人已经证明,查找成功时如下结果:

    这里写图片描述
    可以看到无论哪个函数,装载因子越大,平均查找长度越大,那么装载因子α越小越好?也不是,就像100的表长只存一个数据,α是小了,但是空间利用率不高啊,这里就是时间空间的取舍问题了。通常情况下,认为α=0.75是时间空间综合利用效率最高的情况。

    上面的这个表可是特别有用的。假设我现在有10个数据,想使用链地址法解决冲突,并要求平均查找长度<2
    那么有1+α/2 <2
    α<2
    即 n/m<2 (n=10)
    m>10/2
    m>5 即采用链地址法,使得平均查找长度< 2 那么m>5

    之前我的博客讨论过各种树的平均查找长度,他们都是基于存储数据n的函数,而hash表不同,他是基于装载因子的函数,也就是说,当数据n增加时,我可以通过增加表长m,以维持装载因子不变,确保ASL不变。
    那么hash表的构造应该是这样的:

    这里写图片描述
    五、hash表的删除

    首先链地址法是可以直接删除元素的,但是开放定址法是不行的,拿前面的双探测再散列来说,假如我们删除了元素1,将其位置置空,那 23就永远找不到了。正确做法应该是删除之后置入一个原来不存在的数据,比如-1

    展开全文
  • LR(0)分析的构建

    万次阅读 多人点赞 2019-05-31 22:56:50
    LR(0)分析的构建

    LR(0)分析表的构建

    一、实验要求

    构建LR(0)分析表
    例:
    G[E]:
    E->aA
    E->bB
    A->cA
    A->d
    B->cB
    B->d

    二、实验原理

    在网上找了好久,发现大多数都是概念和复杂公式,
    因此为了使大家能够更好的理解LR(0)分析表的构建,我准备举一个例子进行详细解析,一步步进行分析,直到最后画出分析表。
    文法:
    E->aA
    E->bB
    A->cA
    A->d
    B->cB
    B->d

    1. 给初始符再构建一个初始符E’->E(I0)
    2. 为该初始符加上 ..,变成E’->.E
    3. 查看小圆点后字符是否为非终结符,是,将左部为该非终结符的文法加入其中,并为其添加小圆点;反之进行下一步。(I0变成E’->.E E->.aA E->.bB)
    4. 对I项目中的文法进行分析,若小圆点在最后,则不做处理;若小圆点不在最后,则将根据每个文法的小圆点后的字符来开辟出新的I项目,该文法为新项目的首句文法(I0的文法进行开辟,I0不变,生成I1、I2和I3,I1:E’>.E I2:E->.aA I3:E->.bB),然后将新开辟项目的文法小圆点向后移一位(I1:E’>E. I2:E->a.A I3:E->b.B)。注:若开辟的项目和重复,则不进行开辟,再次利用已存在的项目)
    5. 对开辟的项目重复3-4步骤,直到不再有项目开辟
      具体结果请见下图

    在这里插入图片描述

    6.然后根据上图,构建出相应的分析表
    在这里插入图片描述

    三、算法设计

    1. 设计字符串存储文法,采用结构体存储生成的项目以及项目的去向
    2. 为项目0赋予新的初始符,并添加小圆点
    3. 判断小圆点后的字符:
      若为终结符,进行下一步;若为非终结符,将该非终结符为左部的文法加入该项目当中,并为其添加小圆点。
    4. 判断小圆点位置:
      若在该句文法最后,则进行下一步;反之,开辟新的项目,该句文法为新项目的首句文法,并将新项目文法的小圆点后移一位
      注:若开辟的项目中文法和已有的项目重复,则该文法不进行开辟,再次利用已存在的项目。
    5. 重复执行3-4,直到不再有新的空间开辟出来。

    四、模块设计

    1. 变量定义
    char str[10][10];//存储文法 
    int n;//存储文法行数 
    int v=0;//存储生成项的个数 
    char r[20][10];//存储分析表的float值 
    int rr[20][10];//存储分析表的int值 
    struct DFA{
    	int num;//记录生成项的序号 
    	int  c[10];//存储该项目各个文法的去向(子代) 
    	int f;//记录该项目的来源(父代) 
    	char ss[10][10];//存储该项的文法 
    	int count;//记录该项的文法行数 
    	int l;//存储第一行字符串'.'的位置 
    }LR[20];
    
    1. 输入模块
      从键盘输入上下文无关文法,存储到char类型的字符串数组当中
    //初始化,输入上下文无关文法,以#号结尾 
    void Init(){
    	int i,j;
    	cout<<"输入上下文无关文法:"<<endl;
    	for(i=1;;i++){
    		cin>>str[i];
    		if(str[i][0]=='#')
    		break;
    	}
    	strcat(str[0],"Z->");
    	str[0][3]=str[1][0]; 
    	n=i+1;
    }
    

    我在源代码里还附录了一个输入模块的代码,因为那个是直接将文法输入到字符串中,这样就可减少在进行测试时重复输入文法的时间。
    即:

    //在一开始编程时可先给定文法,避免每次测试重复输入 
    void input(){
    	int i,j;
    	strcat(str[0],"Z->E");
    	strcat(str[1],"E->aA");
    	strcat(str[2],"E->bB");
    	strcat(str[3],"A->cA");
    	strcat(str[4],"A->d");
    	strcat(str[5],"B->cB");
    	strcat(str[6],"B->d");
    	n=7;
    	for(i=0;i<n;i++)
    	cout<<str[i]<<endl;
    	cout<<"***************************"<<endl;
    }
    
    1. LR(0)规范集构建模块
      进行算法分析中第2、3、4三步,记住几个关键点,小圆点位置、小圆点后的字符、项目的开辟(递归)
      当中为使测试方便,调用了几个子函数
      以下只附录子函数代码,具体请看最后源代码
      设置小圆点位置

    2. 输出模块
      将生成的项目以分析表的形式得出,因水品有限,采用的是cout结合二维数组进行输出,代码较多,主要是为了使得输出的格式更加的整齐。
      这部分就不重复贴出代码,大家请从源代码里查看。

    • 设置小圆点位置
    //为文法添加小数点 
    void AddD(int a,int b){//为LR[a]的ss第b行字符串添加'.' 
    	int i,j=0;
    	char c[10];
    	for(i=0;i<3;i++)
    	c[j++]=LR[a].ss[b][i];
    	c[3]='.';
    	j++;
    	for(i=3;i<strlen(LR[a].ss[b]);i++)
    	c[j++]=LR[a].ss[b][i];
    	memset(LR[a].ss[b],0,sizeof(LR[a].ss[b]));
    	for(i=0;i<j;i++)
    	LR[a].ss[b][i]=c[i];
    }
    
    • 添加移进项目的文法
    //添加移进项目的文法 
    void AddG(int a,char s){//把str文法中左部非终结符与s相同的文法,添加进LR[a]中 
    	int i,j,k;
    	for(i=0;i<n;i++){
    		if(str[i][0]==s){
    			for(j=0;j<strlen(str[i]);j++)
    			LR[a].ss[LR[a].count][j]=str[i][j];
    			AddD(a,LR[a].count); 
    			LR[a].count++;
    		}
    	}
    }
    
    • 小圆点后移一位
    //将文法小圆点向后移一位 
    void add(int a,int j){
    	int i,k;
    	char temp;
    	for(i=0;i<strlen(LR[a].ss[j]);i++){
    		LR[v].ss[0][i]=LR[a].ss[j][i];
    		if(LR[a].ss[j][i]=='.')
    		k=i;//记录小圆点的位置 
    	}
    	LR[a].c[j]=v;//记录该条文法的跳转(子)项数 
    	LR[v].f=a;//记录跳转项数的来源(父代) 
    	LR[v].count++;
    	temp=LR[v].ss[0][k+1];//小圆点向后移一位 
    	LR[v].ss[0][k+1]=LR[v].ss[0][k];
    	LR[v].ss[0][k]=temp;
    	LR[v].l=k+1;//记录小圆点的位置 
    }
    
    • 更新项目的上一项(父代)和下一项(子代)
    //更新某一项的来源(父代)和每一句文法的跳转项(子代) 
    void fix(int a,int b){
    	int i,j,k;
    	k=LR[b].f;//父代 
    	for(i=0;i<LR[k].count;i++)
    	if(LR[k].c[i]==b)
    	LR[k].c[i]=a;//子代 
    }
    
    • 删除相同的项目
    //比较,删除相同的内容 
    void Compare(int a){
    	int i,j,k;
    	for(i=0;i<a;i++){
    		for(j=i+1;j<=a;j++){
    			if(strcmp(LR[i].ss[0],LR[j].ss[0])==0){//若相同 
    				fix(i,j);
    				memset(LR[j].ss,0,sizeof(LR[j].ss));//靠后的文法内容清空 
    				LR[j].count=0;
    			}
    		}
    	}	
    }
    
    1. 主函数
    //主函数 
    int main(){
    	Init();;//输入上下文无关文法 
    	//input();//输入上下文无关文法 
    	gfj();//规范集的构建 
        Output();//输出分析表 
    } 
    

    5、结果展示

    1. 首先编译运行
      在这里插入图片描述
    2. 然后输入上下文无关文法,以#键结尾
      在这里插入图片描述

    3.然后回车获得结果
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    6、源代码

    源代码已经过编译,可直接使用。代码都有详细的注释,大家碰到任何问题都可以留言,一起讨论。

    #include<iostream>
    #include<iomanip>
    #include<string.h>
    using namespace std;
    
    char str[10][10];//存储文法 
    int n;//存储文法行数 
    int v=0;//存储生成项的个数 
    char r[20][10];//存储分析表的float值 
    int rr[20][10];//存储分析表的int值 
    struct DFA{
    	int num;//记录生成项的序号 
    	int  c[10];//存储该项的上一项位置 
    	int f;//记录 
    	char ss[10][10];//存储该项的文法 
    	int count;//记录该项的文法行数 
    	int l;//存储第一行字符串'.'的位置 
    }LR[20];
    
    //初始化,输入上下文无关文法,以#号结尾 
    void Init(){
    	int i,j;
    	cout<<"输入上下文无关文法:"<<endl;
    	for(i=1;;i++){
    		cin>>str[i];
    		if(str[i][0]=='#')
    		break;
    	}
    	strcat(str[0],"Z->");
    	str[0][3]=str[1][0]; 
    	n=i+1;
    }
    
    //在一开始编程时可先给定文法,避免每次测试重复输入 
    void input(){
    	int i,j;
    	strcat(str[0],"Z->E");
    	strcat(str[1],"E->aA");
    	strcat(str[2],"E->bB");
    	strcat(str[3],"A->cA");
    	strcat(str[4],"A->d");
    	strcat(str[5],"B->cB");
    	strcat(str[6],"B->d");
    	n=7;
    	for(i=0;i<n;i++)
    	cout<<str[i]<<endl;
    	cout<<"***************************"<<endl;
    }
    
    //为文法添加小数点 
    void AddD(int a,int b){//为LR[a]的ss第b行字符串添加'.' 
    	int i,j=0;
    	char c[10];
    	for(i=0;i<3;i++)
    	c[j++]=LR[a].ss[b][i];
    	c[3]='.';
    	j++;
    	for(i=3;i<strlen(LR[a].ss[b]);i++)
    	c[j++]=LR[a].ss[b][i];
    	memset(LR[a].ss[b],0,sizeof(LR[a].ss[b]));
    	for(i=0;i<j;i++)
    	LR[a].ss[b][i]=c[i];
    }
    
    //添加移进项目的文法 
    void AddG(int a,char s){//把str文法中左部非终结符与s相同的文法,添加进LR[a]中 
    	int i,j,k;
    	for(i=0;i<n;i++){
    		if(str[i][0]==s){
    			for(j=0;j<strlen(str[i]);j++)
    			LR[a].ss[LR[a].count][j]=str[i][j];
    			AddD(a,LR[a].count); 
    			LR[a].count++;
    		}
    	}
    }
    
    //将文法小圆点向后移一位 
    void add(int a,int j){
    	int i,k;
    	char temp;
    	for(i=0;i<strlen(LR[a].ss[j]);i++){
    		LR[v].ss[0][i]=LR[a].ss[j][i];
    		if(LR[a].ss[j][i]=='.')
    		k=i;//记录小圆点的位置 
    	}
    	LR[a].c[j]=v;//记录该条文法的跳转(子)项数 
    	LR[v].f=a;//记录跳转项数的来源(父代) 
    	LR[v].count++;
    	temp=LR[v].ss[0][k+1];//小圆点向后移一位 
    	LR[v].ss[0][k+1]=LR[v].ss[0][k];
    	LR[v].ss[0][k]=temp;
    	LR[v].l=k+1;//记录小圆点的位置 
    }
    
    //更新某一项的来源(父代)和每一句文法的跳转项(子代) 
    void fix(int a,int b){
    	int i,j,k;
    	k=LR[b].f;//父代 
    	for(i=0;i<LR[k].count;i++)
    	if(LR[k].c[i]==b)
    	LR[k].c[i]=a;//子代 
    }
    
    //比较,删除相同的内容 
    void Compare(int a){
    	int i,j,k;
    	for(i=0;i<a;i++){
    		for(j=i+1;j<=a;j++){
    			if(strcmp(LR[i].ss[0],LR[j].ss[0])==0){//若相同 
    				fix(i,j);
    				memset(LR[j].ss,0,sizeof(LR[j].ss));//靠后的文法内容清空 
    				LR[j].count=0;
    			}
    		}
    	}	
    }
    
    //LR(0)规范集的构建
    void gfj(){
    	int i,j,k,p;
    	for(i=0;i<20;i++){
    		LR[i].num=i;//Ii
    		if(i==0){//第一个,赋予文法的初始符Z->E 
    			for(k=0;k<strlen(str[0]);k++)
    			LR[0].ss[0][k]=str[0][k];
    			AddD(0,LR[0].count);//添加小圆点 Z->.E 
    			LR[0].l=3;//小圆点的位置 
    			LR[0].count++;//文法数目+1		
    	    	if(LR[i].ss[0][4]>='A'&&LR[i].ss[0][4]<'Z') 
    	    	AddG(i,LR[i].ss[0][4]);//添加移进项目的文法E->aA E->bB
    	    	v++;
                //为每一个文法进行向外扩散 I1、I2、I3 
    	    	for(j=0;j<LR[0].count;j++){
    	    		p=strlen(LR[0].ss[j]);
    		    	if(LR[0].ss[j][p-1]!='.'){
    		    		add(0,j);//将向外扩散的文法小圆点向后移一位 
    		    		v++;
    		    	}
    	    	}
    		}
        	else{//除I0以外的生成项 
        		p=strlen(LR[i].ss[0]);//Ii第一句文法的长度 
        		if(LR[i].count==1&&LR[i].ss[0][p-1]=='.'){//若小圆点再最后则不进行处理 
        	    }
        		else{
    	        	p=LR[i].l;//小圆点的位置 
    	        	if(LR[i].ss[0][p+1]>='A'&&LR[i].ss[0][p+1]<'Z')
    	        	AddG(i,LR[i].ss[0][p+1]);//添加移进项目的文法
    	            //为每一个文法进行向外扩散 
    	        	for(j=0;j<LR[i].count;j++){
    	        		add(i,j);//将待向外扩散的文法小圆点向后移一位 
    	        		v++;
    	            }
    	            
    	        }
                Compare(i);//对所有已生成的项进行比较,若有重复的则删除i值靠后的 
    		}
    	}
        //将生成的项进行整理,补齐有缺的部分(删除重复的之后可能会有内容为空,从后面补齐) 
        for(i=0;i<20;i++){
        	for(j=i+1;j<20;j++){
        		if(LR[i].count==0&&LR[j].count!=0&&LR[i].num<LR[j].num){
        			fix(i,j);
        			LR[i]=LR[j];
        			LR[j].count=0;    			
    			}
    		}
    	}
    	//对当前的生成项进行编号 
    	for(i=0;LR[i].count!=0;)
    	i++;
    	v=i;
    	//输出当前生成项及各项的文法 
    	cout<<"各项的序号和文法内容:"<<endl;
    	for(i=0;i<v;i++){
        	cout<<i<<":"<<endl;
        	for(j=0;j<LR[i].count;j++)
        	cout<<LR[i].ss[j]<<endl;
            cout<<endl;
        }  
    } 
    
     
    //分析表根据第一行进行匹配处理 
    void match(int a,int b){
    	int i,j;
    	char k;
    	if(b==0&&LR[a].count==1&&strlen(LR[a].ss[b])-1==LR[a].l){//若是终结文法 (即小圆点在最后) 
    		if(LR[a].ss[b][0]=='Z')//且是初始符终结 
        	strcpy(r[a+1],"acc");
        	else
    		for(i=0;i<5;i++)//Action都输出r 
    		r[a+1][i]='r';
    	}
        else{//不是终结文法,k储存小圆点后一个字符,进行比较判断 
        	if(b==0)
        	k=LR[a].ss[b][LR[a].l+1];
        	else
        	k=LR[a].ss[b][4];
        	for(i=0;i<strlen(r[0]);i++){
        		if(r[0][i]==k)
        		rr[a+1][i]=LR[a].c[b];
        	}
    	}
    }
     
    //进行分析表的构建和输出 
    void Output(){
    	int i,j,k,temp;
    	strcpy(r[0],"abcd#EAB");//分析表的第一行 
    	cout<<"LR0分析表:"<<endl;
    	cout<<setw(20)<<"Action"<<setw(18)<<"Goto"<<endl; 
    	//分析表根据第一行进行匹配 
        for(i=0;i<v;i++){
        	for(j=0;j<LR[i].count;j++)
        	match(i,j);//进行匹配处理 
    	}
    	//进行分析表输出形式的处理 
    	for(i=0;i<v+1;i++){
    		temp=0;
    		//保证输出对其 
    		if(i==0)
    		cout<<"   ";
            if(i>0&&i<=10)
        	cout<<" "<<i-1<<":";
        	if(i>10)
        	cout<<i-1<<":";
        	if(strcmp(r[i],"acc")==0)
        	cout<<setw(24);
        	//先输出Action部分 
    		for(j=0;j<5;j++){
    		    if(r[i][j]=='r'){//输出终结文法 
        	    	cout<<setw(4)<<r[i][j]<<k;
        	    	temp=1;
        	    }
        	    else if(strcmp(r[i],"acc")==0)//输出起始符的终结欸文法 
        	    cout<<r[i][j];
    	    	else{ 
    	    		if(i==0)
        	    	cout<<setw(5)<<r[i][j];
        	    	else if(rr[i][j]==0)
        	    	cout<<setw(5)<<" ";
        	    	else
        	    	cout<<setw(4)<<"S"<<rr[i][j];
        	    }
    	    }
    	    if(temp==1)
    	    k++;//进行对r1、r2、r3等下标的处理 
    	    //再输出Goto部分 
    		for(j=5;j<strlen(r[0]);j++){
    			if(i==0)
        	    cout<<setw(5)<<r[i][j];
        	    else if(rr[i][j]==0)
        	    cout<<setw(5)<<" ";
        	    else
        	    cout<<setw(5)<<rr[i][j];
    		}
    		cout<<endl;
    	}
    }
    
    //主函数 
    int main(){
    	int i,j;
    	Init();
    	//input();//输入上下文无关文法 
    	gfj();//规范集的构建 
    	//Excels();
        Output();//输出分析表 
    } 
    

    在这里插入图片描述

    展开全文
  • 1、PLSQL复制 create table T_DJ_NSRXX_bf as select * from T_DJ_NSRXX 2、将一张插入另一张中 方式一: insert into b select * from a 方式二: insert into b (字段1,字段2) select 字段1,字段2 ...

    1、PLSQL下复制表

    create table T_DJ_NSRXX_bf as select * from T_DJ_NSRXX

    2、将一张表插入另一张表中

    方式一:
    insert into b select * from a
    方式二:
    insert into b (字段1,字段2) select 字段1,字段2  from a
    3、连接两张表,包含所有字段结构
    create table XX as select * from  t1,t2  where 1=0;

    展开全文
  • 史上最全ASCII码对照表0-255(%d)

    万次阅读 多人点赞 2018-08-29 10:28:09
    十进制代码 十六进制代码 MCS 字符或缩写 DEC 多国字符名 ... 0 0 NUL 空字符 1 1 SOH 标...

    十进制代码

    十六进制代码

    MCS 字符或缩写

    DEC 多国字符名

    ASCII 控制字符 1

    0

    0

    NUL

    空字符

    1

    1

    SOH

    标题起始 (Ctrl/A)

    2

    2

    STX

    文本起始 (Ctrl/B)

    3

    3

    ETX

    文本结束 (Ctrl/C)

    4

    4

    EOT

    传输结束 (Ctrl/D)

    5

    5

    ENQ

    询问 (Ctrl/E)

    6

    6

    ACK

    认可 (Ctrl/F)

    7

    7

    BEL

    铃 (Ctrl/G)

    8

    8

    BS

    退格 (Ctrl/H)

    9

    9

    HT

    水平制表栏 (Ctrl/I)

    10

    0A

    LF

    换行 (Ctrl/J)

    11

    0B

    VT

    垂直制表栏 (Ctrl/K)

    12

    0C

    FF

    换页 (Ctrl/L)

    13

    0D

    CR

    回车 (Ctrl/M)

    14

    0E

    SO

    移出 (Ctrl/N)

    15

    0F

    SI

    移入 (Ctrl/O)

    16

    10

    DLE

    数据链接丢失 (Ctrl/P)

    17

    11

    DC1

    设备控制 1 (Ctrl/Q)

    18

    12

    DC2

    设备控制 2 (Ctrl/R)

    19

    13

    DC3

    设备控制 3 (Ctrl/S)

    20

    14

    DC4

    设备控制 4 (Ctrl/T)

    21

    15

    NAK

    否定接受 (Ctrl/U)

    22

    16

    SYN

    同步闲置符 (Ctrl/V)

    23

    17

    ETB

    传输块结束 (Ctrl/W)

    24

    18

    CAN

    取消 (Ctrl/X)

    25

    19

    EM

    媒体结束 (Ctrl/Y)

    26

    1A

    SUB

    替换 (Ctrl/Z)

    27

    1B

    ESC

    换码符

    28

    1C

    FS

    文件分隔符

    29

    1D

    GS

    组分隔符

    30

    1E

    RS

    记录分隔符

    31

    1F

    US

    单位分隔符

    ASCII 特殊和数字字符

    32

    20

    SP

    空格

    33

    21

    !

    感叹号

    34

    22

    "

    引号 (双引号)

    35

    23

    #

    数字符号

    36

    24

    $

    美元符

    37

    25

    %

    百分号

    38

    26

    &

    和号

    39

    27

    '

    省略号 (单引号)

    40

    28

    (

    左圆括号

    41

    29

    )

    右圆括号

    42

    2A

    *

    星号

    43

    2B

    +

    加号

    44

    2C

    ,

    逗号

    45

    2D

    --

    连字号或减号

    46

    2E

    .

    句点或小数点

    47

    2F

    /

    斜杠

    48

    30

    0

    49

    31

    1

    1

    50

    32

    2

    2

    51

    33

    3

    3

    52

    34

    4

    4

    53

    35

    5

    5

    54

    36

    6

    6

    55

    37

    7

    7

    56

    38

    8

    8

    57

    39

    9

    9

    58

    3A

    :

    冒号

    59

    3B

    ;

    分号

    60

    3C

    <

    小于

    61

    3D

    =

    等于

    62

    3E

    >

    大于

    63

    3F

    ?

    问号

    ASCII 字母字符

    64

    40

    @

    商业 at 符号

    65

    41

    A

    大写字母 A

    66

    42

    B

    大写字母 B

    67

    43

    C

    大写字母 C

    68

    44

    D

    大写字母 D

    69

    45

    E

    大写字母 E

    70

    46

    F

    大写字母 F

    71

    47

    G

    大写字母 G

    72

    48

    H

    大写字母 H

    73

    49

    I

    大写字母 I

    74

    4A

    J

    大写字母 J

    75

    4B

    K

    大写字母 K

    76

    4C

    L

    大写字母 L

    77

    4D

    M

    大写字母 M

    78

    4E

    N

    大写字母 N

    79

    4F

    O

    大写字母 O

    80

    50

    P

    大写字母 P

    81

    51

    Q

    大写字母 Q

    82

    52

    R

    大写字母 R

    83

    53

    S

    大写字母 S

    84

    54

    T

    大写字母 T

    85

    55

    U

    大写字母 U

    86

    56

    V

    大写字母 V

    87

    57

    W

    大写字母 W

    88

    58

    X

    大写字母 X

    89

    59

    Y

    大写字母 Y

    90

    5A

    Z

    大写字母 Z

    91

    5B

    [

    左中括号

    92

    5C

    \

    反斜杠

    93

    5D

    ]

    右中括号

    94

    5E

    ^

    音调符号

    95

    5F

    _

    下划线

    96

    60

    `

    重音符

    97

    61

    a

    小写字母 a

    98

    62

    b

    小写字母 b

    99

    63

    c

    小写字母 c

    100

    64

    d

    小写字母 d

    101

    65

    e

    小写字母 e

    102

    66

    f

    小写字母 f

    103

    67

    g

    小写字母 g

    104

    68

    h

    小写字母 h

    105

    69

    i

    小写字母 i

    106

    6A

    j

    小写字母 j

    107

    6B

    k

    小写字母 k

    108

    6C

    l

    小写字母 l

    109

    6D

    m

    小写字母 m

    110

    6E

    n

    小写字母 n

    111

    6F

    o

    小写字母 o

    112

    70

    p

    小写字母 p

    113

    71

    q

    小写字母 q

    114

    72

    r

    小写字母 r

    115

    73

    s

    小写字母 s

    116

    74

    t

    小写字母 t

    117

    75

    u

    小写字母 u

    118

    76

    v

    小写字母 v

    119

    77

    w

    小写字母 w

    120

    78

    x

    小写字母 x

    121

    79

    y

    小写字母 y

    122

    7A

    z

    小写字母 z

    123

    7B

    {

    左大括号

    124

    7C

    |

    垂直线

    125

    7D

    }

    右大括号 (ALTMODE)

    126

    7E

    ~

    代字号 (ALTMODE)

    127

    7F

    DEL

    擦掉 (DELETE)

    控制字符

    128

    80

     

    [保留]

    129

    81

     

    [保留]

    130

    82

     

    [保留]

    131

    83

     

    [保留]

    132

    84

    IND

    索引

    133

    85

    NEL

    下一行

    134

    86

    SSA

    被选区域起始

    135

    87

    ESA

    被选区域结束

    136

    88

    HTS

    水平制表符集

    137

    89

    HTJ

    对齐的水平制表符集

    138

    8A

    VTS

    垂直制表符集

    139

    8B

    PLD

    部分行向下

    140

    8C

    PLU

    部分行向上

    141

    8D

    RI

    反向索引

    142

    8E

    SS2

    单移 2

    143

    8F

    SS3

    单移 3

    144

    90

    DCS

    设备控制字符串

    145

    91

    PU1

    专用 1

    146

    92

    PU2

    专用 2

    147

    93

    STS

    设置传输状态

    148

    94

    CCH

    取消字符

    149

    95

    MW

    消息等待

    150

    96

    SPA

    保护区起始

    151

    97

    EPA

    保护区结束

    152

    98

     

    [保留]

    153

    99

     

    [保留]

    154

    9A

     

    [保留]

    155

    9B

    CSI

    控制序列引导符

    156

    9C

    ST

    字符串终止符

    157

    9D

    OSC

    操作系统命令

    158

    9E

    PM

    秘密消息

    159

    9F

    APC

    应用程序

    其他字符

    160

    A0

     

    [保留] 2

    161

    A1

    ¡

    反向感叹号

    162

    A2

    ¢

    分币符

    163

    A3

    £

    英磅符

    164

    A4

     

    [保留] 2

    165

    A5

    ¥

    人民币符

    166

    A6

     

    [保留] 2

    167

    A7

    §

    章节符

    168

    A8

    ¤

    通用货币符号 2

    169

    A9

    ©

    版权符号

    170

    AA

    ª

    阴性顺序指示符

    171

    AB

    «

    左角引号

    172

    AC

     

    [保留] 2

    173

    AD

     

    [保留] 2

    174

    AE

     

    [保留] 2

    175

    AF

     

    [保留] 2

    176

    B0

    °

    温度符

    177

    B1

    ±

    加/减号

    178

    B2

    ²

    上标 2

    179

    B3

    ³

    上标 3

    180

    B4

     

    [保留] 2

    181

    B5

    µ

    微符

    182

    B6

    段落符,pilcrow

    183

    B7

    ·

    中点

    184

    B8

     

    [保留] 2

    185

    B9

    ¹

    上标 1

    186

    BA

    º

    阳性顺序指示符

    187

    BB

    »

    右角引号

    188

    BC

    ¼

    分数四分之一

    189

    BD

    ½

    分数二分之一

    190

    BE

     

    [保留] 2

    191

    BF

    ¿

    反向问号

    192

    C0

    À

    带重音符的大写字母 A

    193

    C1

    Á

    带尖锐重音的大写字母 A

    194

    C2

    Â

    带音调符号的大写字母 A

    195

    C3

    Ã

    带代字号的大写字母 A

    196

    C4

    Ä

    带元音变音 (分音符号) 的大写字母 A

    197

    C5

    Å

    带铃声的大写字母 A 

    198

    C6

    Æ

    大写字母 AE 双重元音

    199

    C7

    Ç

    带变音符号的大写字母 C

    200

    C8

    È

    带重音符的大写字母 E 

    201

    C9

    É

    带尖锐重音的大写字母 E 

    202

    CA

    Ê

    带音调符号的大写字母 E 

    203

    CB

    Ë

    带元音变音 (分音符号) 的大写字母 E

    204

    CC

    Ì

    带重音符的大写字母 I 

    205

    CD

    Í

    带尖锐重音的大写字母 I 

    206

    CE

    Î

    带音调符号的大写字母 I 

    207

    CF

    Ï

    带元音变音 (分音符号) 的大写字母 I

    208

    D0

     

    [保留] 2

    209

    D1

    Ñ

    带代字号的大写字母 N 

    210

    D2

    Ò

    带重音符的大写字母 O  

    211

    D3

    Ó

    带尖锐重音的大写字母 O 

    212

    D4

    Ô

    带音调符号的大写字母 O  

    213

    D5

    Õ

    带代字号的大写字母 O  

    214

    D6

    Ö

    带元音变音 (分音符号) 的大写字母 O

    215

    D7

    OE

    大写字母 OE 连字 2

    216

    D8

    Ø

    带斜杠的大写字母 O 

    217

    D9

    Ù

    带重音符的大写字母 U 

    218

    DA

    Ú

    带尖锐重音的大写字母 U 

    219

    DB

    Û

    带音调符号的大写字母 U 

    220

    DC

    Ü

    带元音变音 (分音符号) 的大写字母 U

    221

    DD

    Y

    带元音变音 (分音符号) 的大写字母 Y

    222

    DE

     

    [保留] 2

    223

    DF

    ß

    德语高调小写字母 s

    224

    E0

    à

    带重音符的小写字母 a 

    225

    E1

    á

    带尖锐重音的小写字母 a 

    226

    E2

    â

    带音调符号的小写字母 a 

    227

    E3

    ã

    带代字号的小写字母 a 

    228

    E4

    ä

    带元音变音 (分音符号) 的小写字母 a

    229

    E5

    å

    带铃声的小写字母 a 

    230

    E6

    æ

    小写字母 ae 双重元音

    231

    E7

    ç

    带变音符号的小写字母 c

    232

    E8

    è

    带重音符的小写字母 e 

    233

    E9

    é

    带尖锐重音的小写字母 e 

    234

    EA

    ê

    带音调符号的小写字母 e 

    235

    EB

    ë

    带元音变音 (分音符号) 的小写字母 e

    236

    EC

    ì

    带重音符的小写字母 i 

    237

    ED

    í

    带尖锐重音的小写字母 i 

    238

    EE

    î

    带音调符号的小写字母 i 

    239

    EF

    ï

    带元音变音 (分音符号) 的小写字母 i

    240

    F0

     

    [保留] 2

    241

    F1

    ñ

    带代字号的小写字母 n 

    242

    F2

    ò

    带重音符的小写字母 o 

    243

    F3

    ó

    带尖锐重音的小写字母 o 

    244

    F4

    ô

    带音调符号的小写字母 o 

    245

    F5

    õ

    带代字号的小写字母 o 

    246

    F6

    ö

    带元音变音 (分音符号) 的小写字母 o

    247

    F7

    oe

    小写字母 oe 连字 2

    248

    F8

    ø

    带斜杠的小写字母 o 

    249

    F9

    ù

    带重音符的小写字母 u 

    250

    FA

    ú

    带尖锐重音的小写字母 u 

    251

    FB

    û

    带音调符号的小写字母 u 

    252

    FC

    ü

    带元音变音 (分音符号) 的小写字母 u

    253

    FD

    ÿ

    带元音变音 (分音符号) 的小写字母 y 2

    254

    FE

     

    [保留] 2

    255

    FF

     

    [保留] 2

    展开全文
  • MySQL对数据已有进行分区

    万次阅读 2017-02-25 18:41:16
    对现有的一个进行创建分区,并把数据迁移到新,可以按时间来分区,然后这不是实时更新,每天有一次插入操作。 时间比较充裕,但是服务器上有其他应用,使用较小资源为主要方式。 操作方式@1 可以使用ALTER...
  • 邻接

    万次阅读 多人点赞 2019-08-27 17:06:30
    邻接 我们发现,当图中的边数相对于顶点较少时,邻接矩阵是对存储空间的极大浪费。我们可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题。回忆树结构的孩子表示法,将结点存入数组,并对结点的孩子进行...
  • 广义的表头表尾

    万次阅读 2019-07-26 12:07:38
    把好久之前的C语言的知识记录整理发送 广义 表头表尾 head() 返回列表的第一个元素; tail() 返回列表的删去第一个元素之后的剩余列表; 已知广义: A=(a,b), B=(A,A), C=(a,(b,A),B), 求下列运算的结果: ...
  • LR(0)和SLR分析的构造

    万次阅读 2016-05-24 18:58:01
    LR(0)和SLR分析的构造 上篇文章中,我已经说到了,LR(0)分析是LR(0)分析器的重要组成部分,它是总控程序分析动作的依据,他是由LR(0)项目集规范族来进行 构造的。他的结构主要有两个部分ACTION 和GOTO    ...
  • Greenplum是关系型的分布式数据库,需要存储的...本篇介绍查询某模式所有的分布键信息,适用于: 排查是否有分布键创建不合理的,如果分布键是重复率比较高的字段会造成数据分布不均匀,存储过于倾斜。 ...
  • mysql将中某字段null转变为0

    千次阅读 2019-05-05 17:22:54
    SQL: update table tb set tb.column= '0' WHERE tb.column IS NULL 备注(remark): table : 表名 column: 字段列 tb:别名 喜欢请点赞:
  • 基于51单片机的直流数字电压0-5V)

    千次阅读 多人点赞 2016-06-22 17:21:55
    基于51单片机的直流数字电压0-5V) 利用串行A/D转换器TLC549对输入信号电压源进行采集转换成数字信号给51单片机,经单片机进行数据处理后给1602液晶显示。 误差小于1%. #include #include #define uint ...
  • 广义

    万次阅读 多人点赞 2018-03-08 15:51:08
    一个广义是n(n≥0)个元素的一个序列,若n=0时则称为空。设ai为广义的第i个元素,则广义GL的一般表示与线性表相同: GL=(a1,a2,…,ai,…,an)其中n表示广义的长度,即广义中所含元素的个数,n≥0。如果...
  • ASCII码表

    万次阅读 多人点赞 2018-07-08 17:54:06
    ASCII码大致由三部分组成:1、ASCII 打印字符:数字 32...下面是ASCII码和相应数字的对照: 2、ASCII 非打印控制字符:ASCII 上的数字 0–31 分配给了控制字符,用于控制像打印机等一些外围设备。例如,12 代表...
  • Hive查看占用空间大小的方法

    万次阅读 2018-05-18 15:23:36
    一、Hive查看数据信息的方法方法1:查看的字段信息desc table_name;方法2:查看的字段信息及元数据存储路径desc extended table_name;方法3:查看的字段信息及元数据存储路径desc formatted table_name;...
  • MySQL临时与内存

    千次阅读 2019-01-13 12:03:18
    在MySQL中有三种虚拟:临时、内存、视图。下面简单介绍一下临时和内存的使用。 1、临时 MySQL临时在我们需要保存一些临时数据时是非常有用的。临时在MySQL 3.23版本中添加。临时只在当前连接...
  • Oracle 导入导出

    千次阅读 2018-04-28 00:25:56
    导出整个数据库实例的所有数据2.导出指定用户的所有3.导出指定。打开命令行:1,将数据库ORACLE完全导出,用户名system密码manager 导出到c:\daochu.dmp中exp system/manager@ORACLE file=c:\daochu.dmp ...
  • 编译原理根据项目集规范族构造LR(0)分析

    千次阅读 多人点赞 2018-01-14 19:45:30
    本文主要讲LR(0)分析的构造和输入串分析过程。 我这个菜鸡都觉得是通!俗!易!懂!的!! 憋说话往看-> 多的不扯,博(cai)主(ji)我使用的是清华大学出版社的《编译原理第二版》,第二版哦,不知道第三版
  • hive信息查询:查看结构、操作等
  • 中间 临时

    千次阅读 2015-06-16 17:16:17
    今天碰到个需求,需要查询所有级别的医院,看了,分别是 机构类型类(t_OrgType) 机构类(t_Organ) 多对多的关系, 以及中间 机构类型关系类(t_OrgTypeRelation) ,在此对中间的概念做一个总结,下面...
  • 0、查看用户、索引、分区占用空间 select segment_name, sum(bytes)/1024/1024 Mbytese from user_segments group by segment_name; 1、占用空间 select segment_name, sum(bytes)/1024/1024 Mbytese from
  • linux下表空间相关查询及操作

    千次阅读 2017-05-24 11:19:24
    /*查询空间相关信息 */ ...select t.tablespace_name,round(sum(bytes/(1024*1024)),0) ts_size  from dba_tablespaces t, dba_data_files d where t.tablespace_name = d.tablespace_name  group by t.
  • LINUXARP操作

    万次阅读 2012-03-07 16:10:36
    Linux操作ARP项  ARP缓存arp_tbl由协议栈在运行期间自动维护,包括邻居新建,更新,回收等。同时,TCP/IP协议栈的实现中也提供了三个命令,可以用来由用户维护arp_tbl,这三个命令分别是SIOCDARP(删除...
  • 字典

    万次阅读 多人点赞 2018-08-09 09:37:44
    本篇的字典主要针对前端展示多层目录数据的一个设计。 相信我们在金山毒霸上看电影时,会有很多电影分类,可以更具国家的不同,年限的不同亦或电影种类的不同去查询自己想要看的电影类型,那么这么多分类在设计...
  • 当你打开ArcGIS属性,对矢量进行面积或其他计算时,发现如图所示问题,兄弟莫方...........,接下来用两种方法保证你满意。   主要方法: 一、设置系统时间。 二、字段属性设置。 具体操作: 一、(1) ...
  • oracle 导出某个用户所有数据

    万次阅读 2018-09-07 09:26:30
    1:如果要导入的用户有空,需要执行下面语句 select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0 查询出的数据拷出来,再次执行 2:cmd进入命令,导出 导出用户...
  • cmap

    千次阅读 2012-06-07 22:48:31
    原文地址: https://developer.apple.com/fonts/ttrefman/rm06/chap6cmap.html#Surrogates总cmap将字符编码映射为 glyph (即字符点阵图)的...因此cmap会包含多个“子”,每个子支持一种编码方案。如果该字
  • hive内部,外部,分区,桶
  • 用unity来写 二维数组编写程序定义一个二维数组arr,该数组一共有4行3列,如下表所示,请把下表中的所有对应数据利用赋值语句赋值到该二维数组arr中去arr 第0列第1列第2列第0行第1行第2行第3行编写程序依次把第2行第...
  • oracle导出数据库时,当某个为记录为空时,就会报EXP-00003: 未找到段 (0,0) 的存储定义 ,同时这个不会被导出。 原因:  Oracle 11G在用EXPORT导出时,空不能导出.  11GR2中有个新特性,当无数据时,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,475,199
精华内容 990,079
关键字:

下表0