需要减少类似数组的数字(c ++)

时间:2016-03-08 21:24:07

标签: c++ arrays sorting

按照数组的降序排序,两个相同的元素必须消失,而是再输入1个 像这样: [12 8 8 6 4 3 3] => [12 9 6 5]

我试过这样,但完全是胡说八道:

vector<int> v(c, c + mn);

for ( i = 0; i < mn; i++)
{
    if (v[i] == v[i + 1])
    {
        v[i]++;
        v.erase(v.begin() + i + 1);
        i = 0;
    }
    for (auto&x : v)std::cout << x << ".";
}

P.S。:厌恶英语不好

3 个答案:

答案 0 :(得分:1)

你必须确保你没有超出范围:

  • 直到最后一个元素与未存在的下一个元素进行比较
  • 考虑到项目的删除会缩小向量的大小。

因此,一些小的修正可以让它发挥作用:

  vector<int> v{12,8,8,6,4,3,3};
  for (int i = 0; i < v.size()-1; i++)
  {
    if (v[i] == v[i + 1])
    {
        v[i]++;
        v.erase(v.begin() + i + 1);
        i = 0;
    }
  }
  for (auto&x : v)std::cout << x << ".";

Online demo

为避免多次通过,您也可以从结尾开始:

  for (int i = v.size()-2; i >=0; i--)
  {
    if (v[i] == v[i + 1])
    {
        v[i]++;
        v.erase(v.begin() + i + 1);
    }
  }

修改

@ knivil的评论指出,超过2个相同的元素(例如3个连续的8个而不是2个)可能导致向量中的不一致(最终结果不再被排序)。这里有一个修改后的版本,如果这些多次重复在这里是一个有效的案例,修改后的版本(假设n次重复,它还有1个而不是n-1个):

  for (int i = 0; i < v.size()-1; i++)
  {
    if (v[i] == v[i + 1])
    {
        while (i+1<v.size() && v[i+1]==v[i])
            v.erase(v.begin() + i + 1);
        v[i]++;
        i = 0;
    }
  }
  for (auto&x : v)std::cout << x << ".";

使用新的online demo

我留下你的练习来制作单程反转版本; - )

答案 1 :(得分:0)

一种方法是使用哈希映射来基本查看每个元素的频率。然后使用频率信息增加数据。

std::vector<int> result;
std::unordered_map<int, int> hashMap;
bool update = false;
for(auto cur : v) {
   hashMap[cur]++;  // intialize hash map with data
}
do {
   update = false;
   for (auto cur : hashMap) {
     if (cur.second == 2) {      // Process duplicate case
       hashMap[cur.first + 1]++; // add the +1 element
       hashMap.erase(cur.first); // remove the original
       update = true;            // set flag to perform another pass
     }
   }
} while(update);
for (auto cur : hashMap)
   result.push_back(cur.first);
std::sort(result.begin(), result.end(), std::greater<int>());
v = result;

试试here

答案 2 :(得分:0)

这是另一种解决问题的方法。

我有一个std::vector incremented,如果找到重复项,则会保留递增的值。

只要有要删除的重复项,就会运行while循环,增加找到的副本并将其添加到incremented向量。

每次运行后都会对矢量进行排序,以确保正确删除值,以便输出正确显示。

#include <iostream>   // std::cout
#include <vector>     // std::vector
#include <functional> // std::greater
#include <algorithm>  // std::sort

bool remove_duplicates(std::vector<int>& vec, std::vector<int>& incremented)
{ // return true if there is work, false otherwise
   bool work_done { false };
   for (int i = 1; i < vec.size(); ++i) {
      if (vec[i] == vec[i - 1]) {
         incremented.push_back(vec[i] + 1);
         auto it = vec.begin() + i;
         vec.erase(it - 1, it + 1);
         work_done = true;
      }
   }

   return work_done;
}

auto main() -> int
{
   std::vector<int> v { 12, 8, 8, 6, 4, 3, 3 };
   std::vector<int> incremented;

   while (remove_duplicates(v, incremented)) {
      for (const auto& i : incremented)
         v.push_back(i);
      std::sort(v.begin(), v.end(), std::greater<int>());
      incremented.clear();
   }

   // print result
   for (const auto& i : v)
      std::cout << i << " ";
}

输出:12 9 6 5

希望这看起来很有用。