[題目分析]本題是對字符串表達式的處理問題首先定義種數據結構符號的類碼符號的TOKEN 表示變量名表NAMEL和常量表CONSL這四種數據結構均定義成結構體形式數據部分用一維數組存儲同時用指針指出數據的個數算法思想是從左到右掃描表達式對讀出的字符先查出其符號類碼若是變量或常量就到變量名表和常量表中去查是否已有若無則在相應表中增加之並返回該字符在變量名表或常量表中的下標;若是操作符則去查其符號類碼對讀出的每個符號均填寫其TOKEN表如此下去直到表達式處理完畢先定義各數據結構如下
struct //定義符號類別數據結構
{char data[]; //符號
char code[]; //符號類碼
}TYPL;
typedef struct //定義TOKEN的元素
{int typ; //符號碼
int addr; //變量常量在名字表中的地址
}cmp;
struct {cmp data[];//定義TOKEN表長度<
int last; //表達式元素個數
}TOKEN;
struct {char data[]; //設變量個數小於個
int last; //名字表變量個數
}NAMEL;
struct {char data[]; //設常量個數小於個
int last; //常量個數
}CONSL;
int operator(char cr) //查符號在類碼表中的序號
{for(i=;i<=;i++)
if(TYPLdata[i]==cr) return(i);
}
void PROCeString() //從鍵盤讀入字符串表達式(以#結束)輸出其TOKEN表示
{NAMELlast=CONSLlast=TOKENlast=; //各表元素個數初始化為
TYPLdata[]=*;TYPLdata[]=+;TYPLdata[]=(;
TYPLdata[]=); //將操作符存入數組
TYPLcode[]=;TYPLcode[]=;TYPLcode[]=;
TYPLcode[]=; //將符號的類碼存入數組
scanf(%c&ch); //從左到右掃描(讀入)表達式
while(ch!=#) //#是表達式結束符
{switch(ch)of
{caseA: case B: case C: //ch是變量
TY=; //變量類碼為
for(i=;i<=NAMELlast;i++)
if(NAMELdata[i]==ch)break;//已有該變量i記住其位置
if(i>NAMELlast){NAMELdata[i]=ch;NAMELlast++;}//變量加入
case: case: case: case: case: case://處理常量
case: case :case: case: TY=;//常量類碼為
for(i=;i<=CONSLlast;i++)
if(CONSLdata[i]==ch)break;////已有該常量i記住其位置
if(i>CONSLlast){CONSLdata[i]=ch;CONSLlast++;}//將新常量加入
default: //處理運算符
TY=operator(ch);//類碼序號
i=\; //填入TOKEN的addr域(期望輸出空白)
}//結束switch下面將ch填入TOKEN表
TOKENdata[++TOKENlast]typ=TY;TOKENdata[TOKENlast]addr=i;
scanf(%c&ch); //讀入表達式的下一符號
}//while
}//算法結束
[程序討論]為便於討論各一維數組下標均以開始在字符為變量或常量的情況下將其類碼用TY記下用i記下其NAMEL表或CONSL表中的位置以便在填TOKEN表時用在運算符(+*())填入TOKEN表時TOKEN表的addr域沒意義為了程序統一這裡填入了\本題是表達式處理的簡化情況(只有個單字母變量常量只有操作符只個)若是真實情況所用數據結構要相應變化
[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
From:http://tw.wingwit.com/Article/program/sjjg/201311/22605.html