中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

找網(wǎng)站公司做網(wǎng)站的陷阱友情鏈接代碼

找網(wǎng)站公司做網(wǎng)站的陷阱,友情鏈接代碼,網(wǎng)易暴雪最新消息,廣州做網(wǎng)站推廣公司目錄 0 引言 1 棧在括號匹配中的應(yīng)用 2 棧在表達(dá)式求值中的應(yīng)用 2.1 算數(shù)表達(dá)式 2.2 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式 2.3 后綴表達(dá)式求值 3 棧在遞歸中的應(yīng)用 3.1 棧在函數(shù)調(diào)用中的作用 3.2 棧在函數(shù)調(diào)用中的工作原理 4 總結(jié) 0 引言 棧(Stack)是一…

目錄

0? 引言

1? 棧在括號匹配中的應(yīng)用

2? 棧在表達(dá)式求值中的應(yīng)用

? ? ? ? 2.1 算數(shù)表達(dá)式

? ? ? ? 2.2 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

2.3 后綴表達(dá)式求值

3? 棧在遞歸中的應(yīng)用

3.1 棧在函數(shù)調(diào)用中的作用

3.2 棧在函數(shù)調(diào)用中的工作原理

4? 總結(jié)


0? 引言

????????棧(Stack)是一種非?;厩抑匾臄?shù)據(jù)結(jié)構(gòu),它們在許多計算機(jī)科學(xué)和軟件工程的應(yīng)用中都有廣泛的用途。

? ? ? ? 棧:

????????????????①括號匹配;

? ? ? ? ? ? ? ? ②表達(dá)式求值;

? ? ? ? ? ? ? ? ③遞歸函數(shù)調(diào)用。

1? 棧在括號匹配中的應(yīng)用

? ? ? ? 表達(dá)式中有兩種括號:圓括號 ( ) 和 方括號 [ ],嵌套的順序任意,但應(yīng)為正確的格式。

????????例如:( ( [ ]?[ ] ) ) 為正確格式。

? ? ? ? 但如何用算法實(shí)現(xiàn)括號匹配問題?

? ? ? ? 思路如下:

? ? ? ? (1)初始一個空棧;

? ? ? ? (2)順序讀入括號;

? ? ? ? (3)當(dāng)讀入的為左括號,將繼續(xù)讀入括號,直到讀入第一個右括號。那將檢測與之最近的左括號是否與之相匹配,若匹配,則出棧;若不匹配,則退出程序。當(dāng)程序結(jié)束時,棧為空。反之,則表明括號序列的格式不正確。

? ? ? ? 代碼如下:

