【问题标题】:c++ checking an array for a specific range of values?c ++检查数组以获取特定范围的值?
【发布时间】:2012-04-09 18:48:38
【问题描述】:

我想检查一个数组是否有特定范围的值。 即,取值范围为 0 --> 9,实际数组为 50 个元素。

我还想跟踪每个值有多少。 即,如果有 3 个零、8 个 1 和 5 个 2,那么我的最终向量应该是 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;
}

【问题讨论】:

    标签: c++ arrays loops


    【解决方案1】:

    使用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;
    }
    

    这节省了一些空间,因为您不保存未使用的值,并且循环计数也少得多,因为每个值只处理一次。

    【讨论】:

    • 该死!我几乎完成了编写相同的代码来解决这个问题!为你投票,先生。
    • :D 我觉得有人也回答了这个问题,所以我加快了速度。
    • 谢谢!作为菜鸟,我并没有真正遵循 if 语句。我假设 min 和 max 是我的代码中的强度范围,但它如何检查两者之间的每个值?看起来它只是检查最小值和最大值,而不是两者之间的每个值....或者?
    • 你是对的 min 和 max 是范围,但它不会检查每个值,因为它不需要感谢 std::map。例如使用这种方法,您可以编写mymap[8] = 1;,它会自动创建一个 int 值,您可以将其用作您的值的计数器(此处为 8),每次进一步检查都会增加该值。稍后您只需遍历所有保存的计数器和值。
    • 仅当直方图人口稀少时,使用地图才有用。如果范围中的大多数元素可能会被填充,请使用初始化为范围长度的向量。地图是相对昂贵的数据结构。
    【解决方案2】:

    如果您的范围是连续的,我更喜欢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 模板 重新映射索引的参数。如果您映射非 您要计入连续值的连续值集 范围。如果您只想计数,您可能需要执行检查 具体值,但考虑到计数操作的代价, 我宁愿把它们都数一遍,而不是检查要数什么。

    【讨论】:

      【解决方案3】:

      使用std::mapstd::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);
      

      【讨论】:

        【解决方案4】:

        如果您有足够大的空白区域,您可以尝试使用多重集以及一些 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';
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-23
          • 2018-05-02
          • 2018-08-02
          • 1970-01-01
          • 1970-01-01
          • 2020-07-06
          相关资源
          最近更新 更多