2017-01-30 2 views
0

У меня есть карта типаКак оценивать значения в паре от 0 до 1? (Без использования C++ 11 или выше)

map <unsigned, vector < pair <unsigned, float> > > group 

Когда распечатывается, то float часть занимает и данных выглядит так:

Необработанные данные

0 43 0 
0 3690 0 
0 5085 62 
0 6085 63 
0 977 121 
0 4138 142 
1 1515 0 
1 2863 0 
1 6593 64 
1 252 96 
1 2887 141 

Я пытаюсь в настоящее время ранжировать float часть (третий столбец из печати) от 0 до 1, таким образом, что обработанные данные выглядит так:

Обработанные данные

0 43 0 
0 3690 0 
0 5085 0.4 
0 6085 0.6 
0 977 0.8 
0 4138 1 
1 1515 0 
1 2863 0 
1 5593 0.4 
1 6593 0.6 
1 252 0.8 
1 2887 1 

Я выполнил некоторые рейтинги, но никогда на pair и никогда от 0 - 1 (как правило, от 0 до размера вектора).

Любые руководства или решения будут высоко оценены, поскольку я чувствую себя совершенно потерянным в том, как подойти к нему.

+1

max_element (с пользовательской компаратором для проверки.), а затем for_each? – Borgleader

+0

Почему бы просто не перебрать карту, чтобы найти наибольшее значение третьего столбца, и использовать ее на втором проходе для вычисления нормализованного значения? –

+0

@SergeBallesta Потому что я не уверен, как его написать. Я думаю, что в любом случае я подхожу к нему, ему нужно найти наивысшую ценность и просеять его путь через потом. – Newskooler

ответ

0

Я не понял, что это точный алгоритм ранжирования вы хотите использовать, но вот отправная точка для вас:

#include <algorithm> 
#include <map> 
#include <vector> 
#include <utility> 


typedef std::pair<unsigned, float> Pair; 
typedef std::vector<Pair> Vec; 
typedef std::map<unsigned, Vec> Group; 

bool pairLess(Pair const & a, Pair const & b) { 
    return (a.second < b.second) 
     || (!((a.second < b.second) || (b.second < a.second)) 
      && (a.first < b.first)); 
} 

void rankGroup(Group & g) { 
    for (Group::iterator it = g.begin(); it != g.end(); ++it) { 
     if (it->second.empty()) 
      continue; 
     /// \todo handle case with one element? 
     Vec & v(it->second); 

     /// \todo Substitute for actual ranking algorithm: 
     Vec::iterator maxIt(std::max_element(v.begin(), v.end(), &pairLess)); 
     for (Vec::iterator it2 = v.begin(); it2 != v.end(); ++it2) 
      /// \todo handle division by zero: 
      it2->second = it2->second/maxIt->second; 
    } 
} 

Код для тестирования:

#include <iostream> 

std::ostream & operator<<(std::ostream & os, Group const & g) { 
    for (Group::const_iterator it = g.begin(); it != g.end(); ++it) { 
     unsigned key = it->first; 
     Vec const & v(it->second); 
     for (Vec::const_iterator it2 = v.begin(); it2 != v.end(); ++it2) 
      os << key << ' ' << it2->first << ' ' << it2->second << '\n'; 
    } 
    return os; 
} 

void groupAdd(Group & g, unsigned key, unsigned u, float f) 
{ g[key].push_back(Pair(u, f)); } 

int main() { 
    Group input; 
    groupAdd(input, 0, 43, 0); 
    groupAdd(input, 0, 3690, 0); 
    groupAdd(input, 0, 5085, 62); 
    groupAdd(input, 0, 6085, 63); 
    groupAdd(input, 0, 977, 121); 
    groupAdd(input, 0, 4138, 142); 
    groupAdd(input, 1, 1515, 0); 
    groupAdd(input, 1, 2863, 0); 
    groupAdd(input, 1, 6593, 64); 
    groupAdd(input, 1, 252, 96); 
    groupAdd(input, 1, 2887, 141); 
    std::cout << "INPUT:\n" << input << std::endl; 

    rankGroup(input); 
    std::cout << "RESULT:\n" << input << std::endl; 
} 
Смежные вопросы