2013-10-30 84 views
-1

我碰到一個鍛鍊來在網絡上,這是文字:實現C++中的INT堆棧

編寫類int_stack將管理整數堆棧。整數值將被存儲在動態分配的數組中。

這個類將提出以下的成員函數:

int_stack(INT n)的構造,將動態分配Ñ 整數,

int_stack()構造分配20點的整數,

〜int_stack( )析構函數,

int empty()如果​​堆棧爲空,返回值爲1,否則爲0 ,

INT滿()的返回值是1,如果堆棧已滿,否則爲0,

void運算<(INT p)的推壓(添加)在堆棧上的p值,

INT操作> (INT p)返回(和刪除)上的 堆棧

我試圖實現它頂部的值,但>(拉)運營商將無法正常工作。

這裏是我的代碼:

int_stack.h

class int_stack 
{ 
private: 
    int* stack; 
    unsigned int n, p; 
    void init(unsigned int n); 

public: 
    int_stack(unsigned int n); 
    int_stack(); 
    ~int_stack(); 
    int empty(); 
    int full(); 
    void operator <(int i); 
    int operator >(int i); 
}; 

int_stack.cpp

#include "int_stack.h" 

void int_stack::init(unsigned int n) 
{ 
    this->stack = new int[n]; 
    this->p = 0; 
} 

int_stack::int_stack(unsigned int n) 
{ 
    this->init(n); 
} 

int_stack::int_stack() 
{ 
    this->init(20); 
} 

int_stack::~int_stack() 
{ 
    delete this->stack; 
} 


int int_stack::empty() 
{ 
    return (this->p == 0 ? 1 : 0); 
} 

int int_stack::full() 
{ 
    return (this->p == n-1 ? 1 : 0); 
} 

void int_stack::operator <(int i) 
{ 
    if (!this->full()) 
     this->stack[p++] = i; 
} 

int int_stack::operator >(int i) 
{ 
    if(!this->empty()) 
     return this->stack[p--]; 
    return 0; 
} 

我在做什麼錯?

+0

在什麼意義上它不工作?編譯器錯誤?運行時錯誤?或者是什麼? – 2013-10-30 18:38:07

+1

'p'是項目的數量,但是你的數組索引是'0-(p-1)'。 – Joe

+1

這是一個相當差的設計,所以不要付出太多的努力來實現它。使用'>'和'<'進行push和pop是非常可怕的,並且使用'empty()'和'full()'return'int'(C++具有'bool')意味着設計它的人真的不知道什麼他們在做。 –

回答

0

界面的選擇很不好,但是忽略這個事實考慮你的成員的意思,特別是p。索引p是指以上位置最後添加的元素。當您在pop操作你正在閱讀從該位置值返回值,但該位置沒有值:

int int_stack::operator >(int i) 
{ 
    if(!this->empty()) 
     return this->stack[p--]; // <-- predecrement! 
    return 0; 
} 

關於界面,operator<operator>是push和pop操作不自然的選擇。當某人讀入代碼s < 5時,他們會解釋您正在比較s與5,而不是將元素插入堆棧s。這將成爲混亂的根源。

operator<更差的是operator>定義爲int operator>(int)。用戶代碼讀取值會顯得如:

value = s > 5; 

這看起來就像比較s至5,並將結果存儲到value。此外,實際的行爲是完全獨立的參數5,相同的操作可以拼寫爲s > -1甚至s > 5.3

1

除了獲得索引權,類需要一個拷貝構造函數和賦值運算符。至於寫你會得到相同的數據塊的多個刪除:

int_stack s0; 
int_stack s1(s0); // uh-oh 

兩個析構函數將刪除由構造爲s0分配的陣列。

+0

我該如何執行它們?在複製p和n之後,我應該複製堆棧,但是如何在不公開的情況下做到這一點? –

+1

@RiccardoBestetti - 複製構造函數是一個成員,因此它可以訪問它正在複製的對象的私有數據。嘗試一下。 –

1

有你的代碼的幾大缺陷:

除非你希望每次按壓時間或流行的東西來調整堆棧上或關閉它分別,你可能想使用一個鏈接列表 - 或deque-style存儲結構而不是vector/array-style。

超載operator<operator>做什麼等於提取和插入是一個可怕的界面選擇。我呼籲不要使用運營商爲這些操作:

void int_stack::push(int i) 
{ 
    // push an element onto the stack 
} 

int int_stack::pop() 
{ 
    // pop an element off of the stack 
} 

因爲你沒有實現它作爲一個鏈接列表或雙端隊列,當你去推元素,你可以(而且最終會)試圖外面寫你分配的內存邊界。

最後,您不要正確刪除堆棧。如果您使用new [],則還必須使用delete []

-1

這是我提出的工作實現。

它實現了複製構造函數和賦值運算符。

此外,索引工作,並且接口已從<>運營商更改爲兩個簡單的push(int)int pop()函數。

當您嘗試推送/彈出邊界時,它會引發異常。

int_stack.h

#include <exception> 

class int_stack 
{ 
private: 
    int* stack; 
    unsigned int n, p; 
    void init(unsigned int n); 
    void copy(int_stack& other); 

public: 
    int_stack(unsigned int n); 
    int_stack(); 
    int_stack(int_stack& other); 
    int_stack& operator=(int_stack& other); 
    ~int_stack(); 
    int empty(); 
    int full(); 
    void push(int i); 
    int pop(); 
    class OutOfBoundariesException: public std::exception {}; 
}; 

int_stack.cpp

#include "int_stack.h" 

void int_stack::init(unsigned int _n) 
{ 
    n = _n; 
    stack = new int[n]; 
    p = 0; 
} 

int_stack::int_stack(unsigned int n) 
{ 
    init(n); 
} 

int_stack::int_stack() 
{ 
    init(20); 
} 

int_stack::int_stack(int_stack& other) 
{ 
    copy(other); 
} 

int_stack& int_stack::operator=(int_stack& other) 
{ 
    copy(other); 
    return *this; 
} 

void int_stack::copy(int_stack& other) 
{ 
    n = other.n; 
    p = other.p; 
    stack = new int[n]; 
    for (unsigned int i = 0; i < n; i++) 
     stack[i] = other.stack[i]; 
} 

int_stack::~int_stack() 
{ 
    delete[] stack; 
} 

int int_stack::empty() 
{ 
    return (p == 0 ? 1 : 0); 
} 

int int_stack::full() 
{ 
    return (p == n ? 1 : 0); 
} 

void int_stack::push(int i) 
{ 
    if (!full()) 
     stack[(++p)-1] = i; 
    else 
     throw new OutOfBoundariesException; 
} 

int int_stack::pop() 
{ 
    if (!empty()) 
     return stack[(p--)-1]; 
    else 
     throw new OutOfBoundariesException; 

    return 0; 
}