2012-03-26 4 views
3

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

Я также хочу отслеживать, сколько из каждого значения есть. т. Е. Если есть 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

Это гораздо проще в использовании 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; 
} 

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

+1

проклятье! Я почти закончил писать тот же код, чтобы решить это! повысьте для вас, сэр. –

+0

: D Я чувствовал, что есть кто-то, кто также отвечает на этот вопрос, поэтому я немного ускорился. – Pillum

+0

спасибо за это! Будучи noob, я действительно не следую инструкциям if. Я предполагаю, что min и max являются интенсивностью Range в моем коде, но как он проверяет каждое значение между ними? похоже, что он просто проверяет минимальное и максимальное значение, а не каждое значение между .... или? –

0

Если ваш диапазон непрерывный, я бы предпочел 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 шаблону аргумент переназначить индексов. Это также будет работать, если вы наберете непрерывный набор значений, которые вы хотите пересчитать в непрерывный диапазон . Возможно, вам потребуется выполнить проверку, если вы хотите только подсчитать значения , но с учетом стоимости операции подсчета, Я бы предпочел считать их, а не проверять, что считать.

0

Используйте 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

Если у вас есть большие достаточно пустые области, вы можете попробовать мультимножество, вместе с некоторыми из 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'; 
} 
Смежные вопросы