自底向上语法分析(bottom-up parsing)

news2025/2/21 3:58:42

自底向上语法分析(bottom-up parsing)

  • 自底向上分析概述
  • LR分析概述
  • LR(0)分析
    • 增广文法
    • 点标记
    • 项目
    • LR(0)分析表
    • CLOSURE函数
    • GOTO函数
    • LR(0)自动机的状态集
    • LR(0)分析表构造算法
    • LR(0)自动机的形式化定义
    • LR(0)分析的冲突问题
  • SLR分析
    • SLR算法的关键
    • SLR分析的冲突问题
  • LR(1)分析
    • 规范LR(1)项目
    • 等价LR(1)项目
    • 同心项目集
    • CLOSURE函数
    • GOTO函数
    • 文法G' 构造LR(1)项集族
    • LR(1)分析表的构造算法
  • LALR分析

在自顶向下语法分析(top-down parsing) 中介绍了一种自顶向上语法分析法——LL(1)分析法,但它存在两个问题:

  • 能够分析的文法有限;
  • 很多时候需要进行文法转换。

为此,将介绍一种使用更加广泛的自底向上语法分析法——LR分析法。这也是当前实际运用最广泛的一种语法分析方法。

本文主要是对 哈工大编译原理课件 的学习和总结。

自底向上分析概述

自底向上语法分析是从分析树的底部(叶子节点)向顶部根节点方向构造分析树,也即是将输入串归约为文法开始符号的过程。自顶向下的语法分析是采用最左推导方式,而自底向上的语法分析是采用最左归约方式,其实就是反向构造最右推导

自顶向上语法分析的通用框架是:移入-规约分析(Shift-Reduce Parsing)。下面通过一个例子来介绍移入-规约分析的算法思想。

移动-规约分析法的大致过程为:

  • 对输入串的一次从左到右扫描过程中,将零个或多个输入符号移入到栈的顶端,直到它可以对栈顶的一个文法符号串 β 进行归约为止。
  • 然后,将 β 归约为某个产生式的左部(使用左部的非终结符替换 β )。
  • 不断地重复上面的循环,直到它检测到一个语法错误或者栈中包含了开始符号且输入缓冲区为空为止。

移入-规约语法分析过程中的四个动作:

  • 移入:将下一个输入符号移入到栈顶。
  • 归约:被归约的符号串的右端必然处于栈顶。语法分析器在栈中确定这个串的左端,并决定用哪个非终结符来替换这个串。
  • 接收:语法分析过程成功完成。
  • 报错:发现一个语法错误,并调用错误恢复子例程。

如何正确地识别句柄是移动-规约分析法的关键问题。

LR分析概述

LR文法是最大的、可以构造出相应移入-归约语法分析器的文法类。

  • L:输入串进行从左(Left)到右的扫描;
  • R:反向(Reverse)构造出一个最右推导序列;

LR(k)分析表示需要向前查看 k 个输入符号的LR分析。k = 0 和 k = 1 这两种情况具有实践意义。当(k)省略时,表示k =1。

自底向上分析的关键问题是如何正确识别句柄,句柄是逐步形成的,LR分析法用“状态”表示句柄识别的进展程度。LR分析法的总体结构为:

LR分析器使用自动机的机制,通过读头读入输入串,根据输入串查询动作表和转移表(统称LR分析表),将符号和状态压栈或出栈的过程完成语法分析。动作表和转移表是LR分析法的关键。LR分析算法如下:

  • 输入:串w和LR分析表,该表描述了文法G的ACTION函数和GOTO函数。
  • 输出:如果w在L(G)中,则输出w的自底向上语法分析过程中的归约步骤,否则给出一个错误指示。
  • 方法:初始时,语法分析器栈中的内容为初始状态 s 0 s_0 s0 ,输入缓冲区中的内容为w$。然后,语法分析器执行下面的程序:
令a为w$的第一个符号;
while(1) { /* 永远重复*/
  令s是栈顶的状态;
  if ( ACTION[s,a] = st ) {
    将t压入栈中;
    令a为下一个输入符号;
  } else if ( ACTION[s,a] = 归约A → β ) {
    从栈中弹出│β│个符号;
    将GOTO[t,A]压入栈中;
    输出产生式 A → β ;
  } else if ( ACTION[s,a] = 接受 ) break; /* 语法分析完成*/
  else调用错误恢复例程;
}

LR分析算法的关键过程:

下面通过一个例子介绍LR分析法的工作过程:

对于上面的文法和LR分析表,输入串 bab ,LR分析其工作过程如下:

	             输入           栈        剩余输入             操作
	初始化                      0                       
	            b a b          $         bab$
---------------------------------------------------------------------------
	             输入           栈        剩余输入             备注
	迭代一                      04                       ACTION[0,b]=s4    
	            b a b          $b         ab$
---------------------------------------------------------------------------    
	             输入           栈        剩余输入             备注
	迭代二       B              02                       ACTION[4,a]=r3
	            |              $B         ab$           B→b
	            b a b                                   GOTO[0,B]=2
---------------------------------------------------------------------------      
	             输入           栈        剩余输入             备注
	迭代三       B              023                      ACTION[2,a]=s3
	            |              $Ba         b$
	            b a b
---------------------------------------------------------------------------           
	             输入           栈        剩余输入             备注
	迭代四       B              0234                     ACTION[3,b]=s4
	            |              $Bab         $
	            b a b
---------------------------------------------------------------------------    
	             输入           栈        剩余输入             备注
	迭代五       B   B          0236                      ACTION[4,$]=r3
	            |   |          $BaB         $            B→b
	            b a b                                    GOTO[3,B]=6
---------------------------------------------------------------------------    
	             输入           栈        剩余输入             备注
	              B            025                       ACTION[6,$]=r2
	              | \          $BB          $            B→aB
	迭代六       B | B                                    GOTO[2,B]=5
	            | | |          
	            b a b
--------------------------------------------------------------------------       
	             输入           栈        剩余输入             备注
	            S                                        ACTION[5,$]=r1
	            |\                                       S→BB
	            | B            01                        GOTO[0,S]=1
	            | | \          $S          $
	迭代七       B | B                           
	            | | |          
	            b a b
---------------------------------------------------------------------------               
	             输入           栈        剩余输入            备注
	            S                                        ACTION[1,$]=acc
	            |\  
	            | B            01
	            | | \          $S          $
	迭代八       B | B                           
	            | | |          
	            b a b
--------------------------------------------------------------------------        

上面的例子很好地描述了LR分析器的过程。接下来,如何构建LR分析表成了LR分析的关键。

LR(0)分析

增广文法

对于下面的算术表达式文法G:

// G
1)  E → E + T
2)  E → T
3)  T → T * F
4)  T → F
5)  F → ( E )
6)  F → id

这个文法G中,起始符号 E 出现在多个产生式的左部(1、2),会使得分析器有多个接收状态。

为了解决这个问题,在 G 中新增一个起始符号 S’ 和产生式 S’→S,称为 G 的增广文法(Augmented Grammar) G’,使得开始符号仅出现在一个产生式的左部,从而使得分析器只有一个接受状态。

G 的增广文法 G’ 为:

// G'
0)  E'→ E
1)  E → E + T
2)  E → T
3)  T → T * F
4)  T → F
5)  F → ( E )
6)  F → id

点标记

为了标记语法分析器已经读入了多少输入,引入一个点标记 ·

例如: E + 3 · * 4。· 前面的表示已经读入串,· 后面表示剩余读入串。

项目

项目(Item):右部某位置标有圆点的产生式称为相应文法的一个项目。例如: A → α 1 ⋅ α 2 A \rightarrow \alpha_1·\alpha_2 Aα1α2。产生式 A → ε A\rightarrowε Aε 只生成一个项目 A → ⋅ A \rightarrow · A。项目描述了句柄的识别状态。

