c ++ проверяет массив для определенного диапазона значений? - PullRequest
3 голосов
/ 26 марта 2012

Я хотел бы проверить массив для определенного диапазона значений.т. е. диапазон значений составляет от 0 до> 9, а фактический массив состоит из 50 элементов.

Я также хочу отслеживать, сколько существует каждого значения.то есть, если есть 3 нуля, 8 единиц и 5 двойок, то мой конечный вектор должен выглядеть следующим образом: 3 8 5.

Я смог решить его с помощью кода ниже, НО, я понял, что мои значения диапазонадолжен быть равен размеру моего массива, иначе он не проверяет все элементы.

Есть ли лучший способ сделать это?

int main() {

int intensityRange = 10;
int cloudSize = 10;

int cloud [] = {0, 3, 3, 2, 1, 5, 2, 3, 5, 2};
vector <int> totalGreyValues;
int k = 0;

for (int i = 0; i < intensityRange; i++) {
   for (int j = 0; j < cloudSize; j++) {
      if (cloud[j] == i) {
         k = k + 1;
         cout << "   " << k;
      }
      else
        cout << "  no match  ";
   }
   totalGreyValues.push_back (k);
   k = 0;
}

cout << endl << endl << totalGreyValues.size();

for (int h = 0; h < totalGreyValues.size(); h ++)
   cout << "   " << totalGreyValues[h];

// values --> 0 1 2 3 4 5 6 7 8 9
// answer --> 1 1 3 3 0 2 0 0 0 0 

return 0;
}

Ответы [ 4 ]

4 голосов
/ 26 марта 2012

Гораздо проще использовать std::map:

int size = 50;
int data[size] = { 1, 2, 3, 4, 5, ... };

std::map<int, int> mymap;

for(int i = 0; i < size; i++)
{
   if(data[i] >= min && data[i] <= max)
      mymap[data[i]] = mymap[data[i]] + 1;
}

Это экономит некоторое пространство, потому что вы не сохраняете неиспользуемые значения и количество циклов также намного меньше, потому что вы обрабатываете только один раз для каждого значения.

0 голосов
/ 26 марта 2012

Если у вас достаточно больших пустых областей, вы можете попробовать мультимножество вместе с некоторыми из новых возможностей C ++:

#include <set>
#include <iostream>

int main () {
    int vals[] = { 0, 1, 2, 3, 4, 5, 5, 5, 6 };

    std::multiset <int> hist;
    for (auto const &v : vals)
        if (v >= 3 && v <= 5) hist.insert (v);

    for (auto const &v : hist)
        std::cout << v << " -> " << hist.count (v) << '\n';
}

Если ваши данные плотно заполнены, std::vector может дать превосходящие результаты:

#include <algorithm>
#include <iostream>

int main () {
    using std::begin; using std::end;

    int vals[] = { 1, 2, 4, 5, 5, 5, 6 };

    const auto val_mm  = std::minmax_element (begin(vals), end(vals));
    const int  val_min = *val_mm.first,
               val_max = *val_mm.second + 1;

    std::vector<int> hist (val_max - val_min);

    for (auto v : vals)
        ++hist [v - val_min];

    for (auto v : vals)
        std::cout << v << " -> " << hist[v-val_min] << '\n';
}
0 голосов
/ 26 марта 2012

Используйте std::map и функцию std::accumulate:

#include <map>
#include <algorithm>

typedef std::map<int, int> Histogram;

Histogram& addIfInRange(Histogram& histogram, const int value)
{
    if(inRange(value))
    {
        ++histogram[value];
    }
    // else don't add it

    return histogram;
}

Histogram histogram =
    std::accumulate(data, data + size, Histogram(), addIfInRange);
0 голосов
/ 26 марта 2012

Если ваш диапазон непрерывный, я бы предпочел boost :: vector_property_map .

#include <boost/property_map/vector_property_map.hpp>
#include <iostream>

int main()
{
  boost::vector_property_map<unsigned int> m(10); // size of expected range

  std::vector<int> cloud = {0, 3, 3, 2, 1, 5, 2, 3, 5, 2};
  for(auto x : cloud) { m[x]++; }
  for(auto it = m.storage_begin(); it != m.storage_end(); ++it) { 
    std::cout << *it << " ";
  }
  std::cout << std::endl;

  return 0;
}

Если ваш диапазон не начинается с 0, вы можете использовать IndexMap шаблон аргумент для переназначения индексов. Это также будет работать, если вы отображаете не непрерывный набор значений, которые вы хотите посчитать в непрерывный спектр. Возможно, вам придется выполнить проверку, если вы хотите только считать конкретные значения, но учитывая дороговизну операции подсчета, Я бы лучше посчитал их все вместо того, чтобы проверять, что считать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...