win7 C# 利用windows自帶語音類庫讀書 spvoice,電腦端 讀書-摘自網路
棧
//順序表實現 #define MaxSize 50 typedef int ElemType; typedef struct { ElemType data[MaxSize];//陣列 int top; }SqStack; void InitStack(SqStack& S) { S.top = -1;//棧為空 } bool StackEmpty(SqStack S) { if (-1 == S.top) return true; else return false; } bool Push(SqStack& S, ElemType x) { if (S.top == MaxSize - 1)//棧滿 { return false; } S.data[++S.top] = x;//++S.top = -1,一開始為空棧“-1” -1+1=0 S.data[0]=x,依次走 return true; } //獲取棧頂元素 bool GetTop(SqStack S, ElemType& x) { if (StackEmpty(S))//棧為空 { return false; } x = S.data[S.top]; return true; } bool Pop(SqStack& S, ElemType& x) { if (StackEmpty(S))//棧為空 { return false; } x = S.data[S.top--];//等價於x=S.data[S.top]; S,top--; return true; }
假設以Ⅰ和О分別表示入棧和出棧操作。棧的初態和終態均為空,入棧和出棧的操作序列可表示為僅由Ⅰ和О組成的序列,可以操作的序列稱為合法序列,否則稱為非法序列。寫出一個演算法,判定所給的操作序列是否合法。若合法,返回true,否則返回false(假定被判定的操作序列已存入一維陣列中).
設被判定的操作序列已存入一維陣列A中。演算法的基本設計思想:依次逐一掃描入棧出棧序列(即由“I”和“O”組成的字串),每掃描至任一位置均需檢查出棧次數(即“O”的個數)是否小於入棧次數(“I”的個數),若大於則為非法序列。掃描結束後,再判斷入棧和出棧次數是否相等,若不相等則不合題意,為非法序列。
int Judge(char A[]) { //判斷字元陣列A中的輸入輸出序列是否是合法序列,如是,返回true,否則返回false int i=0; //i為下標 int j=k=0; //j和k分別為字母I和O的個數 while(A[i]='\0') //未到字元陣列尾 { switch(A[i]){ case 'I': j++; break; //入棧次數加1 case 'O': k++; if(k>j) {printf("非法序列\n");exit(0);} } i++; //不論A[i]是“I”或者是“O",指標i均後移 } if(j!=k){ printf("序列非法"); return false; } else{ printf("序列合法\n"); return true; } }
設單鏈表的表頭指標為L,結點結構由data和next兩個域構成,其中data域為字元型。試設計演算法判斷該連結串列的全部n個字元是否中心對稱。例如xyx、xyyx都是中心對稱。
演算法思想:使用棧來判斷連結串列中的資料是否中心對稱。讓連結串列的前一半元素依次進棧。在處理連結串列的後一半元素時,當訪問到連結串列的一個元素後,就從棧中彈出一個元素,兩個元素比較,若相等,則將連結串列中的下一個元素與棧中再彈出的元素比較,直至連結串列到尾。這時若棧是空棧,則得出連結串列中心對稱的結論;否則,當連結串列中的一個元素與棧中彈出元素不等時,結論為連結串列非中心對稱,結束演算法執行
演算法先將“連結串列的前一半”元素(字元)進棧。當n為偶數時,前一半和後一半的個數相同;當n為奇數時,連結串列中心結點字元不必比較,移動連結串列指標到下一字元開始比較。比較過程中遇到不相等時,立即退出while迴圈,不再進行比較。
int dc(LinkList L,int n){
//L是帶頭節點的n個元素單鏈表,本演算法判斷連結串列是否是中心對稱
int i;
chars s[n/2]; //s字元棧
p=L->next; //p是連結串列的工作指標,指向待處理的當前元素
for(i=0;i<n/2){ //連結串列前一半元素進棧
s[i]=p->data;
p=p->next;
}
i--; //恢復最後的i值
if(n%2==1) //若n是奇數,後移過中心結點
p=p->next;
while(p!=NULL&&s[i]==p->data){//檢測是否中心對稱
i--; //i充當棧頂指標
p=p->next;
}
if(i==-1)
return 1;
else
return 0;
}
設有兩個棧s1、s2都採用順序棧方式,並共享一個儲存區〔0...., maxsize-1],為了儘量利用空間,減少溢位的可能,可採用棧頂相向、迎面增長的儲存方式。試設計s1、s2有關入棧和出棧的操作演算法。
兩個棧共享向量空間,將兩個棧的棧底設在向量兩端,初始時,s1棧頂指標為-1,s2棧頂指標為maxsize。兩個棧頂指標相鄰時為棧滿。兩個棧頂相向、迎面增長,棧頂指標指向棧頂元素。
#define maxsize 100 //兩個棧共享順序儲存空間所能達到的最多元素樹,初始化為100
#define elemtp int //假設元素型別為整型
typedef struct{
elemtp stack[maxsize];
int top[2];
}stk;
stk s; //s是如上定義的結構型別變數,為全域性變數
本題的關鍵在於,兩個棧入棧和退棧時的棧頂指標的計算。s1棧是通常意義下的棧;而s2棧入棧操作時,其棧頂指標左移(減1),退棧時,棧頂指標右移(加1).此比外,對於所有棧的操作,都要注意
(1)入棧操作
int push(int i,elemtp x)
{
//入棧操作。i為棧號,i表示左邊的是s1棧,i=1表示右邊的s2棧,x是入棧元素
//入棧成功返回1,否則返回0
if(i<0||i>1){
printf("棧號輸入不對");
exit(0);
}
if(s.top[1]-s.top[0]==1{
printf("棧已滿\n");
return 0;
}
switch(i){
case 0: s.stack[++s.top[0]]=x;return 1; break;
case 1: s.stack[--s.top[1]]=x;return -1;
}
}
(2)退棧操作
elemtp pop(int i){
//推展演算法 i代表站好,i=0時為s1棧,i=1時為s2棧
//退棧成功返回退棧元素,否則返回-1
if(i<0||i>1){
printf("棧號輸入錯誤\n");
exit(0);
}
switch(i){
case 0:
if(s.top[0]==-1){
printf("棧空\n");
return -1;
}
case 1:
if(s.top[1]==maxsize){
printf("棧空\n");
return -1;
}
else
return s.stack[ss.top[1]++];
break;
}//switch
}