实验3
3.1 实验目的
熟练掌握栈的顺序存储结构和链式存储结构。
熟练掌握栈的有关算法设计,并在顺序栈和链栈上实现。
根据具体给定的需求,合理设计并实现相关结构和算法。
3.2实验要求
3.2.1 顺序栈的实验要求
顺序栈结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;
实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
程序有适当的注释。
3.2.2 链栈实验要求
本次实验中的链栈结构指带头结点的单链表;
链栈结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;
实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
程序有适当的注释。
3.3 实验任务
3.3.1 顺序栈实验任务
设计并实现一个顺序栈,编写算法实现下列问题的求解。
<1>利用顺序栈实现将10进制数转换为16进制数。
第一组数据:4 / 4
第二组数据:11 / B
第三组数据:254 / FE
第四组数据:1357 / 54D
<2>对一个合法的数学表达式来说,其中的各大小括号“{”,“}”,“[”,“]”,“(”和“)”应是相互匹配的。设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。
3.3.2 链栈实验任务
以带头结点的单链表表示链栈,编写算法实现下列问题的求解。
<1>利用顺序栈实现将10进制数转换为16进制数。
第一组数据:4
第二组数据:11
第三组数据:254
第四组数据:1357
<2>对一个合法的数学表达式来说,其中的各大小括号“{”,“}”,“[”,“]”,“(”和“)”应是相互匹配的。设计算法对以字符串形式读入的表达式S,判断其中的各括号是否是匹配的。
3.4 选做题
非必做内容,有兴趣的同学选做。自行选择栈的存储结构。
<1>假设栈的输入序列为1、2、3、...、n,设计算法实现对给定的一个序列,判定其是否是此栈合法的输出序列。
<2>假设栈的输入序列为1、2、3、...、n,设计算法求出所有可能的出栈序列。
<3>利用栈求解算术表达式的值。
3.5 运行结果截图及说明
图1 顺序栈实现十进制转十六进制
图2 顺序栈解决表达式括号匹配问题(局部)
图3 顺序栈解决表达式括号匹配问题(局部)
图4 顺序栈解决表达式括号匹配问题(局部)
图5 顺序栈解决表达式括号匹配问题(局部)
图6 链栈实现十进制转十六进制
图7 链栈解决表达式括号匹配问题(局部)
图8 链栈解决表达式括号匹配问题(局部)
图9 链栈解决表达式括号匹配问题(局部)
图10 链栈解决表达式括号匹配问题(局部)
图11 链栈判断1、2、3、4排列中合法出栈序列的问题
图12 链栈解决输出1、2、3、4、5、6、7全排列中合法出栈序列的问题(放大可清晰观看)
图13 链栈中缀表达式求值问题
3.6 附源代码
顺序栈代码:
1 // stdafx.h : include file for standard system include files, 2 // or project specific include files that are used frequently, but 3 // are changed infrequently 4 // 5 6 #if !defined(AFX_STDAFX_H__F1CE48FC_1D41_45D9_B60D_6D065D91DB10__INCLUDED_) 7 #define AFX_STDAFX_H__F1CE48FC_1D41_45D9_B60D_6D065D91DB10__INCLUDED_ 8 9 #if _MSC_VER > 1000 10 #pragma once 11 #endif // _MSC_VER > 1000 12 13 #include <stdc++.h> 14 15 using namespace std; 16 17 //typedef int elementType; 18 typedef double elementType; 19 typedef char elementType1; 20 const int maxLength = 1000 + 3; 21 22 // TODO: reference additional headers your program requires here 23 24 //{{AFX_INSERT_LOCATION}} 25 // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 26 27 #endif // !defined(AFX_STDAFX_H__F1CE48FC_1D41_45D9_B60D_6D065D91DB10__INCLUDED_)
1 // SeqStack1.h: interface for the SeqStack class. 2 // 3 ////////////////////////////////////////////////////////////////////// 4 5 #if !defined(AFX_SEQSTACK1_H__55EE245C_A5F8_47D4_9510_B3BA6C85FF63__INCLUDED_) 6 #define AFX_SEQSTACK1_H__55EE245C_A5F8_47D4_9510_B3BA6C85FF63__INCLUDED_ 7 8 #if _MSC_VER > 1000 9 #pragma once 10 #endif // _MSC_VER > 1000 11 12 #include "charSeqStack.h" 13 14 //using elementType = double; 15 typedef double elementType; 16 class SeqStack 17 { 18 public: 19 SeqStack(); 20 virtual ~SeqStack(); 21 bool stackEmpty(); 22 bool stackFull(); 23 bool getTop( elementType& value ); 24 bool push( elementType value ); 25 bool pop(); 26 int length(); 27 void displayStack(); 28 int isp( elementType1 _operator );//栈内优先级 29 int icp( elementType1 _operator );//栈外优先级 30 charSeqStack css; 31 double doOperator( elementType value1, elementType value2, elementType1 _operator ); 32 void calculate( charSeqStack& css1, charSeqStack& css2 ); 33 friend ostream &operator<< (ostream &os, const SeqStack &a) 34 { 35 for (int i = 0; i < a.top + 1; i++) 36 { 37 if (a.top == -1) 38 return os; 39 os << a.data[i]; 40 } 41 42 return os; 43 } 44 45 private: 46 elementType data[maxLength]; 47 int top; 48 }; 49 50 #endif // !defined(AFX_SEQSTACK1_H__55EE245C_A5F8_47D4_9510_B3BA6C85FF63__INCLUDED_)
1 // SeqStack1.cpp: implementation of the SeqStack class. 2 // 3 ////////////////////////////////////////////////////////////////////// 4 5 #include "stdafx.h" 6 #include "SeqStack1.h" 7 #include <iostream> 8 #include <iomanip> 9 10 ////////////////////////////////////////////////////////////////////// 11 // Construction/Destruction 12 ////////////////////////////////////////////////////////////////////// 13 using namespace std; 14 SeqStack::SeqStack() 15 { 16 top = -1; 17 } 18 19 SeqStack::~SeqStack() 20 { 21 } 22 23 bool SeqStack::stackEmpty() 24 { 25 return top == -1; 26 } 27 28 bool SeqStack::stackFull() 29 { 30 return top == maxLength - 1; 31 } 32 33 bool SeqStack::getTop( elementType& value ) 34 { 35 if( stackEmpty() ) 36 { 37 cout << "???ив????????ив" << endl; 38 return false; 39 } 40 value = data[top]; 41 return true; 42 } 43 44 bool SeqStack::push( elementType value ) 45 { 46 if( stackFull() ) 47 { 48 cout << "?и▓ив????ив" << endl; 49 return false; 50 } 51 top ++; 52 data[top] = value; 53 return true; 54 } 55 56 bool SeqStack::pop() 57 { 58 if( stackEmpty() ) 59 { 60 cout << "??ив????ив" << endl; 61 return false; 62 } 63 top --; 64 return true; 65 } 66 67 int SeqStack::length() 68 { 69 if( stackEmpty() ) 70 { 71 cout << "??ив" << endl; 72 return -1; 73 } 74 return top + 1; 75 } 76 77 void SeqStack::displayStack() 78 { 79 if( stackEmpty() ) 80 { 81 cout << "??ив????ив" << endl; 82 return; 83 } 84 int column = 0; 85 for( int i = 0; i <= top; i ++ ) 86 { 87 cout << setw(6) << setiosflags( ios::left ) << data[i]; 88 column ++; 89 if( column % 10 == 0 ) 90 cout << endl; 91 } 92 } 93 94 int SeqStack::isp( char _operator ) 95 { 96 switch(_operator) 97 { 98 case '#' : 99 return 0; 100 break; 101 case '(': 102 return 6; 103 break; 104 case '*': 105 return 5; 106 break; 107 case '/': 108 return 5; 109 break; 110 case '+': 111 return 3; 112 break; 113 case '-': 114 return 3; 115 break; 116 case ')': 117 return 1; 118 break; 119 } 120 121 cerr << "Error in SeqStack::isp" << endl; 122 return -1; 123 } 124 125 int SeqStack::icp( char _operator ) 126 { 127 switch(_operator) 128 { 129 case '#' : 130 return 0; 131 break; 132 case '(': 133 return 1; 134 break; 135 case '*': 136 return 4; 137 break; 138 case '/': 139 return 4; 140 break; 141 case '+': 142 return 2; 143 break; 144 case '-': 145 return 2; 146 break; 147 case ')': 148 return 6; 149 break; 150 } 151 152 cerr << "Error in SeqStack::icp" << endl; 153 return -1; 154 } 155 156 double SeqStack::doOperator( elementType value1, elementType value2, elementType1 _operator ) 157 { 158 switch(_operator) 159 { 160 case '+': 161 return value1 + value2; 162 break; 163 case '-': 164 return value1 - value2; 165 break; 166 case '*': 167 return value1 * value2; 168 break; 169 case '/': 170 if( fabs(value2) < 0.0001 ) 171 { 172 cout << "Divided by 0!" << endl; 173 return -1000000; 174 } 175 else 176 return value1 / value2; 177 break; 178 } 179 180 cerr << "Error in SeqStack::doOperator" << endl; 181 return -1; 182 } 183 184 void SeqStack::calculate( charSeqStack& css1, charSeqStack& css2 )//?????? css2 ?им????????? css1 ? 185 { 186 char ch, ch1; 187 int i = 0, j = 0; 188 double a, b; 189 css2.pop(); 190 css2.getTop(ch); 191 css2.pop(); 192 193 // when the top of css2 is not '#' or the top of css is not empty. 194 while( css1.topValue() != -1 || ch != '#' ) 195 { 196 // when the top of css2 is a number, put it into ss1 197 if( isdigit(ch) ) 198 { 199 push( (int)( ch - '0' ) ); 200 css2.getTop(ch); 201 css2.pop(); 202 } 203 204 // when the top of css2 is not a number, 205 else 206 { 207 css1.getTop(ch1); 208 if (ch1 == ')' && ch == '(') 209 { 210 css1.pop(); 211 css2.getTop(ch); 212 css2.pop(); 213 continue; 214 } 215 if( isp(ch1) < icp(ch) ) 216 { 217 css1.push(ch); 218 css2.getTop(ch); 219 css2.pop(); 220 } 221 else if( isp(ch1) >= icp(ch) ) 222 { 223 getTop(a); 224 pop(); 225 getTop(b); 226 pop(); 227 push( doOperator( a, b, ch1 ) ); 228 css1.pop(); 229 } 230 } 231 232 } 233 234 }
1 // charSeqStack.h: interface for the charSeqStack class. 2 // 3 ////////////////////////////////////////////////////////////////////// 4 5 #if !defined(AFX_CHARSEQSTACK_H__A9958AD3_333A_41B4_B399_B6895C7AA8C5__INCLUDED_) 6 #define AFX_CHARSEQSTACK_H__A9958AD3_333A_41B4_B399_B6895C7AA8C5__INCLUDED_ 7 8 #if _MSC_VER > 1000 9 #pragma once 10 #endif // _MSC_VER > 1000 11 12 #include <iostream> 13 using namespace std; 14 //using elementType1 = char; 15 typedef char elementType1; 16 //const int maxLength = 1000; 17 18 class charSeqStack 19 { 20 public: 21 charSeqStack(); 22 virtual ~charSeqStack(); 23 bool stackEmpty(); 24 bool stackFull(); 25 bool getTop( elementType1& value ); 26 bool push( elementType1 value ); 27 bool pop(); 28 int length(); 29 int topValue(); 30 void displayStack(); 31 friend ostream &operator<< (ostream &os, const charSeqStack &a) 32 { 33 for (int i = 0; i < a.top+2; i++) 34 { 35 if (a.top == -1) 36 return os; 37 os << a.data[i]; 38 } 39 40 return os; 41 } 42 43 private: 44 elementType1 data[maxLength]; 45 int top; 46 }; 47 48 49 #endif // !defined(AFX_CHARSEQSTACK_H__A9958AD3_333A_41B4_B399_B6895C7AA8C5__INCLUDED_)
1 // charSeqStack.cpp: implementation of the charSeqStack class. 2 // 3 ////////////////////////////////////////////////////////////////////// 4 5 #include "stdafx.h" 6 #include "charSeqStack.h" 7 #include <iostream> 8 #include <iomanip> 9 10 using namespace std; 11 ////////////////////////////////////////////////////////////////////// 12 // Construction/Destruction 13 ////////////////////////////////////////////////////////////////////// 14 15 charSeqStack::charSeqStack() 16 { 17 top = -1; 18 } 19 20 charSeqStack::~charSeqStack() 21 { 22 23 } 24 25 bool charSeqStack::stackEmpty() 26 { 27 return top == -1; 28 } 29 30 bool charSeqStack::stackFull() 31 { 32 return top == maxLength - 1; 33 } 34 35 bool charSeqStack::getTop( elementType1& value ) 36 { 37 if( stackEmpty() ) 38 { 39 value = '#'; 40 cout << "???ив????????ив" << endl; 41 return false; 42 } 43 value = data[top]; 44 return true; 45 } 46 47 bool charSeqStack::push( elementType1 value ) 48 { 49 if( stackFull() ) 50 { 51 cout << "?и▓ив????ив" << endl; 52 return false; 53 } 54 top ++; 55 data[top] = value; 56 return true; 57 } 58 59 bool charSeqStack::pop() 60 { 61 if( stackEmpty() ) 62 { 63 cout << "??ив????ив" << endl; 64 return false; 65 } 66 top --; 67 return true; 68 } 69 70 int charSeqStack::length() 71 { 72 if( stackEmpty() ) 73 { 74 cout << "??ив" << endl; 75 return -1; 76 } 77 return top + 1; 78 } 79 80 void charSeqStack::displayStack() 81 { 82 if( stackEmpty() ) 83 { 84 cout << "??ив????ив" << endl; 85 return; 86 } 87 int column = 0; 88 for( int i = 0; i <= top; i ++ ) 89 { 90 cout << setw(6) << setiosflags( ios::left ) << data[i]; 91 column ++; 92 if( column % 10 == 0 ) 93 cout << endl; 94 } 95 } 96 97 int charSeqStack::topValue() 98 { 99 return top; 100 }
1 // SeqStack.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "SeqStack1.h" 6 #include <iostream> 7 8 using namespace std; 9 int main(int argc, char* argv[]) 10 { 11 SeqStack ss1; 12 ss1.push(0); 13 charSeqStack css1, css2; 14 char Str[] = "#2+5*(2+3)*6/2-4#"; 15 //12+5*(2+3)*6/2-4 16 //char Str[] = "#(1+(5-3)*2+9)/2#"; 17 //char Str[] = "#(1+2)*3#"; 18 //char Str[] = "#(1)#"; 19 //char Str[] = "#1*2+3#"; 20 //char Str[] = "#1+1#"; 21 //char Str[] = "#1#"; 22 for( int i = 0; Str[i] != '