การเรียงลำดับเวกเตอร์ของวัตถุที่กำหนดเอง


249

จะมีวิธีการเกี่ยวกับการเรียงลำดับเวกเตอร์ที่มีวัตถุที่กำหนดเอง (เช่นผู้ใช้กำหนด)
อาจจัดเรียงอัลกอริทึม STL มาตรฐานพร้อมกับเพรดิเคต (ฟังก์ชันหรือวัตถุฟังก์ชัน) ซึ่งจะทำงานบนหนึ่งในฟิลด์ (เป็นคีย์สำหรับการเรียงลำดับ) ในวัตถุที่กำหนดเองควรใช้
ฉันกำลังติดตามใช่ไหม?


คำตอบ:


365

ตัวอย่างง่ายๆโดยใช้ std::sort

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}
};

struct less_than_key
{
    inline bool operator() (const MyStruct& struct1, const MyStruct& struct2)
    {
        return (struct1.key < struct2.key);
    }
};

std::vector < MyStruct > vec;

vec.push_back(MyStruct(4, "test"));
vec.push_back(MyStruct(3, "a"));
vec.push_back(MyStruct(2, "is"));
vec.push_back(MyStruct(1, "this"));

std::sort(vec.begin(), vec.end(), less_than_key());

แก้ไข: ดังที่ Kirill V. Lyadvinsky ชี้ให้เห็นแทนการจัดหาคำอธิบายการเรียงลำดับคุณสามารถใช้operator<สำหรับMyStruct:

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}

    bool operator < (const MyStruct& str) const
    {
        return (key < str.key);
    }
};

การใช้วิธีนี้หมายความว่าคุณสามารถเรียงลำดับเวกเตอร์ดังต่อไปนี้:

std::sort(vec.begin(), vec.end());

แก้ไข 2:ตามที่ Kappa แนะนำคุณยังสามารถเรียงลำดับเวกเตอร์ตามลำดับจากมากไปน้อยโดยการบรรทุกตัว>ดำเนินการมากเกินไปและเปลี่ยนการเรียกบิตเรียงลำดับ:

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}

    bool operator > (const MyStruct& str) const
    {
        return (key > str.key);
    }
};

และคุณควรเรียกการเรียงลำดับเป็น:

std::sort(vec.begin(), vec.end(),greater<MyStruct>());

2
คุณช่วยอธิบายได้ไหมว่าทำไมคุณถึงสร้างฟังก์ชั่นการเปรียบเทียบในอินสแตนซ์ less_than_key (ในตอนแรก) ตัวอย่าง?
kluka

2
และอีกคำถาม / หมายเหตุ: หากใครอยากมีวิธีการเรียงลำดับหลายวิธี (สำหรับคุณลักษณะที่แตกต่างกัน) ในชั้นเรียนวิธีการบรรทุกเกินพิกัดผู้ประกอบการ <อาจเป็นตัวเลือกใช่ไหม?
kluka

5
สิ่งที่ยอดเยี่ยมคือการให้วิธีการดำเนินการ> สิ่งนี้จะทำให้เราสามารถเรียงลำดับแบบย้อนกลับเช่น: std::sort(vec.begin(), vec.end(), greater<MyStruct>())ซึ่งสะอาดและสง่างาม
คัปปา

3
@Bovaz คุณต้อง#include <functional>ใช้ "std :: Greater "
Nick Hartung

4
@kappa: ที่ที่คุณสามารถมีoperator<และใช้อย่างใดอย่างหนึ่งstd::sort(vec.begin(), vec.end());หรือstd::sort(vec.rbegin(), vec.rend());ขึ้นอยู่กับว่าคุณต้องการที่จะมีลำดับขึ้นหรือลง
Pixelchemist

182

อยู่ในความสนใจของความคุ้มครอง ฉันใส่ไปข้างหน้าการดำเนินการโดยใช้การแสดงออกแลมบ์ดา

C ++ 11

#include <vector>
#include <algorithm>

using namespace std;

vector< MyStruct > values;

sort( values.begin( ), values.end( ), [ ]( const MyStruct& lhs, const MyStruct& rhs )
{
   return lhs.key < rhs.key;
});

C ++ 14

#include <vector>
#include <algorithm>

using namespace std;

vector< MyStruct > values;

sort( values.begin( ), values.end( ), [ ]( const auto& lhs, const auto& rhs )
{
   return lhs.key < rhs.key;
});

21
+1 พิเศษสำหรับการรวม #includes
Anne

