4

の最小要素を取得する必要がありstd::mapます。利用可能なドキュメントがたくさんあることは承知しています。しかし、私は何かを働かせることができないようです。

と の 2 つのマップがbidありask、どちらもBookクラスのプロパティです。それぞれがキューのマップです。これらの各キューには、オブジェクト ( 、 などのOrderさまざまなプロパティを持つ) が保持されます。私は最高のビッド、最高のアスク、スプレッドを取得するメンバー関数を持っています:pricevolumeupdate

void update(void)
{
  unsigned long long highest_bid, lowest_ask = 0;

  for (std::map<unsigned long long, queue<Order>>::iterator it = this->bid.begin(); it != this->bid.end(); ++it)
  { 
    highest_bid = it->first;
  }

  // best ask code here

  this->bestBid = highest_bid;
  this->bestAsk = lowest_ask;
  this->spread = labs(this->bestAsk - this->bestBid);
}

質問コードがある場所で、次のことを試しました。

lowest_ask = this->ask.begin()->first;

これはコンパイルされますが、デバッグするとアサーション エラーがスローされます (ここで他の質問を読んだことがありますが、理解できないようです)。

Expression: map/set iterator not dereferencable

逆の繰り返しを試しました:

for(std::map<unsigned long long, queue<Order>>::reverse_iterator rit = this->ask.rbegin(); rit != this->ask.rend(); ++rit)
{
  lowest_ask = rit->first;
}

これは正常にコンパイルおよびデバッグされますが、lowest_ask常に 0 であり、これは間違っています。デバッガーでステップ実行すると、ゼロになるまで停止しません。

イテレータを交換してみました:

for(std::map<unsigned long long, queue<Order>>::reverse_iterator rit = this->ask.rend(); rit != this->ask.rbegin(); ++rit)
{
  lowest_ask = rit->first;
}

これは正常にコンパイルされましたが、もう一度デバッグ アサーション エラーがスローされました。

私が試したことを何度も続けることができましたが、この質問はすでに複雑すぎます。なぜ最初にやったことができないのか理解できません(lowest_ask = this->ask.begin()->first)。

事前にどうもありがとうございました。

4

3 に答える 3

10

マップを反復処理して常に同じ変数を割り当てるのは、不必要に大変な作業のように思えます。

マップの最初のアイテム (またはマップの最後のアイテム) にアクセスする必要がある場合は、begin() (または rbegin()) だけで十分です。

    std::map <int, int> themap;

    themap[4] = 1;
    themap[2] = 2;
    themap[1] = 3;
    themap[6] = 4;
    themap[5] = 5;
    themap[7] = 6;

    if (!themap.empty())
    {
        std::cout << "item[" << themap.begin()->first << "] = " << themap.begin()->second << std::endl;
        std::cout << "item[" << themap.rbegin()->first << "] = " << themap.rbegin()->second << std::endl;
    }

begin と rbegin に注意する必要があるのは、マップが空のときだけです

于 2014-07-19T14:16:42.930 に答える
2

コンテナーが空ではないことを確認して、意味のある(定義された)begin()ものをrbegin()返すだけでよいと思います。

これを試して:

void update(void)
{
    if(bid.empty() || ask.empty())
        return;

    // best ask code here

    this->bestBid = bid.rbegin()->first;
    this->bestAsk = ask.begin()->first;
    this->spread = labs(this->bestAsk - this->bestBid);
}
于 2014-07-19T14:16:37.960 に答える
-1

これは「複雑」ではありません。いくつかの標準的なデバッグ手段を取るだけです

#include <map>
#include <iostream>
#include <algorithm>
#include <random>
#include <string>
#include <queue>


namespace mock {
    using Order = std::string;


    struct Book {
        using key_type = unsigned long long;  
        using order_queue_type = std::queue<Order>;        
        using property_type = std::map<key_type, order_queue_type>; 

        property_type bids, asks;


        void diagnose(const property_type& prop) {
            for (auto it = prop.cbegin(); it != prop.cend(); ++it) {
                std::clog << "\t" << it->first << '\n';
            }
        }

        void diagnose() { 
            std::clog << "bids:" << '\n';     
            diagnose(bids);
            std::clog << "asks:" << '\n';     
            diagnose(asks);
        } 

        Book() {
            std::random_device rd;
            std::mt19937 gen(rd());
            std::uniform_int_distribution<key_type> ba_dist(0, 1000);
            std::uniform_int_distribution<std::size_t> len_dist(0, 10);

            auto prop_gen = [&] (property_type& prop) {
                auto count = len_dist(gen);
                for (std::size_t i = 0; i < count; ++i) {
                    auto val = ba_dist(gen);
                    auto pair = prop.emplace(val, order_queue_type());
                    if (!pair.second) {
                        std::clog << val << " already present" << '\n';
                    }
                }
            };

            prop_gen(bids);
            prop_gen(asks);
        }
    };
}


int main() {
    mock::Book book; 
    book.diagnose();
}    

私のctorのジェネレーターの代わりに、BookもちろんあなたのinitルーチンとあなたのOrder型を使ってください。

于 2014-07-20T01:51:19.253 に答える