2013-08-08 32 views
5

Piszę filtr FIR, który ma obliczyć running average sekwencji wejściowej.Jak mogę iterować elementy `std :: stack` w pętli for?

class RunningAverager 
{ 
    public: 
     RunningAverager(uint64_t FilterOrder) 
     { 
      for (uint64_t i=0; i<FilterOrder; i++) 
      { 
       Registers.push(0); 
      } 
     } 
     uint64_t GetAverage(uint64_t NewInput) 
     { 
      Registers.push(NewInput); 
      Registers.pop(); 
      return GetAverage(); 
     } 
     uint64_t GetAverage() const 
     { 
      uint64_t Sum = 0; 
      //for (uint64_t i=0; i<Registers.size(); i++)  <-- Works 
      for (std::stack<uint64_t>::const_reference ref=Registers.begin(); ref!=Registers.end(); ???) 
      { // begin() and end() methods do not exist for std::stack 
       //Sum += Registers[i];  Doesn't work, because the [] operator is not overloaded. 
       Sum += ref; 
      } 
      return Sum/Registers.size(); 
     } 
    private: 
     std::stack<uint64_t> Registers; 
}; 

Mam problemy z iteracji na std::stack obiekt Registers. W przeciwieństwie do innych kontenerów STL, nie daje on operatora iteratora ani operatora o swobodnym dostępie.

Jak wykonać pętlę i obiekt std::stack?

Przykład użycia:

RunningAverager ra(10); 

while(...) 
{ 
    FilteredSpeed = ra.GetAverage(ActualSpeed); 
} 
+3

Nie można wykonywać iteracji po stosie. To jest cały punkt stosu. –

+0

Myślę, że powinieneś użyć czegoś takiego jak 'boost :: circular_buffer' zamiast' std :: stack' z powodu wspomnianego @KerrekSB. – arne

Odpowiedz

0

naciśnięciu wartości na stosie w pierwszej pętli. Możesz więc wyskoczyć w drugiej pętli i dodać je i policzyć, aby uzyskać średnią.

1

Możesz użyć std::deque zamiast stosu, używając push_front i pop_front.

1

Łatwiej jest używać kontenera std::deque dla tej konkretnej aplikacji.

class RunningAverage 
{ 
    public: 
     RunningAverage(uint64_t Order) 
     { 
      for (uint64_t i=0; i<Order; i++) 
      { 
       Registers.resize(Order, 0); 
      } 
     } 
     uint64_t GetAverage(uint64_t NewInput) 
     { 
      Registers.push_back(NewInput); 
      Registers.pop_front(); 
      return GetAverage(); 
     } 
     uint64_t GetAverage() const 
     { 
      uint64_t Sum = 0; 
      for (std::deque<uint64_t>::const_iterator it=Registers.begin(); it<Registers.end(); ++it) 
      { 
       Sum += *it; 
      } 
      return Sum/Registers.size(); 
     } 
    private: 
     std::deque<uint64_t> Registers; 
};