3
เพื่อความชัดเจนผลลัพธ์นี้เรียงตามลำดับจากน้อยไปมาก ใช้>แทน<เพื่อรับลำดับ
bhaller

57

คุณสามารถใช้ functor เป็นอาร์กิวเมนต์ที่สามของstd::sortหรือคุณสามารถกำหนดoperator<ในชั้นเรียนของคุณ

struct X {
    int x;
    bool operator<( const X& val ) const { 
        return x < val.x; 
    }
};

struct Xgreater
{
    bool operator()( const X& lx, const X& rx ) const {
        return lx.x < rx.x;
    }
};

int main () {
    std::vector<X> my_vec;

    // use X::operator< by default
    std::sort( my_vec.begin(), my_vec.end() );

    // use functor
    std::sort( my_vec.begin(), my_vec.end(), Xgreater() );
}

4
ทำไมเราต้องเพิ่มconstในตอนท้ายของฟังก์ชั่นลายเซ็น?
ง่าม

4
constฟังก์ชั่นไม่ได้เปลี่ยนวัตถุดังนั้นมันจึงเป็น
Kirill V. Lyadvinsky

ถ้าเป็นเช่นนั้นแล้วทำไมเราถึงผ่าน "const X & val" ฉันคิดว่าการส่งค่าเป็น const ไปยังฟังก์ชันทำให้ฟังก์ชันคิดว่าค่าของมันจะไม่เปลี่ยนแปลง
Prashant Bhanarkar

1
@PrashantBhanarkar constคำหลักที่ส่วนท้ายของลายเซ็นระบุว่าoperator()ฟังก์ชั่นจะไม่เปลี่ยนอินสแตนซ์ของXgreaterstruct (ซึ่งโดยทั่วไปอาจมีตัวแปรสมาชิก) ในขณะที่การระบุconstสำหรับค่าอินพุตเพียงระบุว่าค่าอินพุตเหล่านั้นไม่เปลี่ยนรูป
schester

15

การจัดเรียงช่วง a vectorหรืออื่น ๆ ที่ใช้งานได้ (ตัวทำอินพุตอินพุตที่ไม่แน่นอน) ของชนิดของวัตถุที่กำหนดเองXสามารถทำได้โดยใช้วิธีการต่าง ๆ โดยเฉพาะอย่างยิ่งรวมถึงการใช้อัลกอริทึมไลบรารีมาตรฐานเช่น

เนื่องจากเทคนิคส่วนใหญ่เพื่อให้ได้การเรียงลำดับของXองค์ประกอบที่สัมพันธ์กันได้ถูกโพสต์แล้วฉันจะเริ่มต้นด้วยหมายเหตุบางประการเกี่ยวกับ "ทำไม" และ "เมื่อ" เพื่อใช้วิธีการต่างๆ

วิธี "ดีที่สุด" จะขึ้นอยู่กับปัจจัยต่าง ๆ :

  1. การเรียงลำดับช่วงของXวัตถุเป็นงานทั่วไปหรืองานที่หายาก (ช่วงดังกล่าวจะถูกจัดเรียงสถานที่ต่าง ๆ ในโปรแกรมหรือโดยผู้ใช้ห้องสมุด) หรือไม่?
  2. การเรียงลำดับที่ต้องการเป็น "ธรรมชาติ" (คาดว่า) หรือมีหลายวิธีที่ชนิดสามารถเปรียบเทียบกับตัวเองได้หรือไม่
  3. ประสิทธิภาพเป็นปัญหาหรือควรจัดเรียงช่วงของXวัตถุที่จะเข้าใจผิดได้หรือไม่

ถ้าช่วงการเรียงลำดับของXเป็นงานทั่วไปและคาดว่าจะประสบความสำเร็จในการเรียงลำดับ (เช่นXเพียงแค่ตัดค่าพื้นฐานเพียงค่าเดียว) จากนั้นอาจจะทำงานหนักเกินไปoperator<เนื่องจากจะช่วยให้การเรียงลำดับโดยไม่มีฝอย (เช่นผ่านการเปรียบเทียบที่เหมาะสมอย่างถูกต้อง) ผล.

หากการเรียงลำดับเป็นงานทั่วไปหรือมีแนวโน้มที่จะต้องใช้ในบริบทที่แตกต่างกัน แต่มีหลายเกณฑ์ที่สามารถใช้ในการจัดเรียงXวัตถุฉันจะไป Functors ( operator()ฟังก์ชันที่มากเกินไปของคลาสที่กำหนดเอง) หรือตัวชี้ฟังก์ชั่น สำหรับการจัดเรียงคำและอีกอันสำหรับการเรียงตามธรรมชาติ)

