1

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;
}
Mihai
  • 2,807
  • 4
  • 28
  • 53
  • A number is a series of items from the alphabet [0..9]. A string is a series of items from a slightly larger alphabet. Assuming your string is regular ASCII, you could use [0..127] as your alphabet. This will still include some characters that are not printable (all <32, for example), but should suffice for your example. – Botje Feb 01 '19 at 10:02
  • Joke: once you're done with computing `char` frequencies on a `std::string`, you can basically do it on any type, like `std::basic_string` :D – YSC Feb 01 '19 at 10:03
  • Is your aim to count the occurrences of different strings, or of characters within a single string? – molbdnilo Feb 01 '19 at 10:25
  • i want to count the frequency of each individual character in a string –  Feb 02 '19 at 02:48

2 Answers2

4

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.

Community
  • 1
  • 1
YSC
  • 38,212
  • 9
  • 96
  • 149
  • For small and known "contiguous" "alphabet" (as digit/ascii alphabet), `std::array` might even replace `std::map`. – Jarod42 Feb 01 '19 at 10:27
  • 1
    Note: I originally wanted to find a duplicate of this question; didn't find one generic enough or valuable enough. This is why I wrote this answer. Now, I think there is [a lot of questions](https://stackoverflow.com/search?q=%5Bc%2B%2B%5D+counting+occurences) which could be closed as duplicate of _this_ one. As the author of this answer I'm not objective enough to do it. – YSC Feb 01 '19 at 10:27
  • @Jarod42 It could be done with specialization: `occurrences<42, ?>(/*...*/)` returning a `std::array*...*/, 42>` and `occurrences(/*...*/)` a `std::map`. `?` = _starting point_, like `'a'` for counting in `[a..z]`. – YSC Feb 01 '19 at 10:30
  • the answer would even be more duplicatable if you added a note on `map`s elements being sorted – 463035818_is_not_an_ai Feb 01 '19 at 12:22
  • Why do you use `typename` on this line `std::map::value_type, std::size_t> result;`? – Mihai Feb 01 '19 at 13:24
  • 1
    @Mihai good question. You'll find the answer (and a bit more) here: https://stackoverflow.com/q/610245/5470596. Short answer: because _I_ want the compiler to _parse_ `std::iterator_traits::value_type` as a type (it could be a value, it doesn't know). – YSC Feb 01 '19 at 14:11
  • That is amazing! Thank you! I referenced your solution [here](https://stackoverflow.com/q/54479308/5252007), on a question I literally asked two hours ago. – Mihai Feb 01 '19 at 14:20
0

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
  }
vcp
  • 962
  • 7
  • 15
  • You could simplify your code using [`std::map::operator[]`](https://en.cppreference.com/w/cpp/container/map/operator_at) as I did: it creates and zero-initializes values for unknown keys. – YSC Feb 01 '19 at 12:24