计算重复数并将这些计数器存储在数组c ++中

时间:2016-09-26 17:05:22

标签: c++

我们说我有{6,6,8,9,8,1} 6次重复2次,8次重复2次。 每个重复项应按计数器划分。所以它应该是{3,3,4,9,4,1}。

要做到这一点,我试图制作计数器阵列

e.g。 cntArray {2,2,2,1,2,1}(2:重复2次)

这样我可以用计数器划分这些数字

{6,6,8,9,8,1} / {2,2,2,1,2,1} = {3,3,4,9,4,1}

并且我还没有了解地图所以想要通过使用矢量来做到这一点,不使用地图进行排序。

这是我的代码:

int main() {
    vector<int> id_v;
    vector<int> gram_v;
    int id, gram = 0;
    int childNum = 0;
    int counter;
    int *cntArr = new int[0];

    cout << "Enter the number of children : ";
    cin >> childNum;

    for (int i = 0; i < childNum; i++) {
        cin >> id >> gram;
        id_v.push_back(id);
        gram_v.push_back(gram);
    }

    std::stable_sort(gram_v.begin(), gram_v.end(), acompare);
    for (int i = 0; i < childNum; i++) {
        for (counter = 1; i + counter < childNum && gram_v[i + counter] == gram_v[i];)
            counter++;

        if (counter > 1) {
//          cntArr[gram_v[i]] = counter;    //cntArr[100] = 2;
            for (int j = counter; j > 0; j--)
                gram_v[i - j + 1] /= counter;
            counter = 1;
        } else {
//          cntArr[gram_v[i]] = counter;    //cntArr[60] = 1;
            gram_v[i] /= counter;
        }

        cout << gram_v[i] << "\t" << endl;
    }
}

或者请给我一些更好的主意!

3 个答案:

答案 0 :(得分:2)

以下是我能想到的数字0-> 9的最简单方法:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> MyVec = {6, 6, 8, 9, 8, 1};
    int Counters[] = { 0,0,0,0,0,0,0,0,0,0 }; // indexes will represent numbers from 0->9

    for (int i = 0; i < MyVec.size; i++) // count each number
    {
        Counters[MyVec[i]]++;
    }

    for (int i = 0; i < MyVec.size; i++) // replace each number with it self divided by its counter
    {
        MyVec[i] = Counters[MyVec[i]];
    }

    return 0;
}

对于0-> 9以外的输入数据,以及Thomas Matthews的设计。这应该有效:

#include <iostream>
#include <vector>

struct Number_Counts
{
    int element;
    int counter;
    Number_Counts(int _element) { element = _element; counter = 1; }
};

bool IncrementIfFound(std::vector<Number_Counts> &, int );
int GetCounter(std::vector<Number_Counts>, int);

int main()
{
    std::vector<int> OriginalData = {6, 6, 8, 9, 8, 1};
    std::vector<Number_Counts> MyVector; 

    for (int i = 0; i < OriginalData.size(); i++) // populate counters
    {
        if (!IncrementIfFound(MyVector, OriginalData[i])) // if true, would be incremeneted already, if false, add as new 
        {
            Number_Counts temp(OriginalData[i]);
            MyVector.push_back(temp);
        }
    }

    for (int i = 0; i < OriginalData.size(); i++) // submit new value (old / its counter)
    {
        OriginalData[i] /= GetCounter(MyVector, OriginalData[i]);
    }

    return 0;
}

bool IncrementIfFound(std::vector<Number_Counts> &_Container, int _element)
{

    for(int i = 0; i < _Container.size(); i++ )
        if (_Container[i].element == _element)
        {
            _Container[i].counter++;
            return true;
        }
    return false;
}
int GetCounter(std::vector<Number_Counts> _Container, int _element)
{
    for (int i = 0; i < _Container.size(); i++)
        if (_Container[i].element == _element)
            return _Container[i].counter;
}

结果:

输入: {6, 6, 8, 9, 8, 1}

输出: 3 3 4 9 4 1

答案 1 :(得分:1)

我建议使用结构来跟踪值及其计数:

struct Number_Counts
{
  int value;
  int count;
};

您可以制作以下内容:

std::vector<Number_Counts> value_counts;

计算出现次数:

For each data item do:
  search `value_counts` for the value.
  if value exists, increment the counter.
  else add new entry to the value_counts vector.

由于您的作业未按执行时间评分,因此value_count的简单线性搜索就足够了。

编辑1:
value_counts向量中搜索值:

const unsigned int size = value_counts.size();
for (unsigned int i = 0; i < size; ++i)
{
  if (value == value_counts[i].value)
  {
    // Value exists already, so increment the counter
    ++value_counts[i].count;
    break;
  }
}
if (i >= size)
{
  // value was not found, so append a new entry
  Number_Counts nc;
  nc.value = value;
  nc.counts = 1;
  value_counts.push_back(nc);
}

答案 2 :(得分:0)

您声明您不熟悉字典数据结构。 FWIW,我仍然认为the answer using std::unordered_map是这里的方式(它具有较低的预期复杂性),如果有必要,你应该阅读数据结构。

话虽如此,一旦你的vector被排序,就很容易找到元素的多样性:

  • std::equal_range将以对数复杂度(通过二进制搜索的变体)找到与其对应的迭代器对。

  • 给定这对迭代器,您可以使用std::distance找到它们的距离。

所以,你的循环可以简化为:

std::sort(gram_v.begin(), gram_v.end());
for (int i = 0; i < childNum; i++) {
    const auto eq = equal_range(gram_v.begin(), gram_v.end(), id_v[i]);

    cout << id_v[i] / static_cast<double>(std::distance(eq.first, eq.second)) <<  endl;
}

请注意,由于您要对矢量进行排序,因此后续循环不会增加增长顺序。

P.S。在这种情况下,你不需要稳定的排序。