Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;设计:给学生一份分数表,按顺序得到分数的频率 我有一个C++面试问题:_C++_Algorithm_Data Structures_Stl_Map - Fatal编程技术网

C++;设计:给学生一份分数表,按顺序得到分数的频率 我有一个C++面试问题:

C++;设计:给学生一份分数表,按顺序得到分数的频率 我有一个C++面试问题:,c++,algorithm,data-structures,stl,map,C++,Algorithm,Data Structures,Stl,Map,给出学生的分数列表,按顺序获得分数的频率。 [使用C++容器映射] < /P> 我的想法是:把分数列表放在一张地图上,分数作为键,频率作为值。在添加密钥之前,先搜索它。如果一个键是新的,添加它并将其频率设置为1。如果不是,则通过++1更新其频率。O(nlgn) 然后,在一个新的映射中反转键和值,将freq设置为键,将其分数设置为值。O(nlgn),因为map本身进行排序 存储器:O(n) 这不是很有效,因为我必须使用2张地图,并进行2次排序 欢迎提出任何意见或想法 谢谢 我的代码 #包括 #包

给出学生的分数列表,按顺序获得分数的频率。 [使用C++容器映射] < /P> 我的想法是:把分数列表放在一张地图上,分数作为键,频率作为值。在添加密钥之前,先搜索它。如果一个键是新的,添加它并将其频率设置为1。如果不是,则通过++1更新其频率。O(nlgn)

然后,在一个新的映射中反转键和值,将freq设置为键,将其分数设置为值。O(nlgn),因为map本身进行排序

存储器:O(n)

这不是很有效,因为我必须使用2张地图,并进行2次排序

欢迎提出任何意见或想法

谢谢


我的代码
#包括
#包括
#包括
#包括
使用名称空间std;
常数int M=10;
int A[M];
布尔myFunc(p1对,p2对)
{
//返回p1.second>p2.second;
}
整数分数图(整数*A,常数整数&N)
{
如果(A==NULL)
返回1;
地图map1;
迭代器itr;
int j=0;
while(jsecond);
}
++j;
}
//打印地图1

cout假设分数是一个狭窄的整数范围(1-100)

分数累积存储在成对的数组[score range]中,使用您的++[score]想法

通过以迭代方式向下移动分数列表来提取频率。O(N+M)N个分数范围+M个结果/分数。对结果进行排序

伪样本:

