我们说我有{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;
}
}
或者请给我一些更好的主意!
答案 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。在这种情况下,你不需要稳定的排序。