min stackの実装方法
4486 ワード
min stackの実装方法
Q:特殊なスタックをどのように設計するか、min()操作をサポートし、スタックの最小要素を返す.
この問題は去年の面接で出会った問題に由来し、面接官は20分間このようなスタックを設計させた.当時は時間が限られていて、1つのバージョンが書かれていましたが、そのバージョンには多くの問題がありました.例えば、汎用性が足りず、
面接が终わった后にまたよく考えて、再び1つのバージョンを书いて、记录して、みんなに分かち合います!このバージョンは主に前に述べた2つの問題を解決します.汎用性2.効率
1.インタフェースの設計
汎用性の問題を解決するには、このスタックにすべてのデータ型をサポートさせるには、
また、
もう一度よく考えてみると、配列bは本当に最小値を保存する必要がありますか?実は配列aには最小のコピーが存在する、b配列にもう一度保存すると空間が浪費され、スタックに格納されている非常に膨大なクラスタイプであれば、そのタイプのデータをb配列に書き込むのにもかなり時間がかかる.これは空間と時間の二重の浪費をもたらし、明らかにこれは合理的ではない.実際、b配列に実際のクラスオブジェクトを記憶する必要は全くない、そのオブジェクトのa配列におけるインデックスを記憶すればよいので、スペースを節約するとともに、速度を向上させることができる.
上記の分析に基づいて、次のインタフェースを設計することができます.
2.インタフェース実装
上記の設計に基づいて、コードを簡単に書くことができます.
3.テストしてみる
自分が書いたstackが使いやすいかどうかをテストする小さな例を書きます.
コンパイルして
実行結果
問題ないようですね~コードはgithubにアップロードされています.リンクはここです.https://github.com/zkangHUST/CppSTL
THE END.
Q:特殊なスタックをどのように設計するか、min()操作をサポートし、スタックの最小要素を返す.
この問題は去年の面接で出会った問題に由来し、面接官は20分間このようなスタックを設計させた.当時は時間が限られていて、1つのバージョンが書かれていましたが、そのバージョンには多くの問題がありました.例えば、汎用性が足りず、
int
種類のデータしかサポートできませんでした.同時に、効率も低い、大量のデータコピーが存在する.面接が终わった后にまたよく考えて、再び1つのバージョンを书いて、记录して、みんなに分かち合います!このバージョンは主に前に述べた2つの問題を解決します.汎用性2.効率
1.インタフェースの設計
汎用性の問題を解決するには、このスタックにすべてのデータ型をサポートさせるには、
template
を使用する必要がある.また、
min()
の動作をサポートするためには、2つの配列が必要である.配列aはpushをスタックに格納データであり、配列bは最小値を記録し、配列aは更新(pushまたはpop)するたびに、配列bは更新される.もう一度よく考えてみると、配列bは本当に最小値を保存する必要がありますか?実は配列aには最小のコピーが存在する、b配列にもう一度保存すると空間が浪費され、スタックに格納されている非常に膨大なクラスタイプであれば、そのタイプのデータをb配列に書き込むのにもかなり時間がかかる.これは空間と時間の二重の浪費をもたらし、明らかにこれは合理的ではない.実際、b配列に実際のクラスオブジェクトを記憶する必要は全くない、そのオブジェクトのa配列におけるインデックスを記憶すればよいので、スペースを節約するとともに、速度を向上させることができる.
上記の分析に基づいて、次のインタフェースを設計することができます.
template
class stack
{
private:
// top
int top;
// top
int minTop;
T buf[1024];
//
int minIndex[1024];
const int maxsize = 1024;
public:
int push(const T& item);
T pop();
//
int pushMinIndex(const T& item);
int popMinIndex();
T min(); //
stack();
stack(const stack& s);
stack& operator=(const stack& s);
~stack();
};
2.インタフェース実装
上記の設計に基づいて、コードを簡単に書くことができます.
#ifndef MY_STACK_H
#define MY_STACK_H
#include
#define ERROR -1
#define OK 0
template
class stack
{
private:
int top;
int minTop;
T buf[1024];
int minIndex[1024];
const int maxsize = 1024;
public:
int push(const T& item);
int pushMinIndex(const T& item);
int popMinIndex();
T min();
T pop();
stack();
stack(const stack& s);
stack& operator=(const stack& s);
~stack();
};
template
stack::stack():top(-1), minTop(-1)
{
}
template
stack::~stack() {}
template
int stack::push(const T& item)
{
top++;
if ((top >= maxsize) || (top < 0)) {
return ERROR;
}
buf[top] = item;
pushMinIndex(item);
return OK;
}
template
T stack::pop()
{
assert(top >= 0);
popMinIndex();
return buf[top--];
}
// ,
template
int stack::pushMinIndex(const T& item)
{
minTop++;
if ((minTop >= maxsize) || (minTop < 0)) {
return ERROR;
}
if (minTop == 0) {
minIndex[minTop] = top;
return OK;
}
if (item < buf[minIndex[minTop - 1]]) {
minIndex[minTop] = top;
} else {
minIndex[minTop] = minIndex[minTop - 1];
}
return OK;
}
template
int stack::popMinIndex()
{
minTop--;
return OK;
}
template
T stack::min()
{
assert(minTop >= 0);
return buf[minIndex[minTop]];
}
// ,
template
stack::stack(const stack& s):top(s.top), minTop(s.minTop)
{
top = s.top;
minTop = s.minTop;
for (int i = 0; i <= top; i++) {
buf[i] = s.buf[i];
}
for (int i = 0; i <= minTop; i++) {
minIndex[i] = s.minIndex[i];
}
}
template
stack& stack::operator=(const stack& s)
{
top = s.top;
minTop = s.minTop;
for (int i = 0; i <= top; i++) {
buf[i] = s.buf[i];
}
for (int i = 0; i <= minTop; i++) {
minIndex[i] = s.minIndex[i];
}
return *this;
}
#endif
3.テストしてみる
自分が書いたstackが使いやすいかどうかをテストする小さな例を書きます.
#include
#include "minstack.hpp"
using namespace std;
int main()
{
stack s;
double a[] = {8.1, 7.2, 9.5, 6.3, 2.5, 5.6, 3.5};
for (int i = 0; i < 7; i++) {
s.push(a[i]);
cout << s.min() << " ";
}
cout << endl;
stack t;
t = s;
cout << "---------------------------" << endl;
for (int i = 0; i < 7; i++) {
cout << t.min() << " ";
t.pop();
}
return 0;
}
コンパイルして
g++ -g main.cpp -Wall
実行結果
$ ./a.out
8.1 7.2 7.2 6.3 2.5 2.5 2.5
---------------------------
2.5 2.5 2.5 6.3 7.2 7.2 8.1
問題ないようですね~コードはgithubにアップロードされています.リンクはここです.https://github.com/zkangHUST/CppSTL
THE END.