美好的一天,并提前感谢。
我的问题就像在标题中所说的那样,编写一个接收堆栈和数字的函数,并返回一个新堆栈,其中包含旧堆栈的所有元素,而不是给定的数字,并且顺序相同。
算法必须使用递归来实现,并且具有尽可能低的时间和空间复杂度。
由于我对递归不好,我已经通过以下方式实现了这个:
template<typename T>
Stack<T> lesserStack(Stack<T> s, const T& max){
Stack<T> s1;
for(int i = 0; i <= s.numberOfElements() ; i++){
if(s.top() < max) s1.push(s.top());
s.pop();
}
s1.reverse();
return s1;
}
它有效,但它不应该是什么,我根本不知道如何使它递归:(
其他信息:
Stack实现为动态数组,pop函数返回弹出元素,top返回top元素。反向功能反转堆栈中的元素(以便保留原始顺序)。
答案 0 :(得分:2)
您可以尝试以下几行(我还没有测试过)。我的想法是首先深入到递归中并在从递归返回后推送条目。
template<typename T>
Stack<T> lesserStack(Stack<T> s, Stack<T> s2, const T& max){
if ( s.size() == 0 )
return s2;
T top = s.top();
s.pop();
Stack<T> s1 = lesserStack( s, s2, max);
if ( top < max )
s1.push( top );
return s1;
}
编辑:很高兴听到它有效。但是,我认为可以进一步改善,避免不必要的并发症。
它作为您的原始代码,但以下内容除外: 一旦它从原始堆栈中取出顶部元素,就不会立即将其推入新堆栈。相反,它首先弹出元素并再次为堆栈中的其他元素调用此函数。这是因为你想要保留顺序,并且这样做,首先从原始堆栈中弹出的那个,需要被推入新堆栈的最后一个。
在推动其他项目后,控件返回到此功能的下一行,然后按下该项目。
答案 1 :(得分:1)
递归执行此操作效率相当低。非递归版本看起来像这样:
template<typename T>
Stack<T> lesserStack(Stack<T> source, const T& max)
{
Stack<T> dest;
while (s.numberOfElements())
{
T t = s.top();
if (t < max)
{
dest.push(t);
}
s.pop();
}
dest.reverse();
return dest;
}
要转换它,您将删除循环:
template<typename T>
Stack<T> lesserStack(Stack<T> source, Stack<T>& dest, const T& max)
{
if (source.numberOfElements() == 0)
{
return dest; // break out of your recursion
}
T t = s.top(); // get the "last" element
source.pop();
lesserStack(source, dest, max); // make the recursive call
if (t < max)
{
dest.push(t); // push the last element - this will be done in the correct order
}
// no need to reverse the order as the unwinding of the call stack will put them in the reverse order already
return dest;
}