2016-08-30 20 views
17

Tôi có đoạn mã sau:Làm thế nào để cải thiện các lồng cho vòng

// vector of elements 
vector<Graphic> graphics; 

// vector of indexes of the selected graphic elements 
vector<int> selected_indexes; 

// vector according to which the graphic elements have to be "sorted" and parsed 
vector<short> order; 

for (auto o : order) 
{ 
    for (auto i : selected_indexes) 
    { 
     const auto& g = graphics[i]; 

     if (g.position() == o) 
     { 
      // parse g 
     } 
    } 
} 

Tôi có một vector của các yếu tố tùy chỉnh cũng như các chỉ số trong những yếu tố đó đã được chọn để được phân tích, nhưng thứ tự mà các phần tử này phải được phân tích cú pháp phụ thuộc vào giá trị position() của chúng theo một vectơ thứ ba.

Có cách nào để cải thiện các vòng lặp lồng nhau này, tránh lặp đi lặp lại các thành phần sẽ bị bỏ qua vì vị trí của chúng không bằng với thứ tự hiện tại không?

+0

Những cải tiến bạn đang tìm kiếm, chúng có phải là tốc độ (thời gian thực hiện), khả năng đọc hoặc "sang trọng" không? – Niall

+0

@Niall Tôi đang tìm kiếm các cải tiến về tốc độ. – Nick

Trả lời

13

Giả sử chỉ có một Graphic đối tượng với một position() đưa ra:

Xây dựng một unordered_map: intGraphics*, mà bạn gọi ví dụ gp, sao cho gp[i]->position() = i.

Xây dựng bản đồ là thời gian tuyến tính, sử dụng bản đồ cho từng chỉ mục là khoảng thời gian cố định.

for(auto o : order) 
{ 
    auto const& g = *gp[o]; 
    // parse g 
} 

Nếu có thể có nhiều hơn một Graphics đối tượng với một vị trí nhất định, xây dựng một unordered_map: intvector<Graphic*>, sau đó với mã sử dụng như

for(auto o : order) 
{ 
    for(auto const p : gp[o]) 
    { 
     auto const& g = *p; 
     // parse g 
    } 
} 

Hoặc, đối với trường hợp cuối cùng bạn có thể sử dụng an unordered_multimap.

+0

Naively xây dựng bản đồ là tuyến tính trong số lượng đồ họa. Mã OP là O (MN) nhưng M là kích thước lựa chọn và N là kích thước đặt hàng, nó là O (1) trong số đồ họa. Hm: khi xây dựng, xây dựng từ vectơ của các chỉ mục được chọn. Điều đó giúp bạn xuống O (M + N)? Vâng. – Yakk

+1

Ký hiệu O không phải là mọi thứ mặc dù trong C++. Tùy thuộc vào kích thước có vector và sắp xếp nó và sau đó lặp lại có thể nhanh hơn việc lặp lại một bản đồ lớn. – Hayt

3

Bạn đã biết có bao nhiêu yếu tố mà bạn muốn xử lý, vì vậy bạn có thể sử dụng một vector mà giữ con trỏ để Graphic trường hợp của bạn, đã được phân bổ với số lượng thích hợp của các yếu tố:

vector<Graphic*> selected(selected_indexes.size(), nullptr); 

Sau đó, bạn có thể điền này vector với các yếu tố, sắp xếp sử dụng order:

for (auto index: selected_indexes) { 
    auto where = std::find_if(order.begin(), order.end(), [&graphics, index] (short i) { return i == graphics[index].position(); }); 
    selected[*where] = &graphics[index]; 
} 
3

Thay vì làm tổ này bạn có thể tạo một vector tạm thời và thực hiện bước này bước.

vector<Graphic> selectedGraphics; //maybe use ptr here 
selectedGraphics.reserve(selected_indexes.size()); 
for(auto i : selected_indexes) 
    selectedGraphics.push_back(graphics[i]); 

//then sort according to your order 
std::sort(selectedGraphics.begin(),selectedGraphics.end(),[order](auto left, auto right) 
{ 
    //the iterator of the position of "left" is further in front of the position of "right" 
    return order.find(left.position()) < order.find(right.position()); 
}); 

//then process 
for(auto graphic : selectedGraphics) 
    //do whatever 

Các loại giả định, rằng order mục vector và những người thân mà là selectedGraphics trận đấu. Tôi không chắc chắn nếu có bất kỳ tác dụng phụ lạ nào nếu một đối tượng đồ họa được chọn có vị trí không nằm trong vectơ order.

+0

Bạn có thể mở rộng quy trình sắp xếp không? (Ví dụ về thứ tự vectơ {2, 1, 3, 0, 4, 5}). – Nick

+1

OK Tôi đã chỉnh sửa câu trả lời. Nó sẽ hoạt động như thế. Tôi không thể kiểm tra nó mặc dù. – Hayt

+0

Tôi cũng đã thêm 'dự trữ' vì mục đích đầy đủ. – Hayt

Các vấn đề liên quan