c ++ - 按特定顺序排列矢量元素

时间:2013-10-19 14:43:14

标签: c++ algorithm vector

我正在开始编程,很抱歉我缺乏知识。 如何按特定顺序在向量中设置元素?我想交换元素的方式不会有相同的元素彼此相邻。 例如,vector包含:

{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

1 个答案:

答案 0 :(得分:1)

  1. 计算每个值的出现次数。
  2. 从最频繁的值开始,用较不频繁的值替换它。
  3. 为了实现(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 << " ";
      }
    }
    

    您可以创建一个名称优于typedeffirst的替代计数器,而不是使用second,但这会使得从地图复制更加冗长。