鏈棧的建立與使用,進位制轉換與括號匹配問題
鏈棧的建立與使用(先進後出) 包含兩個運用 1.判斷一個表示式中符號"(",")","[","]","{","}"是否匹配,若匹配返回1,不匹配返回0; 2.數制轉換:將十進位制轉換為隨意進位制
問題: 1.中途卡在了遍歷棧和出棧函式上,想遍歷來看看是否存進了資料 除錯了幾次,都是在賦值給x和輸出附近出現問題,多次蹦出CPU視窗,判斷是記憶體和存值問題,初次改動沒有成功,反而無法輸入,進入函式後沒有執行,直接結束程式,附圖
2.懷疑是賦值問題,可能需要記憶體??
後來查詢了他人的程式碼,發現大多數定義棧頂指標都喜歡用結構體並附帶棧的長度
自己試了一下並沒有太大改善,反而輸出出現了問題
後來想用和他們一樣,定義棧頂指標結構體然後定義結構體指標,雙重指標進行建表輸出,但沒有實行,
感覺應該有更方便的方法。
附帶程式碼連線:
4.整形轉換為字元型 (1) char c; (2)char c; int a; int a; c=a+48; c=a+'0';
程式一:括號匹配
//括號匹配結構體
typedef struct stnode
{
char data;
struct stnode *next;
}LinkStack;
將記憶體分配放在了主函式內,放在初始化函式內無法正常執行,費了很多時間才弄好
//棧的初始化操作
void InitStack(LinkStack *ls)
{
ls->next=NULL;
}
入棧操作。費了半天勁才調好
//符號入棧操作 void Push(LinkStack *ls,char x) { LinkStack *p; p=(LinkStack*)malloc(sizeof(LinkStack)); p->data=x; p->next=ls->next;//->next; ls->next=p; //先使p->next指向ls(即ls此時對應的結點),然後改變ls指向 }
出棧操作
//符號出棧
void Pop(LinkStack *ls)
{
LinkStack *p;
p=ls->next;
ls->next=ls->next->next;
free(p);
}
為了在寫的時候觀察是否建立成功寫的遍歷函式
//遍歷棧中元素
int ShowStack(LinkStack *ls)
{
LinkStack *p;
p=ls->next;
if(p==NULL)
{
printf("為空棧\n");
return 0;
}
while(p!=NULL) //ls=p->next;
{
printf("元素為:%c\n",p->data);
p=p->next;
}
return 0;
}
重點函式,匹配,返回值是為了中途不匹配返回0,直接跳出
//符號匹配函式
int Exps(LinkStack *ls,char x)
{
switch(x)
{
case '(':Push(ls,x);break; //輸入符號並進行壓棧操作
case '{':Push(ls,x);break; //輸入符號並進行壓棧操作
case '[':Push(ls,x);break; //輸入符號並進行壓棧操作
case ')': //進行匹配,若匹配,則出棧一個,不匹配則進棧
if(ls->next->data=='(')
{
Pop(ls);
break;
}
else
{
printf("不匹配\n"); //若不匹配,則返回選單
return 0;
}
case '}': //進行匹配,若匹配,則出棧一個,不匹配則進棧
if(ls->next->data=='{')
{
Pop(ls);
break;
}
else
{
printf("不匹配\n"); //若不匹配,則返回選單
return 0;
}
case ']': //進行匹配,若匹配,則出棧一個,不匹配則進棧
if(ls->next->data=='[')
{
Pop(ls);
break;
}
else
{
printf("不匹配\n"); //若不匹配,則返回選單
return 0;
}
}
return 1;
程式二:進位制轉換函式
結構體和初始化一起寫了
typedef struct stmath
{
char num;
struct stmath *rear;
}LinkMath;
//進位制轉化初始化
void Math_Stack(LinkMath *lq)
{
lq->rear=NULL;
}
進位制入棧和轉換函式
//進位制入棧
void Push_Math(LinkMath *lq,char y)
{
LinkMath *s;
s=(LinkMath*)malloc(sizeof(LinkMath));
s->num=y; //存入連結串列,以便倒敘
s->rear=lq->rear;
lq->rear=s;
}
//進位制轉換函式
void ZhuanStack(LinkMath *lq,int num1,int j)
{
int z; //定義整形用於計算
char y; //字元型用來存餘數並轉換為字元型
LinkMath *t;
while(num1!=0) //num1不為0,則繼續
{
z=num1%j; //取餘數
if(z>10) //餘數大於10,則轉換進位制大於10,需要字母
{
y='A'+z%10; //計算相應字母
}
else
{
y=z+'0'; //轉換進位制不大於10或餘數不大於10,無需字母,轉換為字元型
}
num1=num1/j; //num1取整
Push_Math(lq,y); //進位制入棧函式
}
t=lq->rear;
while(t!=NULL)
{
printf("%c",t->num); //對進位制棧進行遍歷輸出
t=t->rear;
}
printf("\n");
}
程式中都用個人認為比較詳細的註釋,就不詳細講解了
附圖完整程式碼
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//括號匹配結構體
typedef struct stnode
{
char data;
struct stnode *next;
}LinkStack;
//進位制轉換結構體
typedef struct stmath
{
char num;
struct stmath *rear;
}LinkMath;
//棧的初始化操作
void InitStack(LinkStack *ls)
{
ls->next=NULL;
}
//進位制轉化初始化
void Math_Stack(LinkMath *lq)
{
lq->rear=NULL;
}
//符號入棧操作
void Push(LinkStack *ls,char x)
{
LinkStack *p;
p=(LinkStack*)malloc(sizeof(LinkStack));
p->data=x;
p->next=ls->next;//->next;
ls->next=p; //先使p->next指向ls(即ls此時對應的結點),然後改變ls指向
}
//進位制入棧
void Push_Math(LinkMath *lq,char y)
{
LinkMath *s;
s=(LinkMath*)malloc(sizeof(LinkMath));
s->num=y; //存入連結串列,以便倒敘
s->rear=lq->rear;
lq->rear=s;
}
//符號出棧
void Pop(LinkStack *ls)
{
LinkStack *p;
p=ls->next;
ls->next=ls->next->next;
free(p);
}
//遍歷棧中元素
int ShowStack(LinkStack *ls)
{
LinkStack *p;
p=ls->next;
if(p==NULL)
{
printf("為空棧\n");
return 0;
}
while(p!=NULL) //ls=p->next;
{
printf("元素為:%c\n",p->data);
p=p->next;
}
return 0;
}
//符號匹配函式
int Exps(LinkStack *ls,char x)
{
switch(x)
{
case '(':Push(ls,x);break; //輸入符號並進行壓棧操作
case '{':Push(ls,x);break; //輸入符號並進行壓棧操作
case '[':Push(ls,x);break; //輸入符號並進行壓棧操作
case ')': //進行匹配,若匹配,則出棧一個,不匹配則進棧
if(ls->next->data=='(')
{
Pop(ls);
break;
}
else
{
printf("不匹配\n"); //若不匹配,則返回選單
return 0;
}
case '}': //進行匹配,若匹配,則出棧一個,不匹配則進棧
if(ls->next->data=='{')
{
Pop(ls);
break;
}
else
{
printf("不匹配\n"); //若不匹配,則返回選單
return 0;
}
case ']': //進行匹配,若匹配,則出棧一個,不匹配則進棧
if(ls->next->data=='[')
{
Pop(ls);
break;
}
else
{
printf("不匹配\n"); //若不匹配,則返回選單
return 0;
}
}
return 1;
}
//進位制轉換函式
void ZhuanStack(LinkMath *lq,int num1,int j)
{
int z; //定義整形用於計算
char y; //字元型用來存餘數並轉換為字元型
LinkMath *t;
while(num1!=0) //num1不為0,則繼續
{
z=num1%j; //取餘數
if(z>10) //餘數大於10,則轉換進位制大於10,需要字母
{
y='A'+z%10; //計算相應字母
}
else
{
y=z+'0'; //轉換進位制不大於10或餘數不大於10,無需字母,轉換為字元型
}
num1=num1/j; //num1取整
Push_Math(lq,y); //進位制入棧函式
}
t=lq->rear;
while(t!=NULL)
{
printf("%c",t->num); //對進位制棧進行遍歷輸出
t=t->rear;
}
printf("\n");
}
int main()
{
char x; //輸入括號
int i; //判斷返回值以確定匹配
LinkStack *ls; //括號棧頂指標
LinkMath *lq; //進位制棧頂指標
int num1,j; //轉換的數值以及轉換成的進位制
ls=(LinkStack*)malloc(sizeof(LinkStack));
lq=(LinkMath*)malloc(sizeof(LinkMath));
Math_Stack(lq);
InitStack(ls); //對棧進行初始化
while(1)
{
printf("---------------1.括號匹配--------------\n");
printf("---------------2.進位制轉換--------------\n");
printf("---------------3.遍歷元素--------------\n");
printf("請選擇功能:");
scanf("%d",&i);
scanf("%c",&x); //多餘的輸入,用來存入輸入選擇以後再次輸入的回車'\n',排除'\n'影響
switch(i)
{
case 1:
printf("請輸入括號:");
while(1)
{
scanf("%c",&x);
if(x=='\n') //當x==回車鍵時停止輸入,並判斷是否為空,為空則全部匹配
{
if(ls->next==NULL)
{
printf("括號匹配\n");
break;
}
else
{
printf("括號不匹配\n");
break;
}
}
i=Exps(ls,x); //進入符號匹配函式
if(i==0) //如果匹配中途不匹配,則返回0,並退出迴圈
break;
// Push(ls,x); //輸入符號並進行壓棧操作
}
break;
case 2:
printf("請輸入數字:");
scanf("%d",&num1);
printf("請輸入進位制:");
scanf("%d",&j);
ZhuanStack(lq,num1,j);
break;
case 3:
ShowStack(ls);
break;
}
}
return 0;
}
如有錯誤,請及時指出,謝謝