数据结构-C语言代码 day6-栈及其应用

一、栈的定义

栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说,表尾端称为栈顶(top),表头端称为栈低(bottom)。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除,所以栈又被称为后进先出的线性表。

二、栈的基本操作

1.栈的结构体

typedef struct CharStack 
{
    int top;
    int data[STACK_MAX_SIZE]; 
} *CharStackPtr;

2.初始化

CharStackPtr charStackInit() 
{
	CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
	resultPtr->top = -1;

	return resultPtr;
}

3.打印

void outputStack(CharStackPtr paraStack) 
{
    for (int i = 0; i <= paraStack->top; i ++)
    {
        printf("%c ", paraStack->data[i]);
    }
    printf("\r\n");
}

4.压栈

void push(CharStackPtr paraStackPtr, int paraValue)
{
    // 空间检查(是否栈满)
    if (paraStackPtr->top >= STACK_MAX_SIZE - 1) 
    {
        printf("堆栈已满,无法添加.\r\n");
        return;
    }

    // 顶部更新.
	paraStackPtr->top ++;

	// 入栈.
    paraStackPtr->data[paraStackPtr->top] = paraValue;
}

5.弹栈 

char pop(CharStackPtr paraStackPtr) 
{
    // 空间检查(判断空栈).
    if (paraStackPtr->top < 0) 
    {
        printf("堆栈为空,无法弹出.\r\n");
        return '\0';
    }

    // 顶部更新.
	paraStackPtr->top --;

    return paraStackPtr->data[paraStackPtr->top + 1];
}

 

6.功能测试

void pushPopTest() 
{
    printf("栈的进出开始测试:\r\n");

	// 初始化
    CharStackPtr tempStack = charStackInit();
    printf("初始化后的栈: ");
	outputStack(tempStack);

	// 压栈
	for (char ch = 'a'; ch < 'n'; ch ++) 
    {
		printf("添加 %c.\r\n", ch);
		push(tempStack, ch);
		outputStack(tempStack);
	}//Of for i

	// 弹栈
	for (int i = 0; i < 4; i ++) 
    {
		char ch = pop(tempStack);
		printf("删除 %c.\r\n", ch);
		outputStack(tempStack);
	}

    printf("测试结束\r\n");
}

测试结果

栈的进出开始测试:
初始化后的栈:
添加 a.
a
添加 b.
a b
添加 c.
a b c
添加 d.
a b c d
添加 e.
a b c d e
添加 f.
a b c d e f
添加 g.
a b c d e f g
添加 h.
a b c d e f g h
添加 i.
a b c d e f g h i
添加 j.
a b c d e f g h i j
添加 k.
堆栈已满,无法添加.
a b c d e f g h i j
添加 l.
堆栈已满,无法添加.
a b c d e f g h i j
添加 m.
堆栈已满,无法添加.
a b c d e f g h i j
删除 j.
a b c d e f g h i
删除 i.
a b c d e f g h
删除 h.
a b c d e f g
删除 g.
a b c d e f
测试结束

三、括号匹配

 借助栈

bool bracketMatching(char* paraString, int paraLength) 
{
	// 通过在底部压入“#”来初始化堆栈
    CharStackPtr tempStack = charStackInit();
	push(tempStack, '#');
	char tempChar, tempPopedChar;

	// 处理字符串
	for (int i = 0; i < paraLength; i++) {
		tempChar = paraString[i];

		switch (tempChar) {
		case '(':
		case '[':
		case '{':
			push(tempStack, tempChar);
			break;
		case ')':
			tempPopedChar = pop(tempStack);
			if (tempPopedChar != '(') {
				return false;
			}
			break;
		case ']':
			tempPopedChar = pop(tempStack);
			if (tempPopedChar != '[') {
				return false;
			}			break;
		case '}':
			tempPopedChar = pop(tempStack);
			if (tempPopedChar != '{') {
				return false;
			}
			break;
		default:
			break;
		}
	}

	tempPopedChar = pop(tempStack);
	if (tempPopedChar != '#') 
    {
		return true;
	}

	return true;
}

功能测试

void bracketMatchingTest() 
{
    printf("括号匹配测试开始:\r\n");
	char* tempExpression = "{6+3-[1+2*(6-2)]}/2";
	bool tempMatch = bracketMatching(tempExpression, 17);
	printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);


	tempExpression = "[1+2*8)(]";
	tempMatch = bracketMatching(tempExpression, 6);
	printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);

	tempExpression = "({[]})";
	tempMatch = bracketMatching(tempExpression, 8);
	printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);

	tempExpression = "()()[]";
	tempMatch = bracketMatching(tempExpression, 6);
	printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);


	tempExpression = "{]()";
	tempMatch = bracketMatching(tempExpression, 2);
	printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);
    printf("测试结束\r\n");
}

测试结果

括号匹配测试开始:
'{6+3-[1+2*(6-2)]}/2'是否括号匹配? 1
'[1+2*8)(]'是否括号匹配? 1
'({[]})'是否括号匹配? 1
'()()[]'是否括号匹配? 1
'{]()'是否括号匹配? 0
测试结束

四、表达式求值

//属实是难到了,C++还有很多不理解的地方,主要还是在观摩学习,以下为学长代码,只用了两个栈便实现了表达式求值的功能。

1.#include <cstring>:可以使用很多实用的字符串函数;

2.#include<algorithm>:algorithm意为"算法",是C++的标准模版库(STL)中最重要的头文件之一,提供了大量基于迭代器的非成员模版函数;

3.#include < stack > include < stack >为C++ STL栈stack的 头文件 ,是STL中实现的一个后进先出的容器:

stack<int>num//声明一个对象

str.size()//返回栈中元素个数于X

num.pop()//移除栈顶元素

num.push(x)//将X置于栈顶

op.top()//返回栈顶元素

4.unordered_map是一种关联容器,存储基于键值和映射组成的元素,即key-value。允许基于键快速查找元素。unordered_map中,键值唯一标识元素,映射的值是一个与该对象关联的内容的对象

5.auto是一个C/C++语言存储类型,仅在语句块内部使用,初始化可为任何表达式,其特点是当执行流程进入该语句块的时候初始化可为任何表达式。

//202031061018 刘知鑫
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <unordered_map>

using namespace std;

stack<int> num;
stack<char> op;

void eval()
{
    auto b = num.top();
    num.pop();
    auto a = num.top();
    num.pop();
    auto c = op.top();
    op.pop();
    int x;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == '*') x = a * b;
    else x = a / b;
    num.push(x);
}

int main()
{
    unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
    string str;
    cin >> str;
    for (int i = 0; i < str.size(); i ++ )
    {
        auto c = str[i];
        if (isdigit(c))
        {
            int x = 0, j = i;
            while (j < str.size() && isdigit(str[j]))
                x = x * 10 + str[j ++ ] - '0';
            i = j - 1;
            num.push(x);
        }
        else if (c == '(') op.push(c);
        else if (c == ')')
        {
            while (op.top() != '(') eval();
            op.pop();
        }
        else
        {
            while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
            op.push(c);
        }
    }
    while (op.size()) eval();
    cout << num.top() << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值