編譯原理Lab1-用FLEX構造C-Minus-f詞法分析器

HNU編譯原理lab1實驗–根據cminux-f的詞法補全lexical_analyer.l文件,完成詞法分析器。

本文沒有添加任何圖片,但是以復制輸出的形式展現出來了實驗結果。

實驗要求:

根據cminux-f的此法補全lexical_analyer.l文件,完成詞法分析器,能夠輸出識別出的token,type,line(剛出現的行數),pos_start(該行的開始位置),post_end(結束位置 不包含)
例如:
文本輸入:

int a;

則識別結果應為:

int     280     1       2       5
a       285     1       6       7
;       270     1       7       8

cminus-f詞法

C MINUS是C語言的一個子集,該語言的語法在《編譯原理與實踐》第九章附錄中有詳細的介紹。而cminus-f則是在C MINUS上追加了浮點操作。

  1. 關鍵字else if int return void while float
  2. 專用符號+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */
  3. 標識符ID和整數NUM,通過下列正則表達式定義:
letter = a|...|z|A|...|Z
digit = 0|...|9
ID = letter+
INTEGER = digit+
FLOAT = (digit+. | digit*.digit+)
  1. 注釋用/*...*/表示,可以超過一行。注釋不能嵌套。
/*...*/
  • 注:[, ], 和 [] 是三種不同的token。[]用于聲明數組類型,[]中間不得有空格。
    • a[]應被識別為兩個token: a[]
    • a[1]應被識別為四個token: a, [, 1, ]

實驗難點

git相關操作:常用的命令在實驗文檔中

將實驗倉庫克隆到本地:打開本地的工作目錄,在命令行中輸入
`git clone https://gitee.com/你的gitee用戶名/cminus_compiler-2022-fall.git`
打開本地的工作目錄,在命令行中輸入
git add *
git commit -m "注釋語句"
然后push到倉庫
git push

實驗環境配置

sudo apt-get install llvm bison flex
輸入:flex --version和bison --version

FLEX工具的簡單使用

首先,FLEX從輸入文件*.lex或者stdio讀取詞法掃描器的規范,從而生成C代碼源文件lex.yy.c。然后,編譯lex.yy.c并與-lfl庫鏈接,以生成可執行的a.out。最后,a.out分析其加入的輸入流,將其轉換為一系列token。
舉例:

%{
//在%{和%}中的代碼會被原樣照抄到生成的lex.yy.c文件的開頭,您可以在這里書寫聲明與定義
#include <string.h>
int chars = 0;
int words = 0;
%}
%%/*你可以在這里使用你熟悉的正則表達式來編寫模式*//*你可以用C代碼來指定模式匹配時對應的動作*//*yytext指針指向本次匹配的輸入文本*//*左部分([a-zA-Z]+)為要匹配的正則表達式,右部分({ chars += strlen(yytext);words++;})為匹配到該正則表達式后執行的動作*/
[a-zA-Z]+ { chars += strlen(yytext);words++;}
. {}/*對其他所有字符,不做處理,繼續執行*/
%%
int main(int argc, char **argv){//yylex()是flex提供的詞法分析例程,默認讀取stdin      yylex();                                                               printf("look, I find %d words of %d chars\n", words, chars);return 0;
}

lex中的字符規定:

格式含義
a字符
“a”元字符
\a轉義
a*a的零次或者多次重復
a+a的一次或者多次重復
a?一個可選的a
ab
(a)a本身
[abc]字符abc中的任意一個
[a-d]字符abcd的任意一個
{xxxxx}名字xxx表示的正則表達式
.除了新行之外的任意一個字符

實驗設計

找到Token符號對應的字符

cminux_compiler-2023-fall/include/lexical_analyzer.h
有定義cimux_token_type(附錄)

對應正則表達式

根據cminus-f詞法

1. 關鍵字
else if int return void while float2. 專用符號
+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */3. 標識符ID和整數NUM,通過下列正則表達式定義:
letter = a|...|z|A|...|Z
digit = 0|...|9
ID = letter+
INTEGER = digit+
FLOAT = (digit+. | digit*.digit+)4. 注釋用`/*...*/`表示,可以超過一行。注釋不能嵌套。
/*...*/
- 注:`[`, `]`, 和 `[]` 是三種不同的token。`[]`用于聲明數組類型,`[]`中間不得有空格。- `a[]`應被識別為兩個token: `a`、`[]`- `a[1]`應被識別為四個token: `a`, `[`, `1`, `]`

