vector stack(堆栈)有啥不一样和一样的地方?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vector stack(堆栈)有啥不一样和一样的地方?相关的知识,希望对你有一定的参考价值。

vector 可以代替stack 使用么,怎么代替
成员函数有什么?对应什么?

vector可以替代stack,stack仅支持一端操作(push,pop),而vector除此之外(push_back,pop_back)还支持中间插入(insert)、‘移除(erase),所以要用vector替代stack如有:

/*
struct TreeNode 
    int val;
    TreeNode *left;
    TreeNode *right;
;
*/
stack<TreeNode*> s;
s.push(root);
while(!s.empty()) 
    TreeNode *tmp = s.top();
    if(tmp != NULL) 
        cout << tmp->val; // visit node.
        s.push(tmp->right);
        s.push(tmp->left);
    

想直接替换可以改为:

vector<TreeNode*> s;
s.push_back(root);
while(!s.empty()) 
    TreeNode *tmp = s.back();
    if(tmp != NULL) 
        cout << tmp->val; // visit node.
        s.push_back(tmp->right);
        s.push_back(tmp->left);
    

在STL中stack本身就是一个容器适配器,默认情况是以deque实现:

template < class T, class Container = deque<T> > class stack;

这里的Container必须supports the following operations:

front()
back()
push_back()
pop_back()

而vector就满足这些条件,所以要用vector替代deque作为stack的底层容器,只需这样定义即可:

stack<TreeNode*, vector<TreeNode*> >  stk;

关于C++标准库的细节可以参考C++官方参考:
http://www.cplusplus.com/reference/ (涵盖C++11标准)

这里有一份离线版,可以下载:

http://www.kuaipan.cn/file/id_34843416110039117.htm (C++0x标准)

参考技术A   “Stack extends Vector”从语义上意味着:堆栈是个向量 或者 堆栈属于向量。
  其实从现实生活中,并不会认为堆栈是从向量衍伸而来的,所以这种继承关系会让人从语义上觉得奇怪。
  有点像是:某人为了贪图方便,定义猴子的时候,直接从人类继承过来了;结果语义变成了 猴子属于人类。
  Effective java上说继承有自己的一些原则,但是显然栈并不是向量,所以栈不应该扩展向量。同样的,Properties不应该继承HashTable.这样回导致子类拥有一些父类的方法,逻辑奇怪也可能出现歧义。

.* 和有啥不一样?和 .* 正则表达式?

【中文标题】.* 和有啥不一样?和 .* 正则表达式?【英文标题】:What is the difference between .*? and .* regular expressions?.* 和有什么不一样?和 .* 正则表达式? 【发布时间】:2011-03-05 17:52:51 【问题描述】:

我正在尝试使用正则表达式将字符串分成两部分。字符串格式如下:

text to extract<number>

我一直在使用(.*?)&lt;&lt;(.*?)&gt;,它们工作得很好,但是在稍微阅读了正则表达式之后,我开始想知道为什么我需要在表达式中使用?。我只是在通过这个网站找到它们后才这样做的,所以我不确定有什么区别。

【问题讨论】:

另见***.com/questions/2301285/… 【参考方案1】:

假设你有:

<a></a>

&lt;(.*)&gt; 将匹配 a&gt;&lt;/a,而 &lt;(.*?)&gt; 将匹配 a。 后者在&gt; 的第一场比赛后停止。它检查一个 或 0 个匹配 .* 后跟下一个表达式。

第一个表达式&lt;(.*)&gt; 在匹配第一个&gt; 时不会停止。它会一直持续到&gt;的最后一场比赛。

【讨论】:

这个比上面的解释更容易理解。 解释应该是这样的。【参考方案2】:

这是贪心量词和非贪心量词的区别。

考虑输入101000000000100

使用1.*1* 是贪心的——它会一直匹配到最后,然后回溯直到它可以匹配1,留下1010000000001.*? 是非-贪婪的。 * 将不匹配任何内容,但随后会尝试匹配多余的字符,直到匹配 1,最终匹配 101

所有量词都有非贪婪模式:.*?.+?.2,6?,甚至是.??

在您的情况下,类似的模式可能是 &lt;([^&gt;]*)&gt; - 匹配除大于号以外的任何字符(严格来说,它匹配 &lt;&gt; 之间除 &gt; 之外的零个或多个字符) .

Quantifier Cheat Sheet

【讨论】:

啊太棒了,我喜欢除了 > 符号之外的最后一个! 你能否解释或举例说明贪婪的? 与非贪婪的?? 有何不同? 当然。对于字符串"abc",正则表达式/\w\w?\w/ 将匹配完整的字符串"abc" - 因为? 是贪婪的。 /\w\w??\w/ 是惰性的 - 它只会匹配 "ab"。如果稍后失败,它只会回溯并匹配"abc"【参考方案3】:

关于贪婪与非贪婪

默认情况下,正则表达式中的重复是贪婪:他们尝试匹配尽可能多的代表,当这不起作用并且他们不得不回溯时,他们尝试在一个时间,直到找到整个模式的匹配。因此,当匹配最终发生时,贪婪的重复将尽可能匹配 许多 个重复。