หากช่วงการเรียงลำดับของประเภทXเป็นเรื่องแปลกหรือไม่น่าเป็นไปได้ในบริบทอื่น ๆ ฉันมักจะใช้ lambdas แทนที่จะยุ่งเหยิงในเนมสเปซที่มีฟังก์ชันหรือชนิดมากกว่า

โดยเฉพาะอย่างยิ่งหากการเรียงลำดับนั้นไม่ "ชัดเจน" หรือ "เป็นธรรมชาติ" ในบางวิธี คุณสามารถรับตรรกะที่อยู่เบื้องหลังการสั่งซื้อได้อย่างง่ายดายเมื่อดูแลมบ์ดาที่นำมาใช้ในสถานที่ในขณะที่operator<เป็นสิ่งที่คลุมเครือตั้งแต่แรกเห็นและคุณจะต้องค้นหาคำจำกัดความเพื่อทราบว่า

อย่างไรก็ตามโปรดทราบว่าoperator<คำจำกัดความเดียวเป็นจุดหนึ่งของความล้มเหลวในขณะที่หลาย lambas เป็นหลายจุดของความล้มเหลวและต้องใช้ความระมัดระวังมากขึ้น

หากคำจำกัดความของoperator<ไม่สามารถใช้งานได้เมื่อการเรียงลำดับเสร็จสิ้น / แม่แบบการเรียงลำดับถูกรวบรวมคอมไพเลอร์อาจถูกบังคับให้ทำการเรียกใช้ฟังก์ชันเมื่อเปรียบเทียบวัตถุแทนการฝังตรรกะการสั่งซื้อซึ่งอาจเป็นข้อเสียเปรียบอย่างรุนแรง ไม่ใช้การเพิ่มประสิทธิภาพเวลาลิงค์ / การสร้างรหัส)

วิธีในการบรรลุการเปรียบเทียบclass Xเพื่อใช้อัลกอริทึมการเรียงลำดับไลบรารีมาตรฐาน

อนุญาตstd::vector<X> vec_X;และstd::vector<Y> vec_Y;

1. โอเวอร์โหลดT::operator<(T)หรือoperator<(T, T)ใช้เทมเพลตไลบรารีมาตรฐานที่ไม่คาดว่าจะมีฟังก์ชั่นการเปรียบเทียบ

เกินสมาชิกoperator<:

struct X {
  int i{}; 
  bool operator<(X const &r) const { return i < r.i; } 
};
// ...
std::sort(vec_X.begin(), vec_X.end());

หรือฟรีoperator<:

struct Y {
  int j{}; 
};
bool operator<(Y const &l, Y const &r) { return l.j < r.j; }
// ...
std::sort(vec_Y.begin(), vec_Y.end());

2. ใช้ตัวชี้ฟังก์ชันพร้อมฟังก์ชันเปรียบเทียบแบบกำหนดเองเพื่อจัดเรียงพารามิเตอร์ฟังก์ชัน

struct X {
  int i{};  
};
bool X_less(X const &l, X const &r) { return l.i < r.i; }
// ...
std::sort(vec_X.begin(), vec_X.end(), &X_less);

3. สร้างbool operator()(T, T)โอเวอร์โหลดสำหรับประเภทที่กำหนดเองซึ่งสามารถส่งเป็น functor การเปรียบเทียบ

struct X {
  int i{};  
  int j{};
};
struct less_X_i
{
    bool operator()(X const &l, X const &r) const { return l.i < r.i; }
};
struct less_X_j
{
    bool operator()(X const &l, X const &r) const { return l.j < r.j; }
};
// sort by i
std::sort(vec_X.begin(), vec_X.end(), less_X_i{});
// or sort by j
std::sort(vec_X.begin(), vec_X.end(), less_X_j{});

นิยามฟังก์ชันวัตถุเหล่านั้นสามารถเขียนทั่วไปได้มากกว่าโดยใช้ C ++ 11 และเท็มเพลต:

struct less_i
{ 
    template<class T, class U>
    bool operator()(T&& l, U&& r) const { return std::forward<T>(l).i < std::forward<U>(r).i; }
};

ซึ่งสามารถนำมาใช้ในการจัดเรียงชนิดที่มีสมาชิกสนับสนุนi<

