find frequency in array using vector

Viewed 1304

How can I change my code to get a count for every element? With my code everything is okay. And it works, but how can I change only that part?

   #include <iostream>
   #include <vector> 

   void countFreq(int arr[], int n) 
   { 
      // Mark all array elements as not visited 
      std::vector<bool> visited(n, false); 

     // Traverse through array elements and 
     // count frequencies 
      for (int i = 0; i < n; i++) { 

      // Skip this element if already processed 
       if (visited[i] == true) 
            continue; 
      // Count frequency 
       int count = 1; 
       for (int j = i + 1; j < n; j++) { 
           if (arr[i] == arr[j]) { 
               visited[j] = true; 
               count++; 
              }  
      } 
       std::cout<<count<<" ";     
    } 
   } 

   int main() 
   { 
    int n;
    std::cin>>n;
    int arr[n];
    for(int i = 0; i < n; i++){
        std::cin>>arr[i];
    }
    countFreq(arr, n); 
    return 0; 
   } 

And about the result`

input 10
      1 1 2 2 3 3 4 4 5 5


output 2 2 2 2 2

but I want to get

 output 2 2 2 2 2 2 2 2 2 2

(for every element)

5 Answers

You can find the frequencies of numbers this way if you know the what is your maximum element in the input array. lets say m is maximum number in your array. so you have to create a new array of size m. you can simply co-relate them as m buckets. from 0 to m. And each bucket will hold the count of each element in the input array. The index of each bucket will refer to element in the input array. This has time complexity O(1) if we know what is the max element the array.

You can do this way:

std::vector<int> frequencey(std::vector<int>& nums){
    auto max = *(std::max_element(nums.begin(), nums.end()));
    std::vector<int> frequencies(max + 1, 0);
    for(int i = 0; i < nums.size(); ++i){
        frequencies[nums[i]] +=1;
    }

    return frequencies;
}

You need to save the result to an array for each number. Then when you find any processed number then print counter from the saved array.

#include <iostream>
#include <vector>
#include <unordered_map>

void countFreq(int arr[], int n)
{
    // Mark all array elements as not visited
    std::vector<bool> visited(n, false);
    std::unordered_map<int, int> counter;

    // Traverse through array elements and
    // count frequencies
    for (int i = 0; i < n; i++)
    {

        // Skip this element if already processed
        if (visited[i] == true)
        {
            std::cout << counter[arr[i]] << " ";
            continue;
        }
        // Count frequency
        int count = 1;
        for (int j = i + 1; j < n; j++)
        {
            if (arr[i] == arr[j])
            {
                visited[j] = true;
                count++;
            }
        }
        counter[arr[i]] = count;
        std::cout<<count<<" ";
    }
}

int main()
{
    int n;
    std::cin>>n;
    int arr[n];
    for(int i = 0; i < n; i++)
    {
        std::cin>>arr[i];
    }
    countFreq(arr, n);
    return 0;
}

Your function contains extra code that ends up confusing you. The visited variable is essentially unnecessary. Start the count at 0 and make no special case for the "current" cell and you'll find that some very simple code will do what you need:

void countFreq(int arr[], int n) 
{ 
    // Traverse through array elements and 
    // count frequencies 
    for (int i = 0; i < n; i++) { 

        // Count frequency 
        int count = 0; 
        for (int j = 0; j < n; j++) { 
            if (arr[i] == arr[j]) { 
                count++; 
            }  
        }

        std::cout << count << " ";     
   } 
}

The issue is that you discard the values already visited.

One possibility is instead to memorize the count when the value is visited the first time, and to memorize the index value of the first value appearance, when a value is visited the 2nd, 3rd ... time.

#include <iostream>
#include <vector> 

void countFreq(const std::vector<int>& arr) { 
   int n = arr.size();
      // Mark all array elements as not visited 
   std::vector<int> mem_count(n, n); 

     // Traverse through array elements and 
     // count frequencies 
    for (int i = 0; i < n; i++) { 

      // Skip this element if already processed 
        if (mem_count[i] != n) {
            std::cout << mem_count[mem_count[i]] << " ";
            continue; 
        }
        // Count frequency 
        int count = 1; 
        for (int j = i + 1; j < n; j++) { 
            if (arr[i] == arr[j]) { 
                  mem_count[j] = i; 
                  count++; 
            }  
        }
        mem_count[i] = count;
        std::cout << count << " ";     
    } 
} 

int main() { 
    int n;
    std::cin>>n;
    std::vector<int> arr(n);
    for(int i = 0; i < n; i++){
        std::cin >> arr[i];
    }
    countFreq(arr); 
    return 0; 
} 

This is very simple

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

void main()
{
    std::vector<int> v { 1,1,2,2,3,3,4,4,5,5 }; // Your input vector

    // Count "frequencies"
    std::map<int, int> m;
    for (auto i : v)
        m[i]++;

    // Print output
    for (auto i : v)
        std::cout << m[i] << " ";
}
Related