- 浏览: 865125 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
-
yukang1:
蚂蚁lovejing 写道我也出现与楼上相同的问题。查了一些资 ...
Spring中实现文件上传 -
史玉凤:
必须用ie浏览器
javascript获取客户端网卡MAC地址和IP地址和计算机名 -
蚂蚁lovejing:
我也出现与楼上相同的问题。查了一些资料,描述的跟楼主的博文差不 ...
Spring中实现文件上传 -
温柔一刀:
djlijian 写道最近也在研究redis,如何在项目中使用 ...
Redis 常见的性能问题和解决方法 -
djlijian:
最近也在研究redis,如何在项目中使用呢?感觉网上的资料太少 ...
Redis 常见的性能问题和解决方法
Stacks and queues are the first entities we have discussed that are not strictly built into Ruby. By this we mean that Ruby does not have Stack and Queue classes as it does Array and Hash classes (except for the Queue class in tHRead.rb, which we'll mention later).
And yet, in a way, they are built into Ruby after all. In fact, the Array class implements all the functionality we need to treat an array as a stack or a queue. We'll see this in detail shortly.
A stack is a last-in first-out (LIFO) data structure. The traditional everyday example is a stack of cafeteria trays on its spring-loaded platform; trays are added at the top and also taken away from the top.
A limited set of operations can be performed on a stack. These include push and pop (to add and remove items) at the very least; usually there is a way to test for an empty stack, and there may be a way to examine the top element without removing it. A stack implementation never provides a way to examine an item in the middle of the stack.
You might ask how an array can implement a stack since array elements may be accessed randomly, and stack elements may not. The answer is simple. A stack sits at a higher level of abstraction than an array; it is a stack only so long as you treat it as one. The moment you access an element illegally, it ceases to be a stack.
Of course, you can easily define a Stack class so that elements can only be accessed legally. We will show how this is done.
It is worth noting that many algorithms that use a stack also have elegant recursive solutions. The reason for this becomes clear with a moment's reflection. Function or method calls result in data being pushed onto the system stack, and these data are popped upon return. Thus a recursive algorithm simply trades an explicit user-defined stack for the implicit system-level stack. Which is better? That depends on how you value readability, efficiency, and other considerations.
A queue is a first-in first out (FIFO) data structure. It is analogous to a group of people standing in line at (for example) a movie theater. Newcomers go to the end of the line, while those who have waited the longest are the next served. In most areas of programming, queues are probably used less often than stacks.
Queues are useful in more real-time environments where entities are processed as they are presented to the system. They are useful in producer-consumer situations (especially where threads or multitasking are involved). A printer queue is a good example; print jobs are added to one end of the queue, and they "stand in line" until they are removed at the other end.
The two basic queue operations are usually called enqueue and dequeue in the literature. The corresponding instance methods in the Array class are called unpush and shift, respectively.
Note that unshift could serve as a companion for shift in implementing a stack, not a queue, because unshift adds to the same end from which shift removes. Various combinations of these methods could implement stacks and queues, but we will not concern ourselves with all the variations.
That ends our introductory discussion of stacks and queues. Now let's look at some examples.
9.2.1. Implementing a Stricter Stack
We promised earlier to show how a stack could be made "idiot-proof" against illegal access. We may as well do that now. Here is a simple class that has an internal array and manages access to that array. (There are other ways of doing thisby delegating, for examplebut what we show here is simple and works fine.)
class Stack def initialize @store = [] end def push(x) @store.push x end def pop @store.pop end def peek @store.last end def empty? @store.empty? end end
We have added one more operation that is not defined for arrays; peek simply examines the top of the stack and returns a result without disturbing the stack.
Some of the rest of our examples assume this class definition.
9.2.2. Detecting Unbalanced Punctuation in Expressions
Because of the nature of grouped expressions such as parentheses and brackets, their validity can be checked using a stack. For every level of nesting in the expression, the stack will grow one level higher; when we find closing symbols, we can pop the corresponding symbol off the stack. If the symbol does not correspond as expected, or if there are symbols left on the stack at the end, we know the expression is not well-formed.
def paren_match(str) stack = Stack.new lsym = "{[(<" rsym = "}])>" str.each_byte do |byte| sym = byte.chr if lsym.include? sym stack.push(sym) elsif rsym.include? sym top = stack.peek if lsym.index(top) != rsym.index(sym) return false else stack.pop end # Ignore non-grouped characters... end end # Ensure stack is empty... return stack.empty? end str1 = "(((a+b))*((c-d)-(e*f))" str2 = "[[(a-(b-c))], [[x,y]]]" paren_match str1 # false paren_match str2 # true
The nested nature of this problem makes it natural for a stack-oriented solution. A slightly more complex example would be the detection of unbalanced tags in HTML and XML. The tokens are multiple characters rather than single characters, but the structure and logic of the problem remain exactly the same. Some other common stack-oriented problems are conversion of infix expressions to postfix form (or vice versa), evaluation of a postfix expression (as is done in a Java VM or many other interpreters), and in general any problem that has a recursive solution. In the next section, we'll take a short look at the relationship between stacks and recursion.
9.2.3. Understanding Stacks and Recursion
As an example of the isomorphism between stack-oriented algorithms and recursive algorithms, we will take a look at the classic "Tower of Hanoi" problem.
According to legend, there is an ancient temple somewhere in the far east, where monks have the sole task of moving disks from one pole to another while obeying certain rules about the moves they can make. There were originally 64 disks on the first pole; when they finished, the world would come to an end.
As an aside, we like to dispel myths when we can. It seems that in reality, this puzzle originated with the French mathematician Edouard Lucas in 1883 and has no actual basis in eastern culture. What's more, Lucas himself named the puzzle the "Tower of Hanoi" (in the singular).
So if you were worried about the world ending . . . don't worry on that account. And anyway, 64 disks would take 264-1 moves. A few minutes with a calculator reveals that those monks would be busy for millions of years.
But on to the rules of the game. (We'll explain this even though every first-year computer science student in the world has already seen the puzzle.) We have a pole with a certain number of disks stacked on it; call this the source pole. We want to move all of these to the destination pole, using a third (auxiliary) pole as an intermediate resting place. The catch is that you can only move one disk at a time, and you cannot ever place a larger disk onto a smaller one.
The following example uses a stack to solve the problem. We use only 3 disks because 64 would occupy a computer for centuries.
def towers(list) while !list.empty? n, src, dst, aux = list.pop if n == 1 puts "Move disk from #{src} to #{dst}" else list.push [n-1, aux, dst, src] list.push [1, src, dst, aux] list.push [n-1, src, aux, dst] end end end list = [] list.push([3, "a", "c", "b"]) towers(list)
The output produced here is:
Move disk from a to c Move disk from a to b Move disk from c to b Move disk from a to c Move disk from b to a Move disk from b to c Move disk from a to c
Of course, the classic solution to this problem is recursive. And as we already pointed out, the close relationship between the two algorithms is no surprise because recursion implies the use of an invisible system-level stack.
def towers(n, src, dst, aux) if n==1 puts "Move disk from #{src} to #{dst}" else towers(n-1, src, aux, dst) towers(1, src, dst, aux) towers(n-1, aux, dst, src) end end towers(3, "a", "c", "b")
The output produced here is the same. And it may interest you to know that we tried commenting out the output statements and comparing the runtimes of these two methods. Don't tell anyone, but the recursive version is twice as fast.
9.2.4. Implementing a Stricter Queue
We define a queue here in much the same way we defined a stack earlier. If you want to protect yourself from accessing such a data structure in an illegal way, we recommend this practice.
class Queue def initialize @store = [] end def enqueue(x) @store << x end def dequeue @store.shift end def peek @store.first end def length @store.length end def empty? @store.empty? end end
We should mention that there is a Queue class in the thread library that works very well in threaded code. There is even a SizedQueue variant.
These queues use the method names enq and deq rather than the longer names shown in the preceding example. They also allow the names push and pop, which seems misleading to me. The data structure is FIFO, not LIFO; that is, it is a true queue and not a stack.
Of course, the Queue class in tHRead.rb is thread-safe, which is a good enough reason for it to exist. If you need a thread-safe Stack class, I recommend you take the Queue class as a starting point. This should be a quick and easy fix.
The first edition of this book had a lengthy example of queue usage here. Like some of the stack examples, it has been omitted from this edition to save space.
发表评论
-
Query
2008-01-31 17:39 48class System::FastQuery de ... -
Fast Query
2008-01-19 15:07 4052class System::FastQuery def s ... -
9.3. Working with Trees
2008-01-19 15:06 3841I think that I shall never se ... -
9.1. Working with Sets
2008-01-19 15:03 3400We've already seen how certain ... -
8.3. Enumerables in General
2008-01-19 14:26 3543What makes a collection enumera ... -
8.2. Working with Hashes
2008-01-19 14:25 3797Hashes are known in some circle ... -
计算两个字符串之间的Levenshtein距离
2008-01-09 23:32 5231Levenshtein距离 class String ... -
字符串的编码和解码
2008-01-09 23:11 3869rot13编码和解码 class String def r ... -
rails应用自动化部署——使用capistrano2.0
2007-10-10 18:59 6311昨天用capistrano2.0把应用部署搞的比较自动化了一点 ... -
selenium和ajax的测试问题
2007-08-13 15:51 6647Hi,all I am having doubts in se ... -
在selenium测试中使用ActiveRecord
2007-08-10 18:15 5154ActiveRecord是rails的框架,我们在seleni ... -
关于rails应用的验收测试
2007-08-08 18:26 4784ruby的测试运行的本来都慢,selenium的验收测试跑起来 ... -
Exception: Bad file descriptor - connect(2)
2007-08-07 15:59 5507Hi,all I am trying to test web ...
相关推荐
9.2. Python Scopes and Namespaces 91 9.2.1. Scopes and Namespaces Example 94 9.3. A First Look at Classes 95 9.3.1. Class Definition Syntax 95 9.3.2. Class Objects 96 9.3.3. Instance Objects 97 9.3.4....
PEP 492 - Coroutines with async and await syntax PEP 465 - A dedicated infix operator for matrix multiplication PEP 448 - Additional Unpacking Generalizations PEP 461 - percent formatting support ...
3.2 Stacks and Queues 3.3 Dictionaries 3.4 Binary Search Trees 3.5 Priority Queues 3.6 War Story: Stripping Triangulations 3.7 Hashing and Strings 3.8 Specialized Data Structures 3.9 War Story...
hhhhh安卓开发教程大全
avem-labs_Avem_1740990015.zip
微信群机器人管理系统源码 微信群机器人管理系统源码 支持同登陆多个微信 源码类型: C/S 开发环境: VS2010 SQL2008R2 菜单功能 1、支持同时登录多个微信 2、支持机器人聊天(笑话,成语接龙、故事会、智力等等) 3、支持签到 4、可自定义回复 5、可自定义红包语 6、支持定期发送公告(如群规,广告)等 1、WeChatRobots后台配置web版 2、数据库在WeiChartGroup.Net/app_data中,附加即可
https://upload.csdn.net/creation/uploadResources?spm=1003.2018.3001.4314
名字微控制器_STM32_课程_DeepBlue_1740989720.zip
S7-200Smart恒压供水程序示例与485通讯实践:操作指南与案例解析,S7-200 Smart可编程控制器恒压供水程序设计与实现,附带485通讯范例,S7-200Smart 恒压供水程序样例+485通讯样例 ,S7-200Smart; 恒压供水程序样例; 485通讯样例,S7-200Smart程序样例:恒压供水及485通讯应用示例
Java使用JNA、JNI两种不同方式调用DLL、SO动态库方式读写M1卡源码,支持读写M1卡扇区数据、修改IC卡扇区密钥、改写UID卡卡号等功能,支持Windows系统,同时支持龙芯Mips、LoongArch、海思麒麟鲲鹏飞腾Arm、海光兆芯x86_Amd64等架构平台的国产统信、麒麟等Linux系统,内有jna-4.5.0.jar包,vx13822155058 qq954486673
UDP协议接收和发送数据示例JAVA
本文介绍了范德堡大学深脑刺激器(DBS)项目,该项目旨在开发和临床评估一个系统,以辅助从规划到编程的整个过程。DBS是一种高频刺激治疗,用于治疗运动障碍,如帕金森病。由于目标区域在现有成像技术中可见性差,因此DBS电极的植入和编程过程复杂且耗时。项目涉及使用计算机辅助手术技术,以及一个定制的微定位平台(StarFix),该平台允许在术前进行图像采集和目标规划,提高了手术的精确性和效率。此外,文章还讨论了系统架构和各个模块的功能,以及如何通过中央数据库和网络接口实现信息共享。
图像识别”项目源码资源(Python和C++)
虚拟同步电机与并电网模型的Simulink仿真参数配置与直接使用指南,虚拟同步电机与并电网模型的Simulink仿真:参数齐全,直接使用,同步电机simulink仿真 并电网模型仿真 参数设置好了,可直接使用 ,虚拟同步电机; simulink仿真; 并电网模型仿真; 参数设置; 使用,虚拟同步电机Simulink仿真与并电网模型参数化应用
三菱FX3U与力士乐VFC-x610变频器通讯案例详解:PLC控制下的变频器操作与设置程序,含接线方式及昆仑通态触摸屏操作指南,三菱FX3U与力士乐VFC-x610变频器通讯案例详解:接线、设置与程序注解,实现频率设定、启停控制与实时数据读取功能。,三菱FX3U与力士乐VFC-x610变频器通讯程序三菱FX3U与力士乐VFC-x610变频器通讯案例程序,有注释。 并附送程序,有接线方式,设置。 器件:三菱FX3U的PLC,力士乐VFCx610变频器,昆仑通态,威纶通触摸屏。 功能:实现频率设定,启停控制,实际频率读取等。 ,三菱FX3U;力士乐VFC-x610变频器;通讯程序;案例程序;注释;接线方式;设置;频率设定;启停控制;实际频率读取;昆仑通态;威纶通触摸屏。,三菱FX3U与力士乐VFC-x610变频器通讯程序及案例:频率控制与读取实践
xmselect测试用例~~~~~~~~~~~~~~
总共包含 32 款 AAA 级科幻武器。四种武器类型,每种有 8 种不同的纹理变化! 所有内容均采用 PBR 材质,可直接用于开发游戏!
python词云生成器,将txt文本自动分割生成词云图
智慧园区,作为现代城市发展的新形态,旨在通过高度集成的信息化系统,实现园区的智能化管理与服务。该方案提出,利用智能手环、定制APP、园区管理系统及物联网技术,将园区的各类设施与设备紧密相连,形成一个高效、便捷、安全的智能网络。从智慧社区到智慧酒店,从智慧景区到智慧康养,再到智慧生态,五大应用板块覆盖了园区的每一个角落,为居民、游客及工作人员提供了全方位、个性化的服务体验。例如,智能手环不仅能实现定位、支付、求助等功能,还能监测用户健康状况,让科技真正服务于生活。而智慧景区的建设,更是通过大数据分析、智能票务、电子围栏等先进技术,提升了游客的游玩体验,确保了景区的安全有序。 尤为值得一提的是,方案中的智慧康养服务,展现了科技对人文关怀的深刻体现。通过智慧手环与传感器,自动感知老人身体状态,及时通知家属或医疗机构,有效解决了“空巢老人”的照护难题。同时,智慧生态管理系统的应用,实现了对大气、水、植被等环境要素的实时监测与智能调控,为园区的绿色发展提供了有力保障。此外,方案还提出了建立全域旅游营销平台,整合区域旅游资源,推动旅游业与其他产业的深度融合,为区域经济的转型升级注入了新的活力。 总而言之,这份智慧园区建设方案以其前瞻性的理念、创新性的技术和人性化的服务设计,为我们展示了一个充满智慧与活力的未来园区图景。它不仅提升了园区的运营效率和服务质量,更让科技真正融入了人们的生活,带来了前所未有的便捷与舒适。对于正在规划或实施智慧园区建设的决策者而言,这份方案无疑提供了一份宝贵的参考与启示,激发了他们对于未来智慧生活的无限遐想与憧憬。
使用 SignalR 在 .NET Core 8 最小 API 中构建实时通知,构建实时应用程序已成为现代 Web 开发中必不可少的部分,尤其是对于通知、聊天系统和实时更新等功能。SignalR 是 ASP.NET 的一个强大库,可实现服务器端代码和客户端 Web 应用程序之间的无缝实时通信。 参考文章:https://blog.csdn.net/hefeng_aspnet/article/details/145990801