这里是闲话:在上一篇文章(详见https://blog.csdn.net/jokerCe/article/details/114139123)中,我们已经实现了栈的最基本操作,那么在本篇文章中,我们便可以用已实现的数据结构来完成一些小应用,包括数值转换、括号匹配、行编辑程序,并给出必要的实验结果。
在下文内容中,我们应着重思考栈的特性——“后进先出”(FILO)在这几个应用中起到的作用,以下内容仅供参考~
这里是目录:
一、数值转换
1、 算法思想:
求进制转化使一般从高位到低位进行,恰好和计算过程相反。该算法可以使十进制整数转化为N进制整数(N∈(1,10)),每次取余之后把余数入栈保存,保存N进制整数最后从栈顶输出。
例如:将10进制的18转化为3进制
18/3=6..........0
6/3=2............0
2/3=0............2
∴10进制的18用3进制表示为:200
2、代码实现:
//对于输入的任意一个非负十进制整数,打印输出与其等值的N进制数(N<10)
void concersion_10toN() {
SqStack S;
InitStack(S);
int a, N;
cout << "请输入一个非负十进制整数:" << endl;
while (cin >> a && a < 0)
cout << "请输入非负十进制整数!" << endl;
cout << "你要转化为几进制?(1<N<10)" << endl;
while (cin >> N && (N <= 1 || N >= 10))
cout << "进制N应在以下范围:(1,10)!" << endl;
while (a) {
Push(S, a % N);
a /= N;
}
for (int i = S.top - 1; i >= 0; i--)
cout << S.elem[i];
cout << endl;
}
二、括号匹配
1、算法思想:
括号匹配要求表达式中允许包含两种括号:圆括号和方括号,嵌套的格式随意但必须匹配,例如 [()[]] 为正确格式。因此可以用“期待的急迫程度”来描述括号匹配的优先级。该算法可根据以下原则(左)列出解决方法(右):
①表达式中可以连续接收多个左括号,且越后接受的括号急迫程度越高→用栈的数据来接受左括号元素(先进后出,以保证最后的括号先匹配)
②计算机接受右括号时,必须有最急迫对应左括号与其匹配→判断括号是否匹配,若匹配成功则将左括号出栈
2、代码实现:
bool ParenthesisMatch(char str[]) {
SqStack S;
InitStack(S);
bool flag;
for (int i = 0; i < strlen(str); i++) {
SElemType e;
if (str[i] == '(' || str[i] == '{' || str[i] == '[')
Push(S, str[i]);
else if ((str[i] == ')' && Top(S) == '(')
|| (str[i] == '}' && Top(S) == '{')
|| (str[i] == ']' && Top(S) == '['))
Pop(S, e);
else {
flag = false;
break;
}
}
if (StackLength(S) == 0) flag = true;
else flag = false;
ClearStack(S);
return flag;
}
3、运行结果及检验:
①检验问题:输入[()[]]、[(][]]
②理论结果:OK!、ERROR!
③实际结果:
经检验,实际结果符合理论。
三、行编辑程序
1、算法思想:
问题的关键在于设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区,同时这个缓冲区允许输入有误是进行当前行的更正。因此可以设这个输入缓存区为一个栈结构,每当终端接受一个字符后可以做如下判断和操作:
①如果它不是退格符也不是退行符,该字符进栈;
②如果它是退格符,字符栈出栈;
③如果它是退行符,字符栈清为空栈。
2、代码实现:
void LineEdit() {
//利用字符栈S,从终端接收一行并传送只调用过程的数据区。
SqStack S;
InitStack(S);//构建并初始化栈S
char ch;
ch = cin.get();//从终端读入单个字符ch
SElemType e;
while (ch != EOF) {//EOF为全文结束符
while (ch != EOF && ch != '\n') {
switch (ch) {
case '#': Pop(S, e); break;
case '@': ClearStack(S); break;
default: Push(S, ch);
}
ch = cin.get();
}
//输出语句进行验证
for (int i = 0; i < S.top; i++)
cout << S.elem[i];
cout << endl;
ClearStack(S);
if (ch != EOF) ch = cin.get();
}
}
3、运行结果及检验:
①检验问题:终端接受以下两行字符
Whli##ile#e(s#*s)
outcha@putchar(*s=#++);
②理论结果:
While(*s)
putchar(*s++);
③实际结果:
经检验,实际结果符合理论。
这里还是闲话:有关栈的三种简单应用就此结束啦,思路其实不难。下一篇文章是关于栈的另外两个应用——迷宫求解和表达式求值,有兴趣的伙伴可以继续浏览噢~
这里是链接:https://blog.csdn.net/jokerCe/article/details/114144322