后继项目 (Successive Item):同属于一个产生式的项目,但圆点的位置只相差一个符号,则称后者是前者的后继项目,例如: A → α ⋅ X β A \rightarrow α· Xβ Aα 的后继项目是 A → α X ⋅ β A \rightarrow αX·β AαXβ

这个例子中,标有相同彩色标记的项目(如0、2)属于一个项目集闭包,也是自动机的一个状态。

LR(0)分析表

很容易将上述文法的项目集转换为LR(0)自动机和LR(0)分析表:

CLOSURE函数

根据项目集等价的含义,很容计算给定项目集 I I I C L O S U R E CLOSURE CLOSURE 函数:

C L O S U R E ( I ) = I ∪ { B → ⋅ γ   ∣   A → α ⋅ B β ∈ C L O S U R E ( I ) , B → γ ∈ P } CLOSURE( I ) = I∪ \{B→ · γ \ | \ A→α·Bβ∈CLOSURE( I ) , B→γ∈P\} CLOSURE(I)=I{Bγ  AαCLOSURE(I),BγP}

SetOfltems CLOSURE ( I ) {
  J = I;
  repeat
    for ( J中的每个项A → α·Bβ )
      for ( G的每个产生式 B → γ )
        if ( 项B → · γ 不在J中 )
          将 B → · γ 加入J中;
  until 在某一轮中没有新的项被加入到J中;
  return J;
}

GOTO函数

返回项目集 I I I 对应于文法符号 X X X 的后继项目集闭包:

G O T O ( I , X ) = C L O S U R E ( { A → α X ⋅ β   ∣   A → α ⋅ X β ∈ I } ) GOTO( I, X )=CLOSURE(\{A→αX·β \ | \ A→α·Xβ∈I \}) GOTO(I,X)=CLOSURE({AαXβ  AαI})

SetOfltems GOTO ( I,X ) {
  将J 初始化为空集;
  for ( I 中的每个项A → α·Xβ )
    将项 A → αX·β 加入到集合J 中;
  return CLOSURE ( J );
}

LR(0)自动机的状态集

规范LR(0)项集族 (Canonical LR(0) Collection):

C = { I 0 } ∪ { I   ∣   ∃ J ∈ C , X ∈ V N ∪ V T , I = G O T O ( J , X ) } C=\{I_0 \}∪\{ I \ | \ \exists J ∈ C, X∈V_N ∪ V_T , I=GOTO(J , X) \} C={I0}{I  JC,XVNVT,I=GOTO(J,X)}

