How to apply the concept of counting occurrences o

2020-04-21 04:40发布

问题:

following program ca calculate the frequency of ints in an array how to apply this concept on string variable because a string is also an array on the back end

using namespace std;
int counter[10]={0,0,0,0,0,0,0,0,0,0};
int arr [9][9],x;
int main()
{
    srand(time(NULL));

    cout<<"enter the array  \n";
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            arr[i][j]=rand()%10;
        }
    }

    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            cout<<arr[i][j]<<" ";
        }
        cout<<endl;
    }


    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            counter[arr[i][j]]++;

        }
    }

    for(int j=0;j<10;j++){
          cout<<j<<" : "<<  counter[j]<<endl;

        }
    return 0;
}

回答1:

Here is how one can count occurrences of anything from anything:

Code

#include <iterator>
#include <map>
#include <algorithm>

template<class InputIt>
auto
occurrences(InputIt begin, InputIt end)
{
    std::map<typename std::iterator_traits<InputIt>::value_type, std::size_t> result;
    std::for_each(begin, end, [&result](auto const& item){ ++result[item]; });
    return result;
}

Usage

#include <string>
#include <iostream>

int main()
{
    auto text = std::string{"Hello, World!"};
    auto occ = occurrences(begin(text), end(text));
    std::cout << occ['l'] << '\n'; // outputs 3
}

Live demo

Explanation

template<class InputIt>

This is a generic (template) function iterating over any input iterator.

auto

Its return type is inferred from its implementation. Spoiler alert: it is a std::map of (value counter, occurrence of this value).

occurrences(InputIt begin, InputIt end)

occurrences is called with a couple of iterators defining a range, generally calling begin(C) and end(C) on your container C.

std::for_each(begin, end, //...

For each element in the range...

[&result](auto const& item){ //...

...execute the following treatment...

++result[item]; });

...increment the occurrence count for the value item, starting with zero if its the first.

This is not an efficient implementation since it copies the values it counts. For integers, characters, etc. its perfect but for complex types you might want to improve this implementation.

It's generic and standard container compatible. You could count anything iterable.



回答2:

If I understand correctly, you want to count occurrences of strings. STL container map is useful for this purpose. Following is example code.

#include<iostream> 
#include<map> 
#include<string> 
#include<vector>                   

int main()
{
  std::vector<std::string> arrayString;
  std::map<std::string, int> counter;  
  std::map<std::string, int>::iterator it;

  arrayString.push_back("Hello");
  arrayString.push_back("World");
  arrayString.push_back("Hello");
  arrayString.push_back("Around");
  arrayString.push_back("the");
  arrayString.push_back("World");  

  // Counting logic
  for(std::string strVal : arrayString)
  {        
    it = counter.find(strVal);
    if(it != counter.end())
      it->second += 1; // increment count
    else    
      counter.insert(std::pair<std::string, int>(strVal, 1)); // first occurrence
  }

  // Results
  for(std::map<std::string, int>::iterator it = counter.begin(); it != counter.end(); ++it)  
    std::cout << it->first << ": " << it->second << std::endl;

  return 0;
}

More compact way to write the counting logic is :

  // Counting logic
  for(std::string strVal : arrayString)
  {
    ++counter[strVal]; // first time -> init to 0 and increment
  }


标签: c++ counting