4. ผ่านการปิดแบบไม่ระบุชื่อ (แลมบ์ดา) เป็นพารามิเตอร์การเปรียบเทียบไปยังฟังก์ชันการเรียงลำดับ

struct X {
  int i{}, j{};
};
std::sort(vec_X.begin(), vec_X.end(), [](X const &l, X const &r) { return l.i < r.i; });

ที่ C ++ 14 เปิดใช้งานการแสดงออกแลมบ์ดาทั่วไปยิ่งขึ้น:

std::sort(a.begin(), a.end(), [](auto && l, auto && r) { return l.i < r.i; });

ซึ่งสามารถห่อในแมโคร

#define COMPARATOR(code) [](auto && l, auto && r) -> bool { return code ; }

ทำให้การสร้างตัวเปรียบเทียบแบบธรรมดาค่อนข้างราบรื่น:

// sort by i
std::sort(v.begin(), v.end(), COMPARATOR(l.i < r.i));
// sort by j
std::sort(v.begin(), v.end(), COMPARATOR(l.j < r.j));

ในกรณีที่2คุณเขียนbool X_less(X const &l, X const &r) const { return l.i < r.i; }เพื่อเปรียบเทียบ แต่constควรลบคำหลัก (เนื่องจากไม่ใช่ฟังก์ชันสมาชิก)
PolGraphic

@ PolGraphic: ถูกต้อง - ในกรณีที่ 1 เช่นกัน
Pixelchemist

@Pixelchemist ฉันจะใช้แลมบ์ดา (4. ) ได้อย่างไรเมื่อไม่ได้ใช้งานstd::sortหรือสิ่งที่คล้ายกัน แต่ต้องการอินสแตนซ์ของCompareเช่นเมื่อใช้อินสแตนซ์ a std::set?
azrdev

1
@azrdev: ฟังก์ชั่นแม่แบบที่จับประเภทของการปิดที่จะผ่านมันเป็นพารามิเตอร์แม่แบบชุด: ซึ่งอาจนำมาใช้เช่นtemplate<class T, class C> std::set<T, C> make_set(C const& compare) { return std::set<T, C>{ compare }; } auto xset = make_set<X>([](auto && l, auto && r) { return l.i < r.i; });
Pixelchemist

14

คุณอยู่ในเส้นทางที่ถูกต้อง std::sortจะใช้operator<เป็นฟังก์ชั่นการเปรียบเทียบโดยค่าเริ่มต้น ดังนั้นในการจัดเรียงวัตถุของคุณคุณจะต้องใช้งานเกินพิกัดbool operator<( const T&, const T& )หรือจัดให้มี functor ที่ทำการเปรียบเทียบเช่นนี้:

 struct C {
    int i;
    static bool before( const C& c1, const C& c2 ) { return c1.i < c2.i; }
 };

 bool operator<( const C& c1, const C& c2 ) { return c1.i > c2.i; }

 std::vector<C> values;

 std::sort( values.begin(), values.end() ); // uses operator<
 std::sort( values.begin(), values.end(), C::before );

ข้อดีของการใช้ functor คือคุณสามารถใช้ฟังก์ชั่นที่มีการเข้าถึงสมาชิกส่วนตัวของชั้นเรียน


พลาดไปหนึ่งรายการ: จัดเตรียมฟังก์ชันสมาชิกสมาชิก <
xtofl

1
มันจะดีกว่าที่จะทำให้operator<สมาชิกของคลาส (หรือ struct), เนื่องจากระดับโลกสามารถใช้สมาชิกที่ได้รับการป้องกันหรือส่วนตัว หรือคุณควรจะทำให้มันเป็นเพื่อนของ struct ซี
คิริลล์โวลต์ Lyadvinsky

5

ฉันอยากรู้อยากเห็นหากมีผลกระทบที่วัดได้ระหว่างประสิทธิภาพการทำงานระหว่างวิธีต่าง ๆ ที่สามารถเรียก std :: sort ดังนั้นฉันได้สร้างแบบทดสอบง่าย ๆ นี้:

$ cat sort.cpp
#include<algorithm>
#include<iostream>
#include<vector>
#include<chrono>

#define COMPILER_BARRIER() asm volatile("" ::: "memory");

typedef unsigned long int ulint;

using namespace std;

struct S {
  int x;
  int y;
};

#define BODY { return s1.x*s2.y < s2.x*s1.y; }

bool operator<( const S& s1, const S& s2 ) BODY
bool Sgreater_func( const S& s1, const S& s2 ) BODY

