当前位置: 首页 > news >正文

建电子商务网站费用做网络推广有前途吗

建电子商务网站费用,做网络推广有前途吗,从代码角度分析网站怎么做,安防网站建设优点文章目录 前言stack栈的题目最小栈JZ31 栈的压入、弹出序列150. 逆波兰表达式求值 stack的模拟实现queue的模拟实现dequedeque底层设计 前言 栈和队列这一块其实有数据结构的基础,学起来非常简单。 stack 栈的成员函数就这么写,除了emplace其他都已经非…

文章目录

  • 前言
  • stack
  • 栈的题目
    • 最小栈
    • JZ31 栈的压入、弹出序列
    • 150. 逆波兰表达式求值
  • stack的模拟实现
  • queue的模拟实现
  • deque
    • deque底层设计

前言

栈和队列这一块其实有数据结构的基础,学起来非常简单。

stack

在这里插入图片描述
栈的成员函数就这么写,除了emplace其他都已经非常熟悉了。

stack没有迭代器吗?
没有,因为栈已经不是容器了,它是容器适配器。给它一个迭代器还能保证先进先出这些吗?不能。

stack跟我们之前学的list其实很不太一样。
在这里插入图片描述
模板参数不同。
在这里插入图片描述

先快速用一下stack,让它跑起来。

void test_stack()
{stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;
}

在这里插入图片描述

栈的题目

最小栈

接下来我们做题来加深一下对stack的理解。
最小栈

在这里插入图片描述

思路

首先定义两个栈,一个栈是正常的栈,实现正常的操作。
我们用另一个栈是最小栈,来实现O(1)检索到最小元素的栈。

这里要不要写那4个默认成员函数?
在这里插入图片描述
不用。

push
如果是空栈或者需要push的数据小于最小栈栈顶元素,我们就push.否则最小栈不做处理。
在这里插入图片描述

注意,如果需要push的数据等于栈顶元素也要push,否则pop的时候会把最小值也pop掉

pop
如果最小栈的栈顶元素和正常栈的栈顶元素相等我们就pop

class MinStack {
public:
//不用写MinStack() {}void push(int val) {_st.push(val);if (_minst.empty() || val <= _minst.top()){_minst.push(val);}}void pop() {if (_minst.top() == _st.top()){_minst.pop();}_st.pop();}int top() {return _st.top();}int getMin() {return _minst.top();}
private:stack<int> _st;stack<int> _minst;
};

优化
在这里插入图片描述
如果是这样那不是很浪费。

可以这样优化,每个地方不是存一个值而是存一个结构。
在这里插入图片描述
给大家看一下结构,具体实现就先不实现了。

stack<int> _st;
struct Data
{int _val;int _count;
}
stack<Date> _minst;

这就是模板的好处,如果没有模板,那自己还需要再写一个栈。

JZ31 栈的压入、弹出序列

栈的压入、弹出序列
在这里插入图片描述
在这里插入图片描述
这道题稍有不慎就会写的很复杂,如果想清楚了也挺简单的。

在这里插入图片描述
不匹配的一种情况
在这里插入图片描述

思路
这道题有很多种思路,最简单的就是用一个栈模拟入栈出栈的过程。
如果能模拟出来就匹配了,如果模拟不出来就不行。

所以我们的重点在于模拟这个栈。

先要第一个出4,那就入数据1234。只要不匹配就入数据。
在这里插入图片描述

下一个出5,不匹配继续入
在这里插入图片描述
再看下一个要出的数据是不是栈顶的元素,是就直接出。
在这里插入图片描述
如果能把入栈序列走完,出栈序列也走完,那就匹配了。

在这里插入图片描述
以pushi为主要的,因为popi不一定能走到结尾。
第一步,入栈
第二步,判断是否要出栈(注意不一定只出一次)

在这里插入图片描述

凡是这样写一定要小心,栈出了一个,然后栈空了。

空栈调用会报错。

怎么样匹配?
两种方式
1.popi走到尾了
2.栈为空
在这里插入图片描述