void items( G' ) {
  C={ CLOSURE ({[ S'→ ·S ] } ) };
  repeat
    for ( C中的每个项集 I )
      for( 每个文法符号 X )
        if ( GOTO( I,X )非空且不在C中)GOTO( I,X )加入C中;
  until在某一轮中没有新的项集被加入到C中;
}

LR(0)分析表构造算法

  1. 构造G’的规范LR(0)项集族 C = { I 0 , I 1 , . . . , I n } C = \{ I_0 , I_1 , ... , I_n \} C={I0,I1,...,In}
  2. I i I_i Ii 对应状态 i i i。状态 i i i 的语法分析动作按照下面的方法决定:
    2.1. i f A → α ⋅ a β ∈ I i   a n d   G O T O ( I i , a ) = I j   t h e n   A C T I O N [ i , a ] = s j if A→α·aβ∈I_i \ and \ GOTO( I_i , a )=I_j \ then \ ACTION[ i, a ]=sj ifAαaβIi and GOTO(Ii,a)=Ij then ACTION[i,a]=sj
    2.2. i f A → α ⋅ B β ∈ I i   a n d   G O T O ( I i , B ) = I j   t h e n   G O T O [ i , B ] = j if A→α·Bβ∈I_i \ and \ GOTO( I_i , B )=I_j \ then \ GOTO[ i, B ]=j ifAαIi and GOTO(Ii,B)=Ij then GOTO[i,B]=j
    2.3. i f A → α ⋅ ∈ I i if A→α·∈I_i ifAαIi A ≠ S ′   t h e n   f o r   ∀ a ∈ V T ∪ { A ≠ S' \ then \ for \ \forall a∈V_T ∪ \{ A=S then for aVT{ $ } \} } d o   A C T I O N [ i , a ] = r j do \ ACTION[ i, a ]=rj do ACTION[i,a]=rj ( j j j 是产生式 A → α A→α Aα 的编号)
    2.4. i f S ′ → S ⋅ ∈ I i   t h e n   A C T I O N [ i , if S'→S· ∈I_i \ then \ ACTION[i, ifSSIi then ACTION[i, $ ] = a c c ]=acc ]=acc
  3. 没有定义的所有条目都设置为“error”

LR(0)自动机的形式化定义

文法 G:
G = ( V N , V T , P , S ) G=(V_N,V_T,P,S) G=(VN,VT,P,S)

LR(0)自动机:
M = ( C , V N ∪ V T , G O T O , I 0 , F ) M=(C,V_N \cup V_T,GOTO,I_0,F) M=(C,VNVT,GOTO,I0,F)

  • C = { I 0 } ∪ { I   ∣   ∃ J ∈ C , X ∈ V N ∪ V T , I = G O T O ( J , x ) } C=\{I_0\}\cup\{I \ | \ \exist J \in C,X \in V_N \cup V_T,I=GOTO(J,x) \} C={I0}{I  JC,XVNVT,I=GOTO(J,x)}
  • I 0 = C L O S U R E ( { S ′ → ∙ S } ) I_0=CLOSURE(\{S^{'} \rightarrow \bullet S\}) I0=CLOSURE({SS})
  • F = { C L O S U R E ( { S ′ → S ∙ } ) } F=\{CLOSURE(\{S^{'} \rightarrow S\bullet \})\} F={CLOSURE({SS})}

LR(0)分析的冲突问题

LR(0)分析过程中可能会出现移进和归约二者间的冲突问题。例如:

如果LR(0)分析表中没有语法分析动作冲突,那么给定的文法就称为LR(0)文法。不是所有CFG都能用LR(0)方法进行分析,也就是说,CFG不总是LR(0)文法。

SLR分析

SLR算法的关键

有的LR(0)分析表的冲突的问题,可以使用SLR分析解决。SLR分析算法和LR(0)分析算法基本步骤相同,仅在分析表构造算法的2.3中处理归约项目时不同:

  • 对于 i i i 状态上的项目 A − > α ∙ A->\alpha \bullet A>α,仅对 y ∈ F O L L O W ( A ) y \in FOLLOW(A) yFOLLOW(A) 时才添加 A C T I O N [ i , y ] ACTION[i,y] ACTION[i,y]

对于上面的数学表达式。得到SLR分析表如下:

可以消除LR(0)分析表的冲突问题。下面再给一个例子:

SLR分析的冲突问题

如果给定文法的SLR分析表中不存在有冲突的动作,那么该文法称为SLR文法

LR(1)分析

SLR只是简单地考察下一个输入符号 b 是否属于与归约项目 A→α 相关联的 FOLLOW(A)。但 b∈FOLLOW(A) 只是归约 α 的一个必要条件,而非充分条件

在不同的位置,A会有不同的后继符号。使用 FOLLOW(A) 判定 A − > α A->\alpha A>α 是否可以归约,显然扩大了归约的范围。LR(1)分析会使用特定位置的后继符号,从而解决这个问题。

规范LR(1)项目

将一般形式为 [A→α · β, a] 的项称为 LR(1) 项 。 a 是一个终结符(展望符,lookahead),用于表示当前状态下,A后面必须紧跟的终结符。

  • LR(1) 中的 1 指的是项的第二个分量的长度。
  • 在形如 [A→α · β, a] 且 β ≠ ε 的项中,展望符 a 没有任何作用。
  • 但是一个形如 [A→α · , a] 的项在只有在下一个输入符号等于 a 时才可以按照 A→α 进行归约。

等价LR(1)项目

因为这里 β 可能推导为空,因此 b ∈ FIRST (βa) 。

β = > + ε β=>^+ ε β=>+ε 时,此时 b=a 叫 继承的 后继符,否则叫 自生的 后继符。

则赋值语句文法的 LR(1) 自动机和分析表如下:

构造过程和LR(0)和SLR自动机和分析过程一样,主要是在遇到待归约的LR(1)项目时,计算等价项目(也即闭包集)的方法不一样。

同心项目集

则同心的项目集为:

  • I 10 I_{10} I10 I 8 I_8 I8
  • I 11 I_{11} I11 I 4 I_4 I4
  • I 12 I_{12} I12 I 5 I_5 I5
  • I 13 I_{13} I13 I 7 I_7 I7

如果把同心项目集合并,则LR(1)自动机的状态数目和SLR是一样的。

CLOSURE函数

C L O S U R E ( I ) = I ∪ { [ B → ⋅ γ , b ]   ∣   [ A → α ⋅ B β , a ] ∈ C L O S U R E ( I ) , B → γ ∈ P , b ∈ F I R S T ( β a ) } CLOSURE( I ) = I ∪ \{ [B→·γ, b] \ | \ [A→α·Bβ, a] ∈ CLOSURE( I ), B→γ∈P, b∈FIRST(βa)\} CLOSURE(I)=I{[Bγ,b]  [Aα,a]CLOSURE(I),BγP,bFIRST(βa)}

SetOfltems CLOSURE ( I ) {
  repeat
    for ( I中的每个项 [A → α·Bβ,a ])
      for (G' 的每个产生式 B → γ)
        for ( FIRST (βa)中的每个符号 b )[ B → · γ ,b]加入到集合 I 中;
  until 不能向I中加入更多的项;
  until I ;
}

GOTO函数

G O T O ( I , X ) = C L O S U R E ( { [ A → α X ⋅ β , a ]   ∣   [ A → α ⋅ X β , a ] ∈ I } ) GOTO( I, X ) = CLOSURE(\{[A→αX · β,a] \ | \ [A→α · Xβ, a]∈I \}) GOTO(I,X)=CLOSURE({[AαXβ,a]  [Aα,a]I})

SetOfltems GOTO ( I,X ) {
  将J 初始化为空集;
    for ( I 中的每个项 [A → α·Xβ,a ])
      将项 [A → αX·β,a]加入到集合 J 中;
  return CLOSURE ( J );
}

文法G’ 构造LR(1)项集族

void items (G' ) {
  将C初始化为{CLOSURE ({[ S' → · S, $]} )} ;
  repeat
    for ( C 中的每个项集 I )
      for ( 每个文法符号 X )
        if (GOTO(I,X )非空且不在 C 中)GOTO(I,X )加入 C 中;
  until 不再有新的项集加入到C中;
}

LR(1)分析表的构造算法

LR(1)分析表算法和LR(0)分析表算法流程一致,稍加修改即可:

LALR分析

对于LR(1)自动机中,同心的项目集其实是不存在动作冲突,只是展望符不同,可以进行合并,以减少其状态。这就是 LALR分析。

  • 寻找具有相同核心的LR(1) 项集,并将这些项集合并为一个项集;

  • 然后根据合并后得到的项集族构造语法分析表;

  • 如果分析表中没有语法分析动作冲突,给定的文法就称为LALR(1) 文法,就可以根据该分析表进行语法分析。

合并同心项目集时可能产生归约-归约的冲突。例如:

同心项目集合并是合并的是展望符,展望符只在归约的时候起作用,因此,合并同心项目集不会产生移进-归约的冲突。但合并同心项目集可能产会推迟错误的发现。例如:

I 4 I_4 I4 I 9 I_9 I9 是同心项目集, I 6 I_6 I6 I 1 0 I_10 I10 是同心项目集。

对于错误输入d$,合并同心项目集前,从状态 I 0 I_0 I0 转移到状态 I 4 I_4 I4 后,由于展望符是 $,而不是 c,则会报错。而合并同心项目集后,在状态 I 4 I_4 I4 时不会报错,而是执行归约,回到状态 I 0 I_0 I0,状态 I 0 I_0 I0 遇到刚归约的A到状态 I 2 I_2 I2,状态 I 2 I_2 I2 遇到 $ 则报错。可见合并同心项目集可能使得报错推迟。

LALR(1)的特点:

  • 形式上与LR(1)相同,都是采用LR(1)项目的形式;

  • 大小上与LR(0)/SLR相当(自动机的状态相当);

  • 分析能力介于SLR和LR(1)二者之间;
    S L R < L A L R ( 1 ) < L R ( 1 ) SLR<LALR(1)<LR(1) SLR<LALR(1)<LR(1)

  • 合并后的展望符集合仍为FOLLOW集的子集。

参考

  • 哈工大编译原理课件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3412.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

U3D热更新技术

作者 : SYFStrive 博客首页 : HomePage &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f937;‍♀️&#xff1a;创作不易转发需经作者同意&#x1f608; &#x1f483;&#xff1a;程…

适用于 Windows 的企业级 Subversion 服务器

适用于 Windows 的企业级 Subversion 服务器。 Subversion 的 Windows 身份验证 Windows 身份验证是 VisualSVN 服务器的一个关键特性。此功能专为 Active Directory 域环境设计&#xff0c;允许用户使用其 Windows 凭据访问 VisualSVN 服务器。 VisualSVN Server 支持两种不同…

【Linux】基础IO ——中

&#x1f387;Linux&#xff1a;基础IO 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看…

这些Java基础知识,诸佬们都还记得嘛(学习,复习,面试都可)

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇将记录几次面试中经常被问到的知识点以及对学习的知识点总结和面试题的复盘。 本篇文章记录的基础知识&#xff0c;适合在学Java的小白&#xff0c;也适合复习中&…

趣说 Mysql内存篇 Buffer Pool

讲解顺序 先说 Mysql InnoDB 内存结构 Buffer PoolPage 管理机制Change BufferLog Buffer Buffer Pool 接上回 说到了 LRU 算法对内存的数据 进行淘汰 LRU 算法本身是 最近最少使用的&#xff0c;但是这样就会出现 分不清楚 哪些是真正多次使用的数据 LRU缺点&#xff1a…

软考重点10 知识产权

软考重点10 知识产权一、著作权1. 著作权的理解&#xff08;1&#xff09;版权&#xff1a;&#xff08;2&#xff09;人身权与财产权2. 知识产权的归属判定3. 知识产权的归属判定&#xff08;1&#xff09;委托创作&#xff08;2&#xff09;合作开发4. 著作权保护对象及范围5…

为什么要有包装类,顺便说一说基本数据类型、包装类、String类该如何转换?

一、前言 开门见山&#xff0c;首先看看八种基本数据类型对应的包装类&#xff1a; 基本数据类型包装类charCharacterbyteByteshortShortintIntegerlongLongfloatFloatdoubleDoublebooleanBoolean 其中Character 、Boolean的父类是Object&#xff0c;其余的父类是Number 二、装…

【软件测试】毕业打工两年,辞职一年后转行月薪18K,软件测试让我发起了第一春......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 小徐&#xff1a; 毕…

C++ 类和对象 日期类的实现

作者&#xff1a;小萌新 专栏&#xff1a;初阶C 作者简介&#xff1a;大二学生 希望能和大家一起进步 本篇博客目标&#xff1a; 完成Date类的实现 梳理剩下两个默认函数 好困 跑个步去 睡醒啦&#xff01; 继续肝 日期类的实现本章目标一. 日期类的实现1.1 Getmonthday的实现…

CNN的实现与可视化

CNN的实现 我们已经实现了卷积层和池化层&#xff0c;现在来组合这些层&#xff0c;搭建进行手写数字识别的CNN。如下图所示&#xff0c;网络的构成是“Convolution - ReLU - Pooling -Affine - ReLU - Affine - Softmax”&#xff0c;我们将它实现为名为SimpleConvNet的类。 …

R语言—向量

向量&#xff08;vector&#xff09; R 语言最基本的数据结构是向量。类似于数学上的集合的概念&#xff0c;由一个或多个元素构成。向量其实是用于存储数值型、字符型、或逻辑型数据的一维数组。 创建向量 c()函数 > a <- 1 #给a赋值1 > a #显示a的值 [1] 1 …

【C++初阶】类和对象终极篇

文章目录一.加const修饰this指针二.cout<<自定义类型的对象的实现1.深入理解cout和<<2流插入和流提取3.友元函数的来源a.作为ostream成员函数b.作为全局函数c.作为Date类的成员函数d.作为Date类的友元函数三.再谈构造函数之初始化列表四.隐式类型转换&explicit…

Linux命令从入门到实战----文件目录类

文章目录pwd显示当前工作路径的绝对路径ls列出目录的内容cd切换目录mkdir 创建一个新的目录删除一个空的目录touch创建新文件cp复制文件或目rm删除文件或目录mv移动文件与目录&#xff0c;重命名文件cat查看文件内容&#xff0c;创建新文件more文件内容分屏查看less分屏显示文件…

【C语言】字符串、字符数组

目录 写在开头 正文 一、字符串的本质 二、输入函数scanf和gets 三、输出函数printf和puts 四、字符串的长度——strlen 五、字符串的复制——strcpy 六、字符串的比较函数 七、实战练习 八、二维字符数组——字符串数组 写在最后 写在开头 看了标题&#xff0c;是…

Kotlin编程实战——类与对象(05)

一 概述 类与继承属性和字段接口(interface )函数式&#xff08;SAM&#xff09;接口可见性修饰符扩展数据类(data class)密封类泛型嵌套类与内部类枚举类对象表达式与对象声明类型别名内联类(inline class)委托委托属性 二 类与继承 类继承(open override )抽象类(abstract)…

MySQL去重中 distinct 和 group by 的区别

今天在写业务需要对数据库重复字段进行去重时&#xff0c;因为是去重&#xff0c;首先想到的是distinct关键字。于是一小时过去了。。。。&#xff08;菜鸟一个&#xff0c;大家轻点骂&#xff09; 我把问题的过程用sql语句演示给大家演示一下 首先我使用的是mybatis-plus&am…

数据结构之哈希表

文章目录 一、概念二、哈希冲突三、如何解决哈希冲突&#xff1f; 1.哈希函数设计2.负载因子调节3.闭散列4.开散列&#xff08;哈希桶&#xff09;四、模拟实现哈希桶总结一、概念 顺序结构以及平衡树中&#xff0c;元素与其存储位置之间没有对应的关系&#xff0c;因此在查找一…

C++多态学习笔记

C多态学习笔记一、多态概述二、多态的作用三、多态发生的三个条件四、多态实现的原理五、接口的定义六、模板方法模式七、虚析构函数和纯虚析构函数7.1 虚析构函数7.2 纯虚析构函数八、重写重载重定义九、父类引用子类对象一、多态概述 同一个操作作用于不同的对象&#xff0c;…

2014年848数据结构真题复习

求k频度K0; for&#xff08;i1;i<n;i&#xff09; 假如是1——8&#xff0c;执行了9次&#xff0c;8次有效&#xff0c;最后一次无效for&#xff08;ji;j<n;j&#xff09;k 我的理解&#xff1a;假设n为8我们看k频度实际上就是看内圈for的有效循环次数第一轮是1——8 八次…

基础算法 第七课——归并排序

文章目录导言归并排序的概念步骤说明逐步分析STEP1STEP2STEP3STEP4STEP5STEP6STEP0总结导言 这&#xff0c;是一篇现学现卖的文章。因为&#xff0c;我根本没学过归并排序。所以&#xff0c;这篇文章&#xff0c;绝对能让您学懂归并。如果不懂&#xff0c;那我就再学一遍&…