struct Sgreater {
  bool operator()( const S& s1, const S& s2 ) const BODY
};

void sort_by_operator(vector<S> & v){
  sort(v.begin(), v.end());
}

void sort_by_lambda(vector<S> & v){
  sort(v.begin(), v.end(), []( const S& s1, const S& s2 ) BODY );
}

void sort_by_functor(vector<S> &v){
  sort(v.begin(), v.end(), Sgreater());
}

void sort_by_function(vector<S> &v){
  sort(v.begin(), v.end(), &Sgreater_func);
}

const int N = 10000000;
vector<S> random_vector;

ulint run(void foo(vector<S> &v)){
  vector<S> tmp(random_vector);
  foo(tmp);
  ulint checksum = 0;
  for(int i=0;i<tmp.size();++i){
     checksum += i *tmp[i].x ^ tmp[i].y;
  }
  return checksum;
}

void measure(void foo(vector<S> & v)){

ulint check_sum = 0;

  // warm up
  const int WARMUP_ROUNDS = 3;
  const int TEST_ROUNDS = 10;

  for(int t=WARMUP_ROUNDS;t--;){
    COMPILER_BARRIER();
    check_sum += run(foo);
    COMPILER_BARRIER();
  }

  for(int t=TEST_ROUNDS;t--;){
    COMPILER_BARRIER();
    auto start = std::chrono::high_resolution_clock::now();
    COMPILER_BARRIER();
    check_sum += run(foo);
    COMPILER_BARRIER();
    auto end = std::chrono::high_resolution_clock::now();
    COMPILER_BARRIER();
    auto duration_ns = std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count();

    cout << "Took " << duration_ns << "s to complete round" << endl;
  }

  cout << "Checksum: " << check_sum << endl;
}

#define M(x) \
  cout << "Measure " #x " on " << N << " items:" << endl;\
  measure(x);

int main(){
  random_vector.reserve(N);

  for(int i=0;i<N;++i){
    random_vector.push_back(S{rand(), rand()});
  }

  M(sort_by_operator);
  M(sort_by_lambda);
  M(sort_by_functor);
  M(sort_by_function);
  return 0;
}

สิ่งที่มันทำคือสร้างเวกเตอร์แบบสุ่มจากนั้นวัดระยะเวลาที่ต้องใช้ในการคัดลอกและจัดเรียงสำเนาของมัน (และคำนวณผลรวมตรวจสอบบางอย่างเพื่อหลีกเลี่ยงการกำจัดรหัสตายที่แรงเกินไป)

ฉันรวบรวมด้วย g ++ (GCC) 7.2.1 20170829 (Red Hat 7.2.1-1)

$ g++ -O2 -o sort sort.cpp && ./sort

นี่คือผลลัพธ์:

Measure sort_by_operator on 10000000 items:
Took 0.994285s to complete round
Took 0.990162s to complete round
Took 0.992103s to complete round
Took 0.989638s to complete round
Took 0.98105s to complete round
Took 0.991913s to complete round
Took 0.992176s to complete round
Took 0.981706s to complete round
Took 0.99021s to complete round
Took 0.988841s to complete round
Checksum: 18446656212269526361
Measure sort_by_lambda on 10000000 items:
Took 0.974274s to complete round
Took 0.97298s to complete round
Took 0.964506s to complete round
Took 0.96899s to complete round
Took 0.965773s to complete round
Took 0.96457s to complete round
Took 0.974286s to complete round
Took 0.975524s to complete round
Took 0.966238s to complete round
Took 0.964676s to complete round
Checksum: 18446656212269526361
Measure sort_by_functor on 10000000 items:
Took 0.964359s to complete round
Took 0.979619s to complete round
Took 0.974027s to complete round
Took 0.964671s to complete round
Took 0.964764s to complete round
Took 0.966491s to complete round
Took 0.964706s to complete round
Took 0.965115s to complete round
Took 0.964352s to complete round
Took 0.968954s to complete round
Checksum: 18446656212269526361
Measure sort_by_function on 10000000 items:
Took 1.29942s to complete round
Took 1.3029s to complete round
Took 1.29931s to complete round
Took 1.29946s to complete round
Took 1.29837s to complete round
Took 1.30132s to complete round
Took 1.3023s to complete round
Took 1.30997s to complete round
Took 1.30819s to complete round
Took 1.3003s to complete round
Checksum: 18446656212269526361