150. 逆波兰表达式求值

逆波兰表达式求值

在这里插入图片描述

在这里插入图片描述

中缀表达式
我们平时写的式子都是中缀表达式。但是计算机对于中缀表达式没办法直接运算。
比如1+2*(3-2),计算机遇到操作数的时候是不敢运算的,因为还涉及到优先级。

后缀表达式
所以我们先把优先级给确定出来。
后缀就是优先级已经按先后顺序确定了。
在这里插入图片描述
上面的这道题就是用后缀表达式求出结果?省去了中缀转后缀的过程,所以难度大大降低了。

运算后缀表达式
用一个栈就搞定了。
在这里插入图片描述
过程
操作数入栈
在这里插入图片描述
操作符计算
先出的是右操作数。计算,结果入栈。

在这里插入图片描述

最后
在这里插入图片描述

这道题不难,但是你要理解一个逆波兰表达式为什么可以这样算,你就要理解中缀怎么转后缀。

代码实现
在这里插入图片描述
怎么确定是操作数还是操作符?
这里有个小坑,如果操作不当,减号和负数会混。
在这里插入图片描述

最简单的方式是用一个字符串的比较就可以了
操作数入栈
在这里插入图片描述

操作符出栈,计算。
在这里插入图片描述

如何中缀转后缀?
在这里插入图片描述

在这里插入图片描述

注意,输出并不指的是打印,而是说把数据放到一个容器里保存起来。

在这里插入图片描述

跟栈顶操作符比较,优先级更高,不能直接输出,因为后面可能还有优先级更高的。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

然后回到之前第一步,操作数输出
在这里插入图片描述

综上所述,我们便可以看到为什么后缀运算可以利用一个栈来进行模拟?
中缀转后缀的时候。
操作符出的时候,跟我相邻的两个数,就是要跟这个操作符的两个数运算,结果作为操作数又进行运算。
中缀转后缀就是这样转的,它的规则就是这样的。
在这里插入图片描述
操作符出了,我要让两个操作数一定是在我的前面。那我怎么找到最近的两个操作数呢?
栈的后进先出刚刚好

很巧很巧,像发明栈的大佬致敬。

真正麻烦处理的还是带括号的。
比如1 + 2*(4 - 5)+ 6/7;

可以尝试先把后缀表达式写出来。

flag的解决方式
flag0的时候正常处理。
flag
1的时候说明遇到括号了。
下一个的运算符优先级是高。
在这里插入图片描述
不用flag的解决方式
这里就先不讲了。

stack的模拟实现

栈的实现有两种方式。
1.数组栈,尾部当作栈顶。
2.链表栈,头部当作栈顶。
数组栈更有优势一点。

传统的写法,无非就是搞一个数组,不够了就扩容。
我们这里用一个适配器的玩法。
在这里插入图片描述

适配器的本质是什么?
现实生活中,我们的充电头也叫电源适配器。电源适配器是干嘛的?是生产电源的吗?
其实是用来变压的。
所以适配器的本质是用来转换的,把原来的东西给转换过来。

容器适配器,它不是自己存储数据,它是把已有的东西进行转换。

我们要实现一个顺序栈,链表栈,我们需要自己写吗?
我们可以拿一个已有的容器封装,这样写起来更简单。
在这里插入图片描述
但是这还不是适配,还要转换。
再增加一个模板参数,Container,他具体是啥我也不知道,但是它肯定是符合我们要求的容器。
在这里插入图片描述

要实现顺序栈,传vector.
要实现链表栈,传list.

namespace but
{template<class T, class Container>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}const T& top(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private://vector<T> _v;Container _con;};void test_stack(){stack<int, vector<int>> st;//顺序栈//stack<int, list<int>> st;//链式栈//stack<int> st //缺省类型st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;}
}

还可以给缺省类型。

template<class T, class Container= vector<T>>

函数传参如果不从右往左会有歧义。
在这里插入图片描述
假设传两个参数,你就不知道传给谁了。

