Vâng, tôi đã từng có một tình huống tương tự. Một điều mà tôi nghĩ đến là 'tôi có thể sử dụng đa khóa' không? Tôi googled trong một thời gian, và tìm thấy một mẫu bằng cách sử dụng std :: set. Vì vậy, nếu bạn không có quyền truy cập để tăng (tôi khuyên bạn nên nó, không có điểm tái phát minh ra bánh xe); bạn có thể thử một cái gì đó giống như ví dụ dưới đây. Tôi nghĩ bạn có thể sử dụng khóa phụ làm vị trí chèn (tự động tăng). Từ ví dụ mà tôi tìm thấy trên internet; tôi đã điều chỉnh nó theo nhu cầu của tôi. Đây là một phiên bản sửa đổi của cùng một.
Cavaet: Nó đang sử dụng macro. Tôi biết họ là ác nói chung, nhưng việc sử dụng này là o.k. tôi đoán.
#include <set>
#include <functional>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#define MULTIKEYDEF(NAME,TYPE) \
inline TYPE const & NAME() const { return d_##NAME; } \
inline void NAME(TYPE const & t) { d_##NAME = t; } \
TYPE d_##NAME; \
class T##NAME \
: public std::unary_function<Tmultikey*,bool> { \
private: \
TYPE d_compare; \
public: \
T##NAME(TYPE t) : d_compare(t) {} \
T##NAME(T##NAME const & self) \
: d_compare(self.d_compare) {} \
bool operator()(Tmultikey * mk) { \
return d_compare == mk->##NAME(); \
} \
inline TYPE const& name() const { return d_compare; } \
}
class Tmultikey {
public:
// Actual keys
// Can be accessed through d_primary and d_secondary,
// or primary() and secondary()
MULTIKEYDEF(primary , std::string);
MULTIKEYDEF(secondary, unsigned int);
// Mandatory
bool operator < (Tmultikey const& mk) const {
if(primary() < mk.primary()) return true;
else if(primary() == mk.primary()) {
return secondary() < mk.secondary();
}
return false;
}
// Constructor
Tmultikey(std::string p, unsigned int s)
: d_primary(p), d_secondary(s) {}
// Eraser for std::set
template<typename Compare>
static void erase(std::set<Tmultikey> & c, Compare op) {
typename std::set<Tmultikey>::iterator pos = c.begin();
while(pos != c.end()) {
if(op(&(*pos))) {
c.erase(pos++);
} else ++pos;
}
}
// Eraser for std::set
template<typename Compare>
static std::set<Tmultikey>::iterator find_ex(std::set<Tmultikey> & c, Compare op) {
typename std::set<Tmultikey>::iterator pos = c.begin();
while(pos != c.end()) {
if(op(&(*pos))) {
break;
} else ++pos;
}
return pos;
}
};
int main(int argc, char* argv[])
{
std::set<Tmultikey> mkset;
mkset.insert(Tmultikey("1",5));
mkset.insert(Tmultikey("6",4));
mkset.insert(Tmultikey("3",7));
mkset.insert(Tmultikey("1",6));
std::set<Tmultikey>::iterator bg = mkset.begin();
for (;bg != mkset.end(); ++bg)
{
std::cout<<(*bg).primary()<<std::endl;
}
Tmultikey::erase(mkset,Tmultikey::Tsecondary(4));
//Tmultikey::erase(mkset,Tmultikey::Tprimary("1"));
std::cout<<"After erase ....\n";
bg = mkset.begin();
for (;bg != mkset.end(); ++bg)
{
std::cout<<(*bg).primary()<<std::endl;
}
bg = mkset.find(Tmultikey("3",7));
if (bg != mkset.end())
{
std::cout<<"Absolute Find:"<<(*bg).primary()<<" "<<(*bg).secondary()<<std::endl;
}
//bg = Tmultikey::find_ex(mkset,Tmultikey::Tprimary("1"));
bg = Tmultikey::find_ex(mkset,Tmultikey::Tsecondary(5));
if (bg != mkset.end())
{
std::cout<<"Partial Find:"<<(*bg).primary()<<" "<<(*bg).secondary()<<std::endl;
}
else {
std::cout<<"Partial Find: FAILED\n";
}
return 0;
}
HTH,
+1 đánh bại tôi sau 30 giây :-) – lothar