ดูเหมือนว่าตัวเลือกทั้งหมดยกเว้นการส่งต่อตัวชี้ฟังก์ชั่นจะคล้ายกันมากและการส่งตัวชี้ฟังก์ชันทำให้เกิดการลงโทษ + 30%

ดูเหมือนว่าโอเปอเรเตอร์ <เวอร์ชั่นจะช้ากว่า ~ 1% (ฉันทำการทดสอบซ้ำหลายครั้งและเอฟเฟกต์ยังคงอยู่) ซึ่งค่อนข้างแปลกเพราะมันแนะนำว่ารหัสที่สร้างขึ้นนั้นแตกต่างกัน (ฉันขาดทักษะในการวิเคราะห์ การส่งออก temps)


4

ใช่std::sort()ด้วยพารามิเตอร์ที่สาม (ฟังก์ชั่นหรือวัตถุ) จะง่ายขึ้น ตัวอย่าง: http://www.cplusplus.com/reference/algorithm/sort/


ไม่ใช่ว่าลิงก์เพียงคำตอบเท่านั้น แต่อย่างน้อยตัวอย่างบรรทัดเดียวก็มีประโยชน์
Manos Nikolaidis

3

ในชั้นเรียนของคุณคุณอาจใช้ตัวดำเนินการ "<" มากเกินไป

class MyClass
{
  bool operator <(const MyClass& rhs)
  {
    return this->key < rhs.key;
  }
}

3

ด้านล่างเป็นรหัสโดยใช้lambdas

#include "stdafx.h"
#include <vector>
#include <algorithm>

using namespace std;

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}
};

int main()
{
    std::vector < MyStruct > vec;

    vec.push_back(MyStruct(4, "test"));
    vec.push_back(MyStruct(3, "a"));
    vec.push_back(MyStruct(2, "is"));
    vec.push_back(MyStruct(1, "this"));

    std::sort(vec.begin(), vec.end(), 
        [] (const MyStruct& struct1, const MyStruct& struct2)
        {
            return (struct1.key < struct2.key);
        }
    );
    return 0;
}

1
    // sort algorithm example
    #include <iostream>     // std::cout
    #include <algorithm>    // std::sort
    #include <vector>       // std::vector
    using namespace std;
    int main () {
        char myints[] = {'F','C','E','G','A','H','B','D'};
        vector<char> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33
        // using default comparison (operator <):
        sort (myvector.begin(), myvector.end());           //(12 32 45 71)26 80 53 33
        // print out content:
        cout << "myvector contains:";
        for (int i=0; i!=8; i++)
            cout << ' ' <<myvector[i];
        cout << '\n';
        system("PAUSE");
    return 0;
    }

1

คุณสามารถใช้คลาสตัวเปรียบเทียบที่ผู้ใช้กำหนด

class comparator
{
    int x;
    bool operator()( const comparator &m,  const comparator &n )
    { 
       return m.x<n.x;
    }
 }

0

ในการจัดเรียงเวกเตอร์คุณสามารถใช้อัลกอริธึม sort ()

sort(vec.begin(),vec.end(),less<int>());

พารามิเตอร์ที่สามที่ใช้อาจมากกว่าหรือน้อยกว่าหรือสามารถใช้ฟังก์ชันหรือวัตถุใดก็ได้ อย่างไรก็ตามตัวดำเนินการเริ่มต้นคือ <ถ้าคุณปล่อยให้พารามิเตอร์ที่สามว่างเปล่า

// using function as comp
std::sort (myvector.begin()+4, myvector.end(), myfunction);
bool myfunction (int i,int j) { return (i<j); }

// using object as comp
std::sort (myvector.begin(), myvector.end(), myobject);

0
typedef struct Freqamp{
    double freq;
    double amp;
}FREQAMP;

bool struct_cmp_by_freq(FREQAMP a, FREQAMP b)
{
    return a.freq < b.freq;
}

main()
{
    vector <FREQAMP> temp;
    FREQAMP freqAMP;

    freqAMP.freq = 330;
    freqAMP.amp = 117.56;
    temp.push_back(freqAMP);

    freqAMP.freq = 450;
    freqAMP.amp = 99.56;
    temp.push_back(freqAMP);

    freqAMP.freq = 110;
    freqAMP.amp = 106.56;
    temp.push_back(freqAMP);

    sort(temp.begin(),temp.end(), struct_cmp_by_freq);
}

ถ้าเปรียบเทียบเป็นเท็จมันจะทำ "สลับ"


ภาษานี้จะไม่มีการคอมไพล์
LF
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.