寫出對應的正則表達式和指定匹配對應的動作

C minus的詞法單元規則有:
關鍵字:else if int return void while float
專用符號:`+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */``
標識符ID和整數NUM,通過下列正則表達式定義:

letter = a|...|z|A|...|Z
digit = 0|...|9
ID = letter+
INTEGER = digit+
FLOAT = (digit+. | digit*.digit+)

注釋用/*...*/表示,可以超過一行。注釋不能嵌套。

此部分用于定義C Minus的詞法單元的規則,模式采用正則表達式表示,注意當詞法單元的pattern中包含特殊字符時,需要使用轉義字符\。動作使用C語言描述,確定每個Token在每行的開始位置和結束位置,并且返回該詞法單元類型。該返回值為yylex()的返回值。
動作分為兩步:第一步,更新lines、pos_start、post_end。第二步:將識別結果token返回,return。
運算:

\+ {pos_start=pos_end;pos_end=pos_start+1;return ADD;}
\- {pos_start=pos_end;pos_end=pos_start+1;return SUB;}
\* {pos_start=pos_end;pos_end=pos_start+1;return MUL;}
\/ {pos_start=pos_end;pos_end=pos_start+1;return DIV;}
\< {pos_start=pos_end;pos_end=pos_start+1;return LT;}
"<=" {pos_start=pos_end;pos_end=pos_start+2;return LTE;}
\> {pos_start=pos_end;pos_end=pos_start+1;return GT;}
">=" {pos_start=pos_end;pos_end=pos_start+2;return GTE;}
"==" {pos_start=pos_end;pos_end=pos_start+2;return EQ;}
"!=" {pos_start=pos_end;pos_end=pos_start+2;return NEQ;}
\= {pos_start=pos_end;pos_end=pos_start+1;return ASSIN;}

符號:

\; {pos_start=pos_end;pos_end=pos_start+1;return SEMICOLON;}
\, {pos_start=pos_end;pos_end=pos_start+1;return COMMA;}
\( {pos_start=pos_end;pos_end=pos_start+1;return LPARENTHESE;}
\) {pos_start=pos_end;pos_end=pos_start+1;return RPARENTHESE;}
\[ {pos_start=pos_end;pos_end=pos_start+1;return LBRACKET;}
\] {pos_start=pos_end;pos_end=pos_start+1;return RBRACKET;}
\{ {pos_start=pos_end;pos_end=pos_start+1;return LBRACE;}
\} {pos_start=pos_end;pos_end=pos_start+1;return RBRACE;}

關鍵字:

else {pos_start=pos_end;pos_end=pos_start+4;return ELSE;}
if {pos_start=pos_end;pos_end=pos_start+2;return IF;}
int {pos_start=pos_end;pos_end=pos_start+3;return INT;}
float {pos_start=pos_end;pos_end=pos_start+5;return FLOAT;}
return {pos_start=pos_end;pos_end=pos_start+6;return RETURN;}
void {pos_start=pos_end;pos_end=pos_start+4;return VOID;}
while {pos_start=pos_end;pos_end=pos_start+5;return WHILE;}

標識符和整數NUM

[a-zA-Z]+ {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return IDENTIFIER;}
[0-9]+ {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return INTEGER;}
[0-9]*\.[0-9]+ {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return FLOATPOINT;}
"[]" {pos_start=pos_end;pos_end=pos_start+2;return ARRAY;}
[a-zA-Z] {pos_start=pos_end;pos_end=pos_start+1;return LETTER;}
[0-9]+\. {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return FLOATPOINT;}

其他的

  • 當詞法分析器掃描到換行符時(Windows下為\r\n,Linux下為\n,Mac下為\r),行數lines自增,pos_startpos_end更新
  • 由于flex生成的詞法分析器采用最長匹配策略,且注釋/**/包含正則的通配符,正則規范較為復雜。當識別到一個注釋時,需要考慮詞法單元開始位置和結束位置變化,且多行注釋要修改lines.
  • 錯誤的詞法單元 ,當掃描到錯誤的詞法單元,僅返回ERROR
\n {return EOL;} #換行
\/\*([^\*]|(\*)*[^\*\/])*(\*)*\*\/ {return COMMENT;} #注釋
" " {return BLANK;} #空格
\t {return BLANK;} # 空格
. {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return ERROR;} #錯誤

最終的添加

/******************TODO*********************//****請在此補全所有flex的模式與動作  start******///STUDENT TO DO\+ {pos_start=pos_end;pos_end=pos_start+1;return ADD;}
\- {pos_start=pos_end;pos_end=pos_start+1;return SUB;}
\* {pos_start=pos_end;pos_end=pos_start+1;return MUL;}
\/ {pos_start=pos_end;pos_end=pos_start+1;return DIV;}
\< {pos_start=pos_end;pos_end=pos_start+1;return LT;}
"<=" {pos_start=pos_end;pos_end=pos_start+2;return LTE;}
\> {pos_start=pos_end;pos_end=pos_start+1;return GT;}
">=" {pos_start=pos_end;pos_end=pos_start+2;return GTE;}
"==" {pos_start=pos_end;pos_end=pos_start+2;return EQ;}
"!=" {pos_start=pos_end;pos_end=pos_start+2;return NEQ;}
\= {pos_start=pos_end;pos_end=pos_start+1;return ASSIN;}
\; {pos_start=pos_end;pos_end=pos_start+1;return SEMICOLON;}
\, {pos_start=pos_end;pos_end=pos_start+1;return COMMA;}
\( {pos_start=pos_end;pos_end=pos_start+1;return LPARENTHESE;}
\) {pos_start=pos_end;pos_end=pos_start+1;return RPARENTHESE;}
\[ {pos_start=pos_end;pos_end=pos_start+1;return LBRACKET;}
\] {pos_start=pos_end;pos_end=pos_start+1;return RBRACKET;}
\{ {pos_start=pos_end;pos_end=pos_start+1;return LBRACE;}
\} {pos_start=pos_end;pos_end=pos_start+1;return RBRACE;}
else {pos_start=pos_end;pos_end=pos_start+4;return ELSE;}
if {pos_start=pos_end;pos_end=pos_start+2;return IF;}
int {pos_start=pos_end;pos_end=pos_start+3;return INT;}
float {pos_start=pos_end;pos_end=pos_start+5;return FLOAT;}
return {pos_start=pos_end;pos_end=pos_start+6;return RETURN;}
void {pos_start=pos_end;pos_end=pos_start+4;return VOID;}
while {pos_start=pos_end;pos_end=pos_start+5;return WHILE;}
[a-zA-Z]+ {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return IDENTIFIER;}
[0-9]+ {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return INTEGER;}
[0-9]*\.[0-9]+ {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return FLOATPOINT;}
"[]" {pos_start=pos_end;pos_end=pos_start+2;return ARRAY;}
[a-zA-Z] {pos_start=pos_end;pos_end=pos_start+1;return LETTER;}
[0-9]+\. {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return FLOATPOINT;}
\n {return EOL;}
\/\*([^\*]|(\*)*[^\*\/])*(\*)*\*\/ {return COMMENT;}
" " {return BLANK;}
\t {return BLANK;}
. {pos_start=pos_end;pos_end=pos_start+strlen(yytext);return ERROR;}/****請在此補全所有flex的模式與動作  end******/

和補充C語言代碼

注釋可以分為多行,所以在識別到注釋的時候要進行額外的分析,識別到換行符\n的時候,要lines+1,重置pos_end.

           case COMMENT://STUDENT TO DO{pos_start=pos_end;pos_end=pos_start+2;int i=2;while(yytext[i]!='*' || yytext[i+1]!='/'){  			if(yytext[i]=='\n'){lines=lines+1;pos_end=1;}elsepos_end=pos_end+1;i=i+1;}pos_end=pos_end+2;break;}case BLANK://STUDENT TO DO{pos_start=pos_end;pos_end=pos_start+1;break;}case EOL://STUDENT TO DO{lines+=1;pos_end=1;break;}

實驗結果驗證

實驗結果

根據實驗指導書上的流程輸入命令并且得到反饋結果

sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ mkdir build
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ cd build
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall/build$ cmake ../
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found FLEX: /usr/bin/flex (found version "2.6.4") 
-- Found BISON: /usr/bin/bison (found version "3.5.1") 
-- Found LLVM 10.0.0
-- Using LLVMConfig.cmake in: /usr/lib/llvm-10/cmake
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sunny2004/lab1/cminus_compiler-2023-fall/build
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall/build$ make lexer
[ 20%] [FLEX][lex] Building scanner with flex 2.6.4
lexical_analyzer.l:60: warning, 無法匹配規則
Scanning dependencies of target flex
[ 40%] Building C object src/lexer/CMakeFiles/flex.dir/lex.yy.c.o
lexical_analyzer.l: In function ‘analyzer’:
lexical_analyzer.l:92:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
lexical_analyzer.l: At top level:
/home/sunny2004/lab1/cminus_compiler-2023-fall/build/src/lexer/lex.yy.c:1320:17: warning: ‘yyunput’ defined but not used [-Wunused-function]static void yyunput (int c, char * yy_bp )^
/home/sunny2004/lab1/cminus_compiler-2023-fall/build/src/lexer/lex.yy.c:1363:16: warning: ‘input’ defined but not used [-Wunused-function]static int input  (void)^
[ 60%] Linking C static library ../../libflex.a
[ 60%] Built target flex
Scanning dependencies of target lexer
[ 80%] Building C object tests/lab1/CMakeFiles/lexer.dir/main.c.o
[100%] Linking C executable ../../lexer
[100%] Built target lexer
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall/build$ cd ..
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ ./build/lexer
usage: lexer input_file output_file
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ ./build/lexer ./tests/lab1/testcase/1.cminus out
[START]: Read from: ./tests/lab1/testcase/1.cminus
[END]: Analysis completed.
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ head -n 5 out
int	280	1	1	4
gcd	285	1	5	8
(	272	1	9	10
int	280	1	10	13
u	285	1	14	15
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ python3 ./tests/lab1/test_lexer.py
Find 6 files
[START]: Read from: ./tests/lab1/testcase/3.cminus
[END]: Analysis completed.
[START]: Read from: ./tests/lab1/testcase/2.cminus
[END]: Analysis completed.
[START]: Read from: ./tests/lab1/testcase/6.cminus
[END]: Analysis completed.
[START]: Read from: ./tests/lab1/testcase/1.cminus
[END]: Analysis completed.
[START]: Read from: ./tests/lab1/testcase/5.cminus
[END]: Analysis completed.
[START]: Read from: ./tests/lab1/testcase/4.cminus
[END]: Analysis completed.
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ diff ./tests/lab1/token ./tests/lab1/TA_token
sunny2004@sunny2004-VirtualBox:~/lab1/cminus_compiler-2023-fall$ 

如果正確的話,diff不會返回任何輸出,如果返回了,就出錯了

gitee上傳

git commit -m "lab1-result"
如果是第一次提交,Ubuntu會告訴你這樣:
請告訴我您是誰,運行
git config --global user.email "you@example.com"
git config --global user.name "your Name"
來自設置您賬號的缺省身份標識。
如果僅在本地倉庫設置身份標識,則省略 --global參數
這個時候你就運行git config那兩行命令之后再運行git commit -m "lab1-result"就可以了
然后:git push 上傳工作到gitee倉庫(這一部分忘記復制了,實驗指導書里寫的很詳細,就按照那個來就行)

實驗反饋

學習和鞏固了正則表達式
熟悉了gitee的操作
一路磕磕絆絆,調試,趕在驗收之前完成了,編譯原理好難┭┮﹏┭┮

附錄1:cmius_token_type

typedef num cminus_token_type{
//運算
ADD = 259, 	加號:+
SUB = 260, 	減號:-
MUL = 261, 	乘號:*
DIV = 262, 	除法:/
LT = 263, 	小于:<
LTE = 264, 	小于等于:<=
GT = 265, 	大于:>
GTE = 266, 	大于等于:>=
EQ = 267, 	相等:==
NEQ = 268, 	不相等:!=
ASSIN = 269,單個等于號:=//符號
SEMICOLON = 270,	分號:;
COMMA = 271, 		逗號:,
LPARENTHESE = 272, 	左括號:(
RPARENTHESE = 273, 	右括號:)
LBRACKET = 274, 	左中括號:[
RBRACKET = 275, 	右中括號:]
LBRACE = 276, 		左大括號:{
RBRACE = 277, 		右大括號:}//關鍵字
ELSE = 278, 	else
IF = 279, 		if
INT = 280, 		int
FLOAT = 281, 	float
RETURN = 282, 	return 
VOID = 283, 	void
WHILE = 284,	while//ID和NUM
IDENTIFIER = 285,	變量名,例如a,low,high
INTEGER = 286, 		整數,例如10,1
FLOATPOINT = 287,	浮點數,例如11.1
ARRAY = 288,		數組,例如[]
LETTER = 289,		單個字母,例如a,z	//others
EOL = 290,			換行符,\n或\0	
COMMENT = 291,		注釋
BLANK = 292,		空格
ERROR = 258			錯誤
} Token;typedef struct{char text[256];int token;int lines;int pos_start;int pos_end;
} Token_Node;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164342.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164342.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164342.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

國家超級計算濟南中心低代碼平臺應用實踐

摘要&#xff1a;文章主要介紹了濟南超算使用低代碼平臺明道云解決了一系列業務問題&#xff0c;包括資產管理、人員與機構管理、流程制度管理等。通過明道云平臺&#xff0c;濟南超算成功地將不同部門的業務信息進行整合&#xff0c;提高了工作效率和管理水平。文章還強調了明…

計算機端口

前言 計算機端口&#xff08;Port&#xff09;是一種用于在計算機網絡中標識特定服務或應用程序的機制。 端口是一個數字&#xff0c;范圍從0到65535&#xff0c;用于將網絡通信分配給不同的應用程序或服務。 在 Internet 協議套件&#xff08;TCP/IP&#xff09;中&#xff0…

MG-HSF

作者未提供代碼

Go語言中結構體的使用和示例

結構體&#xff08;簡稱struct&#xff09;用于創建不同數據類型的成員集合&#xff0c;放入一個單一的變量中。雖然數組用于將相同數據類型的多個值存儲在單一變量中&#xff0c;但結構體用于將不同數據類型的多個值存儲在單一變量中。結構體對于將數據組合在一起以創建記錄非…

openGL之紋理 :第二課

#include "glew.h" #include "glfw3.h" #include "SOIL2.h"//如何解析輸入的數據流 0&#xff0c;1,2 分三部分 GLchar * vertextSrc " #version 330 core \n \layout (location 0) in vec3 position; \layout (location 1) in vec3 col…

【精選】??通道熱點加持的LW-ResNet:小麥病害智能診斷與防治系統

1.研究背景與意義 小麥是世界上最重要的糧食作物之一&#xff0c;但由于病害的侵襲&#xff0c;小麥產量和質量受到了嚴重的威脅。因此&#xff0c;開發一種高效準確的小麥病害識別分類防治系統對于保障糧食安全和農業可持續發展具有重要意義。 傳統的小麥病害識別分類方法主…

Feign

目錄 RestTemplate方式調用存在的問題: 定義和使用Feign客戶端 自定義Feign的配置 性能優化 Feign的最佳實踐 Feign的使用步驟&#xff1a; 1、引入依賴 2、添加EnableFeignClients注解 3、編寫FeignClient接口 4、使用FeignClient中定義的方法代替RestTemplate Feign的…

什么是遷移學習

1 遷移學習概述 遷移學習&#xff08;Transfer Learning&#xff09;是機器學習中的一種方法&#xff0c;它允許模型將從一個任務中學到的知識應用到另一個相關的任務中。這種方法在數據稀缺的情況下尤為有用&#xff0c;因為它減少了對大量標記數據的需求。遷移學習已成為深度…

Node使用Nvm安裝雙版本切換(node兩個版本同時用怎么辦?不同的項目Node版本要求不一樣怎么辦?)

先把node.js卸載 開始—>添加刪除程序—>node npm -v node -v //檢查是否還存在&#xff0c;卸載成功就行了NVM下載 github下載 百度網盤下載 打開安裝包以管理員身份安裝&#xff0c;要是記得這個路徑并且必須全是英文 使用nvm安裝兩個使用的node版本 cmd以管理員…

計算機組成原理2

1.浮點數 2.IEEE 754 3.存儲器的性能指標 4.存儲器的層次化結構 主存類似手機運行內存8g &#xff0c;輔存類似手機內存128g.... 輔存必須先通過主存才能被cpu接收&#xff0c;就例如微信打開那個月亮小人界面兩三秒就是主存在讀取輔存的程序然后被cpu接收運行。 5.主存儲…

Greenplum的數據庫年齡檢查處理

概述 Greenplum是基于Postgresql數據庫的分布式數據庫&#xff0c;而PG數據庫在事務及多版本并發控制的實現方式上很特別&#xff0c;采用的是遞增事務id的方法&#xff0c;事務id大的事務&#xff0c;認為比較新&#xff0c;反之事務id小&#xff0c;認為比較舊。 事務id的上…

經典的回溯算法題leetcode組合問題整理及思路代碼詳解

目錄 組合問題 leetcode77題.組合 leetcode216題.組合總和III leetcode40題.組合總和II leetcode39題.組合總和 倘若各位不太清楚回溯算法可以去看我上一篇文章。 回溯算法詳解-CSDN博客 組合問題 一般組合和排列類的問題我們都會轉化成一個樹形問題&#xff0c;更便于…

26. 刪除有序數組中的重復項(remove-duplicates-from-sorted-array)

26. 刪除有序數組中的重復項(remove-duplicates-from-sorted-array) 給你一個 非嚴格遞增排列 的數組 nums &#xff0c;請你** 原地** 刪除重復出現的元素&#xff0c;使每個元素 只出現一次 &#xff0c;返回刪除后數組的新長度。元素的 相對順序 應該保持 一致 。然后返回 …

批量創建表空間數據文件(DM8:達夢數據庫)

DM8:達夢數據庫 - - 批量創建表空間數據文件 環境介紹1 批量創建表空間SQL2 達夢數據庫學習使用列表 環境介紹 在某些場景(分區表子表)需要批量創建表空間,給不同的表使用,以下代碼是批量創建表空間的SQL語句; 1 批量創建表空間SQL --創建 24個數據表空間,每個表空間有3個數…

強化學習小筆記 —— 如何選擇合適的更新步長

在強化學習中&#xff0c;動作價值函數的更新可以使用增量法&#xff0c;如下所示&#xff1a; Q k 1 k ∑ i 1 k r i 1 k ( r k ∑ i 1 k ? 1 r i ) 1 k ( r k ( k ? 1 ) Q k ? 1 ) 1 k ( r k k Q k ? 1 ? Q k ? 1 ) Q k ? 1 1 k [ r k ? Q k ? 1 ] \beg…

Linux寶塔面板搭建Discuz論壇, 并內網穿透實現公網訪問

Linux寶塔面板搭建Discuz論壇&#xff0c; 并內網穿透實現公網訪問 文章目錄 Linux寶塔面板搭建Discuz論壇&#xff0c; 并內網穿透實現公網訪問前言1.安裝基礎環境2.一鍵部署Discuz3.安裝cpolar工具4.配置域名訪問Discuz5.固定域名公網地址6.配置Discuz論壇 &#x1f4f7; 江池…

低代碼平臺推薦:五大低代碼廠商誰的模式更“合適”

隨著數字化時代的到來&#xff0c;低代碼開發平臺作為提高數字生產力的工具正受到越來越多企業的關注&#xff0c;市面上的低代碼產品和廠商更是“亂花漸欲迷人眼”。 各家產品不僅功能各有不同&#xff0c;甚至商機都有區別的情況&#xff0c;如何做好產品選型已然成了采購企…

C語言——指針(一)

&#x1f4dd;前言 這篇文章主要帶大家初步認識一下指針&#xff0c;供大家理解參考。 主要歸納與講解&#xff1a; 1&#xff0c;指針與指針變量 2&#xff0c;指針的基本使用&#xff08;如何定義&#xff0c;初始化&#xff0c;引用&#xff09; &#x1f3ac;個人簡介&…

計算方法 期末總結

思維導圖 緒論 算法的性質&#xff1a; 有窮性、確切性、有輸入輸出、可行性 算法的描述方法&#xff1a; 自然語言、偽代碼、流程圖、N-S流程圖 算法設計思想&#xff1a; 化大為小的縮減技術&#xff1a;二分法化難為易的校正技術&#xff1a;開方法化粗為精的松弛技術&a…

無需公網IP,使用內網穿透實現公網訪問本地OpenWRT管理界面

文章目錄 1.openWRT安裝cpolar2.配置遠程訪問地址3.固定公網地址 簡單幾步實現在公網環境下遠程訪問openWRT web 管理界面&#xff0c;使用cpolar內網穿透創建安全隧道映射openWRT web 界面面板443端口&#xff0c;無需公網IP&#xff0c;無需設置路由器。 1.openWRT安裝cpola…