queue的模拟实现

快速手搓。

namespace but
{template<class T, class Container = list<T>>class queue{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}const T& front(){return _con.front();}const T& back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};void test_queue(){queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;}
}

队列还能不能用vector适配?
队列要头插尾删,vector不支持头删。如果强行用erase,效率有点低。

在实现队列的头文件里没有包括vector和list为什么还能用?
如果编译它是会报错的,但是编译器不编译它。.h是不会被编译的,它是在包含的地方展开,然后编译器向上找。
在这里插入图片描述
这样写就不行了
在这里插入图片描述

为什么?
因为c和c++编译的时候都有一个特点,他不会在整个文件里面找。一展开像上去找,找不到vector,因为vector在std里面,又没有指定std.

在命名空间里只有指定或者展开才能找到。

从string开始,只写.h,不写cpp,为什么?
从规范角度来说肯定要写的,模板不能这么写,这样写出来是有问题的。
你可以尝试用声明和定义分离写一下stack。
在这里插入图片描述
为什么又找不到vector?
stack.cpp这里展开.h,又找不到vector.
在这里插入图片描述

声明和定义分离会导致很多问题,他会导致链接错误。链接错误就是找不到定义。
模板不能声明和定义分离。

deque

在这里插入图片描述
栈的默认,默认容器用了一个deque的东西,这个东西是啥?
deque虽然是队列,但它不是正队列,它是双端队列。

deque对标的是vector+list.

它的结构和前面没有什么差别。
在这里插入图片描述

这些功能只有我们之前讲的list能做到。
在这里插入图片描述

最牛逼的是还有这个
在这里插入图片描述

看,它既支持vector的功能又支持list的功能。

但是这个东西真的这么牛吗?
要回答这个问题,我们得看一下deque的底层设计。

deque底层设计

我们先来分析一下顺序表和链表的区别。

顺序表:
它最大的优点就是空间连续随机访问,但是也带来了,头插,中间插入删除的困难。
在这里插入图片描述

其实顺序表还有一个优点就是高速缓存效率高,但是这里学习的时候不作为重点。

链表:
在这里插入图片描述

能不能把这两个合二为一呢?

http://www.yidumall.com/news/33162.html

相关文章:

  • 深圳著名设计网站大全西地那非片
  • 知名b2b网站一个具体网站的seo优化
  • 佳木斯城乡建设局网站网络服务包括
  • 做非法网站判什么邢宁波好的seo外包公司
  • 封面型网页网站有哪些郑州疫情最新动态
  • 开发app商城软件的公司网站推广优化方案
  • 产品推广方案范本优化设计一年级下册数学答案
  • 微信打不开网站网站站内推广怎么做
  • 如何自己做网站一年赚一亿百度推广怎么收费的
  • 网站建设免费模版手机关键词排名优化
  • 做满屏网站的尺寸电脑编程培训学校
  • 濮阳网站建设哪里便宜企业网站建设方案范文
  • 搭建网站教程视频营销管理
  • 做网站 大文件b站推广入口
  • 中国林业工程建设网站泉州网站建设
  • 网站备案回访问题郑州seo优化大师
  • html5 手机网站 模板seo是什么意思啊
  • 宁波高等级公路建设指挥部网站站长交流平台
  • 可以做批发的跨境电商网站平台重庆seo排名优化
  • 网站框架建设中国域名网官网
  • 商城微网站模板百度seo一本通
  • 湖北可以做网站的公司企业站seo案例分析
  • 有做网站需求的客户搜索引擎哪个最好用
  • 四川专业网站建设推广优化网站建设
  • 做图赚钱的网站有哪些seo软文推广工具
  • 软件编程技术培训机构seo信息是什么
  • 调研报告 政府网站建设企业网址怎么注册
  • 关于网站制作的文案凡科建站怎么收费
  • 问答类网站开发站长工具使用方法
  • wordpress建网站的优点百度推广外包哪家不错