const size_t MAX_SCORE = 100; //  Min is assumed 0.
void scoreFrequencies(int [] scores, size_t N){
    pair<int,int> score_counts[MAX_SCORES];
    for(size_t i = 0; i < N; i++){
        score_counts[i].first++;
        score_counts[i].second = i;
    }
    sort( score_counts, score_counts+MAX_SCORES );
    for(size_t score_decreasing = MAX_SCORES-1; 
             score_counts[score_decreasing].first!=0 && score_decreasing >=0; 
             score_decreasing--)
         cout<< (score_counts.second) <<": " << 
                 ( score_counts.first*1.0/N ) << endl;
}
const size\u t MAX\u SCORE=100;//最小值假定为0。
无效分数频率(整数[]分数,大小\u t N){
配对分数计数[最大分数];
对于(大小i=0;i=0;
分数下降--)

cout不使用映射,只需使用数组类型
std::pair
定义所有分数的柱状图。一个成员将是分数,另一个是频率。最初分数将与它们所在的数组索引值相同,但您只应在尝试访问每个特定分数索引时进行初始化x、 否则,您将初始化一组不存在的分数。然后在为分数本身填充直方图后,根据分数的频率对数组进行排序。由于直方图中的分数基本上类似于非常简单的哈希查找,因此总体时间应该非常快(…O(1)对于每个分数查找和相关的频率增量,以及O(n log n)进行排序)

这里有一些代码可以帮助解释:

std::pair<int, int> scores[SCORE_RANGE] = {0}; //zero-out the entire array

//...iterate through your score data
for (int i=0; i < SCORE_DATA_SIZE; i++)
{
    int score_val = raw_score_data[i];

    if (scores[score_val].first == 0)
    {
        scores[score_val].first = score_val;
    }

    scores[score_val].second++;
}

//now sort your scores array based on the frequency which is stored in the second
//member of the std::pair structure
std::pair scores[SCORE\u RANGE]={0};//将整个数组归零
//…遍历您的分数数据
对于(int i=0;i
我的想法是:把分数列表放在一张地图上,分数作为键,频率作为值

到目前为止,一切顺利

在添加密钥之前,搜索它。如果密钥是新的,则添加它并将其频率设置为1。如果不是,则通过++1.O(nlgn)更新其频率

检查地图条目的存在是不必要的,也是浪费。该条目在第一次被引用时将突然存在(使用默认值)。只需执行以下操作:

++scoreMap[score];
这不会改变你的大O,但会让你跑得更快

然后,在新映射中反转键和值,其中将freq设置为键,将其分数设置为value.O(nlgn),因为映射本身进行排序

你不能使用新地图,因为分数不一定是唯一的。但是你可以使用
set

为了在我的电脑上正确安装Ubuntu 11.10(和g++4.6!),下面是如何使用lambdas来解决这个问题:

  map<int, int> scoreMap;
  for_each(istream_iterator<int>(cin), istream_iterator<int>(),
    [&scoreMap] (int i) { ++scoreMap[i]; } );
  set<pair<int,int>> freqMap;
  for_each(scoreMap.begin(), scoreMap.end(),
    [&freqMap] (const pair<int,int>& p) {
      freqMap.insert(make_pair(p.second, p.first));
    } );
  for_each(freqMap.rbegin(), freqMap.rend(),
    [] (const pair<int,int>& p) {
      cout << p.second << "/" << p.first << "\n";
    } );
map评分图;
对于每个(istream_迭代器(cin),istream_迭代器(),
[&scoreMap](inti){++scoreMap[i];});
设置频率图;
对于每个(scoreMap.begin()、scoreMap.end(),
[&freqMap](常量对&p){
freqMap.insert(生成配对(p.second,p.first));
} );
对于每个(freqMap.rbegin(),freqMap.rend(),
[](常数对和p){

分数是否有限制?分数是否为整数类型?分数是否在限定范围内?返回分数频率的顺序是什么?是否必须使用map?是否可以使用无序_map?如果您知道需要使用,为什么支付日志(n)对于inserts.unordered_map with->vector->RESTOR on FRENCE。分数可以是int或float。它在[1100]范围内。必须使用map。但是,在演示如何使用map后,您可以提出更好的解决方案。您不能在直方图中存储“仅分数”,因为如果您要使用另一个“键”(频率)您还需要将分数保存在直方图中。但是,如果分数在足够小的范围内,这个概念很好。请记住,我建议分数是数组索引本身,而不是存储在每个数组索引中的值。如果分数相距太远,那么是的,您将得到太多的“空”数组中的区域,但由于排序时间仍然是O(n log n),并且插入时间是O(1),这将比使用
std::map
更快。此外,如果您想快速清除空区域,可以将它们初始化为MAX_值+1,以便在排序之后,它们都在数组末尾建立索引,您只需执行以下操作即可
  map<int, int> scoreMap;
  for_each(istream_iterator<int>(cin), istream_iterator<int>(),
    [&scoreMap] (int i) { ++scoreMap[i]; } );
  set<pair<int,int>> freqMap;
  for_each(scoreMap.begin(), scoreMap.end(),
    [&freqMap] (const pair<int,int>& p) {
      freqMap.insert(make_pair(p.second, p.first));
    } );
  for_each(freqMap.rbegin(), freqMap.rend(),
    [] (const pair<int,int>& p) {
      cout << p.second << "/" << p.first << "\n";
    } );