? 作为重复量词将此行为更改为非贪婪,也称为不情愿 (in e.g. Java)(有时也称为“懒惰”)。相反,此重复将首先尝试匹配尽可能 少数 个重复,当这不起作用并且他们必须回溯时,他们开始一次匹配一个更多重复。因此,当匹配最终发生时,不情愿的重复将尽可能匹配 少数 次。

参考文献

regular-expressions.info/Repetition - Laziness instead of Greediness

示例 1:从 A 到 Z

让我们比较一下这两种模式:A.*ZA.*?Z

给定以下输入:

eeeAiiZuuuuAoooZeeee

这些模式产生以下匹配:

A.*Z 产生 1 个匹配项:AiiZuuuuAoooZ (see on rubular.com) A.*?Z 产生 2 个匹配项:AiiZAoooZ (see on rubular.com)

让我们首先关注A.*Z 的作用。当它匹配第一个A 时,.* 贪婪,首先尝试匹配尽可能多的.

eeeAiiZuuuuAoooZeeee
   \_______________/
    A.* matched, Z can't match

由于Z 不匹配,引擎回溯,然后.* 必须匹配少一个.

eeeAiiZuuuuAoooZeeee
   \______________/
    A.* matched, Z still can't match

这种情况又发生了几次,直到最后我们得出这样的结论:

eeeAiiZuuuuAoooZeeee
   \__________/
    A.* matched, Z can now match

现在Z可以匹配,所以整体模式匹配:

eeeAiiZuuuuAoooZeeee
   \___________/
    A.*Z matched

相比之下,A.*?Z 中的不情愿重复首先匹配尽可能少的.,然后根据需要匹配更多的.。这就解释了为什么它会在输入中找到两个匹配项。

以下是两种模式匹配内容的直观表示:

eeeAiiZuuuuAoooZeeee
   \__/r   \___/r      r = reluctant
    \____g____/        g = greedy

示例:另一种选择

在许多应用程序中,上述输入中的两个匹配项是所需的,因此使用不情愿的.*? 而不是贪婪的.* 以防止过度匹配。然而,对于这个特定的模式,有一个更好的选择,使用否定字符类。

模式A[^Z]*Z 还找到与上述输入(as seen on ideone.com)的A.*?Z 模式相同的两个匹配项。 [^Z] 是所谓的否定字符类:它匹配除Z 之外的任何字符。

两种模式的主要区别在于性能:更严格,否定字符类只能匹配给定输入的一种方式。对此模式使用贪婪或不情愿的修饰符并不重要。事实上,在某些方面,你可以做得更好,使用所谓的所有格量词,它根本不会回溯。

参考文献

regular-expressions.info/Repetition - An Alternative to Laziness、Negated Character Classes 和 Possessive Quantifiers

示例 2:从 A 到 ZZ

这个例子应该是说明性的:它展示了贪婪、不情愿和否定字符类模式如何在相同的输入下以不同的方式匹配。

eeAiiZooAuuZZeeeZZfff

这些是上述输入的匹配项:

A[^Z]*ZZ 产生 1 个匹配项:AuuZZ (as seen on ideone.com) A.*?ZZ 产生 1 个匹配项:AiiZooAuuZZ (as seen on ideone.com) A.*ZZ 产生 1 个匹配项:AiiZooAuuZZeeeZZ (as seen on ideone.com)

这是他们匹配的视觉表示:

         ___n
        /   \              n = negated character class
eeAiiZooAuuZZeeeZZfff      r = reluctant
  \_________/r   /         g = greedy
   \____________/g

相关主题

这些是指向 *** 上的问题和答案的链接,涵盖了一些可能感兴趣的主题。

一个贪婪的重复可以超过另一个

Regex not being greedy enough Regular expression: who's greedier

【讨论】:

我的意思是说 rubular.com,而不是 ideone.com。对其他人:不要为我修改这篇文章,我会在下一次修改时自己做,还有其他例子。随时在 cmets 中提供反馈、建议等,以便我也可以将它们纳入其中。 参见:***.com/questions/3145023/… 此答案已添加到 Stack Overflow Regular Expression FAQ 的“量词 > 更多关于差异...”下。 这个答案真的不愧是被选中的答案!。非常感谢您的详细解释。 我添加了标签non-greedy。为什么,因为问题需要它,还因为它将吸引更多用户使用这个出色的答案。换句话说,如果您给出了一个很好的答案并且答案使用了不在问题中的标签,那么添加标签,因为 OP 不知道标签是 revelent。

以上是关于vector stack(堆栈)有啥不一样和一样的地方?的主要内容,如果未能解决你的问题,请参考以下文章

union 和 join 和有啥不一样?

.* 和有啥不一样?和 .* 正则表达式?

infura 和 geth 和有啥不一样?

nx 和 Lerna 和有啥不一样? (monorepos)

";" 和有啥不一样和 T-SQL 中的“GO”?

agora 和 mux 和有啥不一样?在颤动中流式传输实时视频的最佳方式是啥?