2013-10-19 70 views
2

我開始編程,所以對於我缺乏知識感到抱歉。 如何在特定順序中設置向量中的元素?我想以不會有相鄰元素相鄰的方式交換元素。 例如向量包含:C++ - 按特定順序排列矢量元素

{1, 2, 2, 2, 3, 3, 4, 4, 4} 

,我想它是這樣的:

{1, 2, 4, 3, 4, 2, 3, 2, 4} 

感謝您的幫助。

編輯: 你好,我發現不是最好的解決方案,也許你可以看看,並糾正它?現在

map<unsigned,unsigned> Map; 
    for(vector<unsigned>::iterator i=V.begin();i!=V.end();++i) 
    { 
     map<unsigned,unsigned>::iterator f=Map.find(*i); 
     if(f==Map.end()) Map[*i]=1; 
     else ++f->second; 
    } 
    for(bool more=true;more;) 
    { 
     more=false; 
     for(map<unsigned,unsigned>::iterator i=Map.begin();i!=Map.end();++i) 
     { 
     if(i->second) 
      { 
      --i->second; 
      cout<<i->first<<", "; 
      more=true; 
      } 
     }    
    } 

,對於{1,2,2,2,3,3,4,4,4,4,4,4}它給我{1,2,3,4,2,3 ,4,2,4,4,4,4}而不是例如{4,1,4,2,4,3,4,2,4,3,4,2}。如何做呢?由於

學分:_13th_Dragon

+0

如果這是不可能的?取決於你想要的,儘管'std :: unique'可能有幫助。 – chris

+0

[算法來分離相同類型的項目]的可能重複(http://stackoverflow.com/questions/12375831/algorithm-to-separate-items-of-the-same-type) –

+1

您必須開發一個算法怎麼做。那麼你應該關心它的實施。乍一看,這似乎不是一個這樣簡單的問題。 –

回答

1
  1. 計算每個值的出現。
  2. 從最頻繁的值開始,用較不頻繁的值替換它。

爲了實現(1),可以簡單地使用std::map<V, unsigned>。但是,對於第二個,需要按第二個值排序的有序集合std::pair<V, unsigned int>。由於我們想要跟蹤我們需要使用給定值的次數,所以第二個值不能保持不變。另外,如果我們偶然減少給定值的數量,我們不想改變順序。總而言之,我們得到

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <map> 

// In the pair, first is the original value, while 
// second is the number occurrences of that value. 
typedef std::pair<int, unsigned> value_counter; 

int main(){ 
    std::vector<int> sequence = { 0, 1, 3, 3, 4, 1, 2, 2, 2, 2 , 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 }; 
    std::map<int, unsigned> count; 

    for(auto i : sequence){ 
    count[i]++; 
    } 

    std::vector<value_counter> store(count.size()); 
    std::copy(count.begin(), count.end(), store.begin()); 

    // Sort by the second value 
    std::sort(store.begin(), store.end(), 
    [](const value_counter& a, const value_counter& b){ 
     return a.second > b.second; 
    }); 

    std::vector<int> result; 

    // We need two indices, one for the current value 
    // and the other one for the alternative 
    for(unsigned i = 0, j = 1; i < store.size(); ++i){ 
    while(store[i].second > 0){ 
     result.push_back(store[i].first); 
     store[i].second--; 
     if(store[i].second == 0) 
     continue; 

     if(j <= i) 
     j = i + 1; 
     while(j < store.size() && store[j].second == 0) 
     ++j; 
     if(j >= store.size()){ 
     std::cerr << "Not enough elements for filling!" << std::endl; 
     return 1; 
     } 
     else { 
     result.push_back(store[j].first); 
     store[j].second--; 
     } 
    } 
    } 

    for(auto r : result){ 
    std::cout << r << " "; 
    } 
} 

而不是使用typedef你可以創建具有比firstsecond更好的名稱替代計數器,但使複製從地圖上一點點更詳細。

+0

謝謝!現在這是我找到的最好的解決方案。再次感謝您:) – pablo7890

+0

@ pablo7890:如果您對算法的複雜性感興趣:它應該是O(n log k),其中k是不同值的數量。 – Zeta

+0

謝謝。它可能對我有用。我還有一個問題,以前我不認爲我必須指定第一個和最後一個元素。它可以在你的算法中實現嗎?我可能知道如何添加第一個元素:定義向量結果只是push_back(first_element)並從1開始而不是從0開始循環,但我完全不知道,如何使它添加最後一個元素,所以最後一個和以前的一個不會是一樣的。 – pablo7890