#include <stdio.h>  
#include <stdlib.h>  
#include <stdbool.h>  #define MAX_SIZE 100 // 假設(shè)棧的最大大小  typedef struct {  char data[MAX_SIZE];  int top;  
} Stack;  // 初始化棧  
void initStack(Stack *s) {  s->top = -1;  
}  // 判斷棧是否為空  
bool isEmpty(Stack *s) {  return s->top == -1;  
}  // 入棧  
void push(Stack *s, char c) {  if (s->top >= MAX_SIZE - 1) {  printf("Stack overflow\n");  return;  }  s->data[++s->top] = c;  
}  // 出棧  
char pop(Stack *s) {  if (isEmpty(s)) {  printf("Stack underflow\n");  return '#'; // 返回一個無效字符,或可以選擇拋出一個錯誤  }  return s->data[s->top--];  
}  // 檢查兩個括號是否匹配  
bool isMatch(char c1, char c2) {  if (c1 == '(' && c2 == ')') return true;  if (c1 == '[' && c2 == ']') return true;  if (c1 == '{' && c2 == '}') return true;  return false;  
}  // 括號匹配函數(shù)  
bool isBalanced(char *str) {  Stack s;  initStack(&s);  for (int i = 0; str[i] != '\0'; i++) {  if (str[i] == '(' || str[i] == '[' || str[i] == '{') {  push(&s, str[i]);  } else if (str[i] == ')' || str[i] == ']' || str[i] == '}') {  if (isEmpty(&s)) {  // 棧為空,但遇到了右括號,不匹配  return false;  }  char topChar = pop(&s);  if (!isMatch(topChar, str[i])) {  // 棧頂元素與當(dāng)前右括號不匹配  return false;  }  }  }  // 如果棧為空,則所有括號都匹配  return isEmpty(&s);  
}  int main() {  char str[MAX_SIZE];  printf("Enter a string with brackets: ");  scanf("%s", str); if (isBalanced(str)) {  printf("The brackets are balanced.\n");  } else {  printf("The brackets are not balanced.\n");  }  return 0;  
}

2? 棧在表達(dá)式求值中的應(yīng)用

? ? ? ? 2.1 算數(shù)表達(dá)式

????????中綴表達(dá)式是人們常用的算術(shù)表達(dá)式,即操作符以中綴形式處于操作數(shù)之間。但在計算機(jī)中,中綴表達(dá)式相較于前綴和后綴表達(dá)式來說,更不易被計算機(jī)識別。前綴表達(dá)式成為波蘭式,后綴表達(dá)式又稱逆波蘭式。

? ? ? ? 2.2 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

? ? ? ? (1)手算方法:

? ? ? ? ①根據(jù)運(yùn)算順序?qū)Ρ磉_(dá)式運(yùn)算符排號;

? ? ? ? ②根據(jù)運(yùn)算符排號順序,將運(yùn)算符及兩端的操作數(shù)以(左操作數(shù) 右操作數(shù) 運(yùn)算符)的順序重新組合。

? ? ? ? 例如:( A + B ) * C + ( D - E ) / F 轉(zhuǎn)后綴表達(dá)式的過程如下:

? ? ? ??(2)算法實(shí)現(xiàn):

? ? ? ? ①初始一個棧;

? ? ? ? ②遇到操作數(shù),直接加入后綴表達(dá)式;

? ? ? ? ③遇到界限符,若為左括號直接入棧,若為右括號,則依次彈出棧中的運(yùn)算符,加入后綴表達(dá)式,知道彈出左括號為止。需要注意的是,左括號和右括號直接刪除,不加入后綴表達(dá)式。

? ? ? ? ④遇到運(yùn)算符,則看運(yùn)算符的優(yōu)先級,若高于除左括號外的棧頂元素,則直接入棧。反之,則依次彈出棧中優(yōu)先級高于或等于當(dāng)前運(yùn)算符的所有運(yùn)算符,并加入后綴表達(dá)式,直到遇到低于他的優(yōu)先級的運(yùn)算符,才入棧。

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <stdbool.h>  #define MAX_SIZE 100  typedef struct {  char data[MAX_SIZE];  int top;  
} Stack;  // 初始化棧  
void initStack(Stack *s) {  s->top = -1;  
}  // 判斷棧是否為空  
bool isEmpty(Stack *s) {  return s->top == -1;  
}  // 入棧  
bool push(Stack *s, char c) {  if (s->top >= MAX_SIZE - 1) {  return false; // 棧溢出  }  s->data[++s->top] = c;  return true;  
}  // 出棧  
char pop(Stack *s) {  if (isEmpty(s)) {  return '\0'; // ???#xff0c;返回空字符  }  return s->data[s->top--];  
}  // 獲取棧頂元素,但不彈出  
char peek(Stack *s) {  if (isEmpty(s)) {  return '\0'; // ???#xff0c;返回空字符  }  return s->data[s->top];  
}  // 運(yùn)算符的優(yōu)先級比較(這里只處理了基本的四則運(yùn)算)  
int precedence(char op) {  if (op == '+' || op == '-') {  return 1;  }  if (op == '*' || op == '/') {  return 2;  }  return 0; // 如果不是運(yùn)算符,返回0  
}  // 將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式  
void infixToPostfix(char *infix, char *postfix) {  Stack s;  initStack(&s);  int i = 0, j = 0;  while (infix[i] != '\0') {  if (infix[i] >= '0' && infix[i] <= '9') {  // 如果是操作數(shù),直接添加到后綴表達(dá)式中  postfix[j++] = infix[i++];  postfix[j++] = ' '; // 假設(shè)操作數(shù)都是個位數(shù),用空格分隔  } else if (infix[i] == '(') {  // 如果是左括號,直接入棧  push(&s, infix[i++]);  } else if (infix[i] == ')') {  // 如果是右括號,則彈出棧中元素直到遇到左括號  while (!isEmpty(&s) && peek(&s) != '(') {  postfix[j++] = pop(&s);  postfix[j++] = ' ';  }  // 彈出左括號,但不加入后綴表達(dá)式  pop(&s);  i++;  } else {  // 如果是運(yùn)算符  while (!isEmpty(&s) && precedence(peek(&s)) >= precedence(infix[i])) {  // 如果棧不為空且棧頂元素優(yōu)先級高于或等于當(dāng)前運(yùn)算符,彈出棧頂元素  postfix[j++] = pop(&s);  postfix[j++] = ' ';  }  // 當(dāng)前運(yùn)算符入棧  push(&s, infix[i++]);  }  }  // 彈出棧中剩余的所有運(yùn)算符  while (!isEmpty(&s)) {  postfix[j++] = pop(&s);  postfix[j++] = ' ';  }  // 添加字符串結(jié)束符  postfix[j] = '\0';  
}  int main() {  char infix[MAX_SIZE], postfix[MAX_SIZE * 2]; // 后綴表達(dá)式可能更長,因此分配更多空間  printf("Enter an infix expression: ");  scanf("%s", infix); // 注意:這里不會處理空格和復(fù)雜輸入  infixToPostfix(infix, postfix);  printf("Postfix expression: %s\n", postfix);  return 0;  
}

2.3 后綴表達(dá)式求值

????????后綴表達(dá)式(也稱為逆波蘭表示法或逆波蘭記法)是一種不需要括號來標(biāo)明運(yùn)算符的優(yōu)先級的數(shù)學(xué)表達(dá)式。在這種表示法中,所有的運(yùn)算符都放在操作數(shù)的后面。

????????求值后綴表達(dá)式的基本步驟如下:

  • 初始化一個棧,用于存儲操作數(shù)。
  • 從左到右掃描后綴表達(dá)式。
  • 如果掃描到操作數(shù),則將其壓入棧中。
  • 如果掃描到運(yùn)算符,則從棧中彈出兩個操作數(shù)(先彈出的為右操作數(shù),后彈出的為左操作數(shù)),將這兩個操作數(shù)作為運(yùn)算符的輸入進(jìn)行運(yùn)算,然后將結(jié)果壓回棧中。
  • 重復(fù)步驟2-4,直到后綴表達(dá)式掃描完畢。
  • 棧中剩下的元素就是表達(dá)式的值。

????????示例

????????后綴表達(dá)式:3 4 + 5 *

????????求值過程:

  1. 掃描到?3,壓入棧:[3]
  2. 掃描到?4,壓入棧:[3, 4]
  3. 掃描到?+,彈出?4?和?3,計算?3 + 4?得到?7,壓入棧:[7]
  4. 掃描到?5,壓入棧:[7, 5]
  5. 掃描到?*,彈出?5?和?7,計算?7 * 5?得到?35,壓入棧:[35]
  6. 掃描完畢,棧中元素?35?即為表達(dá)式的值。

????????下面是實(shí)現(xiàn)代碼(以上述示例為例):

#include <stdio.h>  
#include <stdlib.h>  
#include <ctype.h>  
#include <string.h>  #define MAX_STACK_SIZE 100  typedef struct {  double data[MAX_STACK_SIZE];  int top;  
} Stack;  // 初始化棧  
void initStack(Stack *s) {  s->top = -1;  
}  // 判斷棧是否為空  
int isEmpty(Stack *s) {  return s->top == -1;  
}  // 壓棧操作  
void push(Stack *s, double value) {  if (s->top >= MAX_STACK_SIZE - 1) {  printf("Stack overflow\n");  exit(1);  }  s->data[++s->top] = value;  
}  // 彈棧操作  
double pop(Stack *s) {  if (isEmpty(s)) {  printf("Stack underflow\n");  exit(1);  }  return s->data[s->top--];  
}  // 求值后綴表達(dá)式  
double evaluatePostfix(const char *postfix) {  Stack s;  initStack(&s);  const char *token = strtok((char *)postfix, " "); // 假設(shè)操作符和操作數(shù)之間用空格分隔  while (token != NULL) {  if (isdigit(token[0])) { // 如果是操作數(shù)  double value = atof(token);  push(&s, value);  } else { // 如果是運(yùn)算符  double rightOperand = pop(&s); // 彈出右操作數(shù)  double leftOperand = pop(&s); // 彈出左操作數(shù)  switch (token[0]) {  case '+':  push(&s, leftOperand + rightOperand);  break;  case '-':  push(&s, leftOperand - rightOperand);  break;  case '*':  push(&s, leftOperand * rightOperand);  break;  case '/':  if (rightOperand != 0.0) {  push(&s, leftOperand / rightOperand);  } else {  printf("Error: Division by zero\n");  exit(1);  }  break;  default:  printf("Error: Unknown operator\n");  exit(1);  }  }  token = strtok(NULL, " "); // 繼續(xù)獲取下一個token  }  if (!isEmpty(&s)) {  return pop(&s); // 棧中剩下的元素就是表達(dá)式的值  } else {  printf("Error: Invalid postfix expression\n");  exit(1);  }  
}  int main() {  const char *postfix = "3 4 + 5 *";  double result = evaluatePostfix(postfix);  printf("Result: %lf\n", result);  return 0;  
}

3? 棧在遞歸中的應(yīng)用

3.1 棧在函數(shù)調(diào)用中的作用

  • 參數(shù)傳遞:當(dāng)調(diào)用一個函數(shù)時,需要傳遞參數(shù)給該函數(shù)。這些參數(shù)會被壓入棧中,以便函數(shù)內(nèi)部能夠訪問和使用它們。
  • 局部變量分配:函數(shù)內(nèi)部定義的局部變量會在棧上分配空間。這些變量的生命周期與函數(shù)的執(zhí)行周期相同,當(dāng)函數(shù)執(zhí)行完畢后,這些局部變量所占用的??臻g會被自動釋放。
  • 保存調(diào)用的返回地址:在函數(shù)調(diào)用時,CPU需要知道函數(shù)執(zhí)行完畢后應(yīng)該返回到哪個位置繼續(xù)執(zhí)行。這個返回地址會被保存在棧中,以便函數(shù)執(zhí)行完畢后能夠正確地返回到調(diào)用它的位置。
  • 保存寄存器以供恢復(fù):在函數(shù)調(diào)用和返回的過程中,CPU的寄存器狀態(tài)會發(fā)生變化。為了能夠在函數(shù)返回后恢復(fù)原來的寄存器狀態(tài),棧會保存這些寄存器的值。

3.2 棧在函數(shù)調(diào)用中的工作原理

  • 函數(shù)調(diào)用:當(dāng)調(diào)用一個函數(shù)時,系統(tǒng)首先會創(chuàng)建一個新的棧幀(stack frame)來保存該函數(shù)的執(zhí)行環(huán)境。這個棧幀包含了函數(shù)的返回地址、參數(shù)、局部變量等信息。然后,系統(tǒng)會將當(dāng)前程序的執(zhí)行狀態(tài)(如返回地址、寄存器狀態(tài)等)壓入棧中,以便在函數(shù)執(zhí)行完畢后能夠恢復(fù)。
  • 函數(shù)執(zhí)行:在函數(shù)執(zhí)行過程中,函數(shù)會訪問棧幀中的參數(shù)和局部變量,并根據(jù)需要進(jìn)行計算和操作。同時,如果函數(shù)內(nèi)部調(diào)用了其他函數(shù),系統(tǒng)也會為這些被調(diào)用的函數(shù)創(chuàng)建新的棧幀,并將當(dāng)前函數(shù)的執(zhí)行狀態(tài)壓入棧中保存。
  • 函數(shù)返回:當(dāng)函數(shù)執(zhí)行完畢或者遇到return語句時,系統(tǒng)會彈出當(dāng)前函數(shù)的棧幀,并根據(jù)棧幀中的返回地址返回到調(diào)用它的位置繼續(xù)執(zhí)行。在返回之前,系統(tǒng)還會恢復(fù)調(diào)用該函數(shù)時的寄存器狀態(tài)。

? ? ? ? 下面將給出一個例子:

? ? ? ? 例如:階乘,大家可以自行調(diào)試;

#include <stdio.h>int step(int n){if(n==1)return 1;elsereturn n*step(n-1);
}int main(){int n,s;scanf("%d",&n);s=step(n);printf("%d",s);
}

4? 總結(jié)

????????在本文中,我們深入探討了棧這一數(shù)據(jù)結(jié)構(gòu)及其在各種應(yīng)用場景中的重要作用。棧作為一種后進(jìn)先出(LIFO)的數(shù)據(jù)結(jié)構(gòu),其獨(dú)特的操作方式——壓棧(push)和彈棧(pop),使得它在計算機(jī)科學(xué)和軟件開發(fā)中占據(jù)了不可或缺的地位。

????????詳細(xì)討論了棧在多個領(lǐng)域中的應(yīng)用。其中,后綴表達(dá)式的求值是一個經(jīng)典的棧應(yīng)用示例。在這個問題中,我們利用棧來存儲操作數(shù),并通過操作數(shù)的彈出和結(jié)果的壓入,實(shí)現(xiàn)了表達(dá)式的正確計算。這種方法不僅簡化了表達(dá)式的處理流程,而且提高了計算效率。

????????此外,棧還在函數(shù)調(diào)用、遞歸等方面發(fā)揮著重要作用。在函數(shù)調(diào)用中,棧用于存儲局部變量和返回地址,確保函數(shù)能夠正確地返回并繼續(xù)執(zhí)行。在遞歸算法中,棧用于保存遞歸調(diào)用的中間結(jié)果,從而避免重復(fù)計算。

????????綜上所述,棧作為一種基本而強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),在各個領(lǐng)域都有著廣泛的應(yīng)用。通過學(xué)習(xí)和掌握棧的使用方法和應(yīng)用場景,我們能夠更好地解決實(shí)際問題,提高編程效率。

http://www.risenshineclean.com/news/35360.html

相關(guān)文章:

  • 工廠采購信息網(wǎng)深圳優(yōu)化公司哪家好
  • 林州網(wǎng)站建設(shè)服務(wù)關(guān)鍵詞分類哪八種
  • 網(wǎng)站建設(shè) 石景山windows優(yōu)化大師卸載不了
  • 模板網(wǎng)站制作成都百度推廣優(yōu)化創(chuàng)意
  • 西昌有做網(wǎng)站的公司嗎怎樣推廣公司的網(wǎng)站
  • 日本一級做a在線播放免費(fèi)視頻網(wǎng)站網(wǎng)站制作詳細(xì)流程
  • 美橙網(wǎng)站建設(shè)怎么做全國疫情最新數(shù)據(jù)
  • 學(xué)校網(wǎng)站開發(fā)招標(biāo)網(wǎng)絡(luò)推廣優(yōu)化品牌公司
  • 美女做曖曖網(wǎng)站關(guān)鍵詞排名推廣軟件
  • 虎門仿做網(wǎng)站一鍵生成個人網(wǎng)站
  • 怎么把做的網(wǎng)站放到騰訊云里面代寫文章哪里找寫手
  • 聊城做網(wǎng)站優(yōu)化百度投訴中心人工電話
  • 做宣傳可以在哪些網(wǎng)站上發(fā)布如何營銷推廣自己的產(chǎn)品
  • 臨沂手機(jī)網(wǎng)站建設(shè)google學(xué)術(shù)搜索
  • 公眾號網(wǎng)站怎么做永久免費(fèi)linux服務(wù)器
  • 網(wǎng)站制作說明書谷歌瀏覽器app
  • 南陽網(wǎng)站優(yōu)化渠道市場調(diào)研報告的基本框架
  • server2012 wordpress想找搜索引擎優(yōu)化
  • 網(wǎng)站建設(shè)裝修專業(yè)網(wǎng)站推廣優(yōu)化
  • 網(wǎng)站制作工具 簡易中國國家培訓(xùn)網(wǎng)官網(wǎng)查詢
  • 南寧建站程序搜索引擎營銷的四種方式
  • 蘭州做網(wǎng)站哪家好網(wǎng)址域名ip解析
  • 免認(rèn)證域名注冊手機(jī)卡頓優(yōu)化軟件
  • 龍之向?qū)赓Q(mào)網(wǎng)站 網(wǎng)絡(luò)服務(wù)關(guān)鍵詞優(yōu)化設(shè)計
  • 網(wǎng)站建設(shè)對網(wǎng)絡(luò)營銷的影響seo課程簡介
  • 導(dǎo)購網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷有什么方式
  • 企業(yè)網(wǎng)站虛擬空間自助建站免費(fèi)建站平臺
  • 購物網(wǎng)站開發(fā)實(shí)例鄭州網(wǎng)站公司哪家好
  • 做網(wǎng)站要用多少錢如何在其他平臺做推廣
  • 橋頭仿做網(wǎng)站個人博客