Count the frequency of integers in an arrayBit-twiddling for a custom image formatSmallest MultipleCreate ranges from an array of integersUVA #10258 - Contest ScoreboardInterpreter programming challengeA Simple Console Based Keno/Lottery Game in C++RDS receiver - synchronization and error correctionC# TCP server/client classLeast cost swapping in C++Count the frequency of items in an array

Sleeping solo in a double sleeping bag

Is this kind of description not recommended?

Alchemist potion on Undead

Infinite loop in CURSOR

My two team members in a remote location don't get along with each other; how can I improve working relations?

Land Registry Clause

Is there any road between the CA State Route 120 and Sherman Pass Road (Forest Route 22S0) that crosses Yosemite/Serria/Sequoia National Park/Forest?

Was Switzerland really impossible to invade during WW2?

What can I do to keep a threaded bolt from falling out of it’s slot

How does the Saturn V Dynamic Test Stand work?

Chess software to analyze games

How to get distinct values from an array of arrays in JavaScript using the filter() method?

How big would a Daddy Longlegs Spider need to be to kill an average Human?

How can I describe being temporarily stupid?

Are there any OR challenges that are similar to kaggle's competitions?

Unbiased estimator of exponential of measure of a set?

How to avoid using System.String with Rfc2898DeriveBytes in C#

How could China have extradited people for political reason under the extradition law it wanted to pass in Hong Kong?

How to compare two different formulations of a problem?

To "hit home" in German

Is there a known non-euclidean geometry where two concentric circles of different radii can intersect? (as in the novel "The Universe Between")

Is there such a thing as too inconvenient?

Why don't sharp and flat root note chords seem to be present in much guitar music?

Did the twin engined Lazair ultralight have a throttle for each engine?



Count the frequency of integers in an array


Bit-twiddling for a custom image formatSmallest MultipleCreate ranges from an array of integersUVA #10258 - Contest ScoreboardInterpreter programming challengeA Simple Console Based Keno/Lottery Game in C++RDS receiver - synchronization and error correctionC# TCP server/client classLeast cost swapping in C++Count the frequency of items in an array






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








4












$begingroup$


I recently reviewed a question here on Code Review. The problem statement is




Write a program that prompts the user to input ten values between 80 and 85 and stores them in an array. Your program must be able to count the frequency of each value appears in the array.




I coded my own solution for the problem statement. My questions are

- Can this be optimized more?

- Did I miss anything in C++14 or C++17 that might improve the code?

- Is the code readable?

- Are the variable and function names good or can they be improved?



My goals were to write the best C++ I could, remove any magic numbers and allow the solution to scale for different sets of numbers.



#include "pch.h"
#include <iostream>
#include <array>

const size_t INPUTSIZE = 10;
const size_t FREQUENCYSIZE = 6;
const int MINLEGALVALUE = 80;
const int MAXLEGALVALUE = 85;

std::array<int, INPUTSIZE> getUserInput()

std::array<int, INPUTSIZE> inputValues;

size_t i = 0;
do

int inputValue = 0;
std::cout << "Please enter a number between " << MINLEGALVALUE << " and " << MAXLEGALVALUE << ":" ;
std::cin >> inputValue;

if (inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)

inputValues[i] = inputValue;
i++;

else

std::cout << "The number must be between" << MINLEGALVALUE << " and " << MAXLEGALVALUE << "n";


while (i < INPUTSIZE);

return inputValues;


std::array<unsigned, FREQUENCYSIZE> getFrequencyCounts(std::array<int, INPUTSIZE> inputValues)

std::array<unsigned, FREQUENCYSIZE> freqs = 0 ;

for (auto inputs : inputValues)

freqs[inputs - MINLEGALVALUE]++;


return freqs;


void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)

unsigned rowLabel = MINLEGALVALUE;
for (auto frequency : freqs)

std::cout << rowLabel << " " << frequency << "n";
rowLabel++;



int main()

std::array<int, INPUTSIZE> inputValues = getUserInput();
std::array<unsigned, FREQUENCYSIZE> freqs = getFrequencyCounts(inputValues);

std::cout << "n";

printFrequencies(freqs);










share|improve this question









$endgroup$









  • 1




    $begingroup$
    You've asked for optimizations, but the input size is too small for the usual histogramming optimizations to matter, and anyway the program spends all of its time doing IO. Do you want to know about them anyway?
    $endgroup$
    – harold
    7 hours ago

















4












$begingroup$


I recently reviewed a question here on Code Review. The problem statement is




Write a program that prompts the user to input ten values between 80 and 85 and stores them in an array. Your program must be able to count the frequency of each value appears in the array.




I coded my own solution for the problem statement. My questions are

- Can this be optimized more?

- Did I miss anything in C++14 or C++17 that might improve the code?

- Is the code readable?

- Are the variable and function names good or can they be improved?



My goals were to write the best C++ I could, remove any magic numbers and allow the solution to scale for different sets of numbers.



#include "pch.h"
#include <iostream>
#include <array>

const size_t INPUTSIZE = 10;
const size_t FREQUENCYSIZE = 6;
const int MINLEGALVALUE = 80;
const int MAXLEGALVALUE = 85;

std::array<int, INPUTSIZE> getUserInput()

std::array<int, INPUTSIZE> inputValues;

size_t i = 0;
do

int inputValue = 0;
std::cout << "Please enter a number between " << MINLEGALVALUE << " and " << MAXLEGALVALUE << ":" ;
std::cin >> inputValue;

if (inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)

inputValues[i] = inputValue;
i++;

else

std::cout << "The number must be between" << MINLEGALVALUE << " and " << MAXLEGALVALUE << "n";


while (i < INPUTSIZE);

return inputValues;


std::array<unsigned, FREQUENCYSIZE> getFrequencyCounts(std::array<int, INPUTSIZE> inputValues)

std::array<unsigned, FREQUENCYSIZE> freqs = 0 ;

for (auto inputs : inputValues)

freqs[inputs - MINLEGALVALUE]++;


return freqs;


void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)

unsigned rowLabel = MINLEGALVALUE;
for (auto frequency : freqs)

std::cout << rowLabel << " " << frequency << "n";
rowLabel++;



int main()

std::array<int, INPUTSIZE> inputValues = getUserInput();
std::array<unsigned, FREQUENCYSIZE> freqs = getFrequencyCounts(inputValues);

std::cout << "n";

printFrequencies(freqs);










share|improve this question









$endgroup$









  • 1




    $begingroup$
    You've asked for optimizations, but the input size is too small for the usual histogramming optimizations to matter, and anyway the program spends all of its time doing IO. Do you want to know about them anyway?
    $endgroup$
    – harold
    7 hours ago













4












4








4





$begingroup$


I recently reviewed a question here on Code Review. The problem statement is




Write a program that prompts the user to input ten values between 80 and 85 and stores them in an array. Your program must be able to count the frequency of each value appears in the array.




I coded my own solution for the problem statement. My questions are

- Can this be optimized more?

- Did I miss anything in C++14 or C++17 that might improve the code?

- Is the code readable?

- Are the variable and function names good or can they be improved?



My goals were to write the best C++ I could, remove any magic numbers and allow the solution to scale for different sets of numbers.



#include "pch.h"
#include <iostream>
#include <array>

const size_t INPUTSIZE = 10;
const size_t FREQUENCYSIZE = 6;
const int MINLEGALVALUE = 80;
const int MAXLEGALVALUE = 85;

std::array<int, INPUTSIZE> getUserInput()

std::array<int, INPUTSIZE> inputValues;

size_t i = 0;
do

int inputValue = 0;
std::cout << "Please enter a number between " << MINLEGALVALUE << " and " << MAXLEGALVALUE << ":" ;
std::cin >> inputValue;

if (inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)

inputValues[i] = inputValue;
i++;

else

std::cout << "The number must be between" << MINLEGALVALUE << " and " << MAXLEGALVALUE << "n";


while (i < INPUTSIZE);

return inputValues;


std::array<unsigned, FREQUENCYSIZE> getFrequencyCounts(std::array<int, INPUTSIZE> inputValues)

std::array<unsigned, FREQUENCYSIZE> freqs = 0 ;

for (auto inputs : inputValues)

freqs[inputs - MINLEGALVALUE]++;


return freqs;


void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)

unsigned rowLabel = MINLEGALVALUE;
for (auto frequency : freqs)

std::cout << rowLabel << " " << frequency << "n";
rowLabel++;



int main()

std::array<int, INPUTSIZE> inputValues = getUserInput();
std::array<unsigned, FREQUENCYSIZE> freqs = getFrequencyCounts(inputValues);

std::cout << "n";

printFrequencies(freqs);










share|improve this question









$endgroup$




I recently reviewed a question here on Code Review. The problem statement is




Write a program that prompts the user to input ten values between 80 and 85 and stores them in an array. Your program must be able to count the frequency of each value appears in the array.




I coded my own solution for the problem statement. My questions are

- Can this be optimized more?

- Did I miss anything in C++14 or C++17 that might improve the code?

- Is the code readable?

- Are the variable and function names good or can they be improved?



My goals were to write the best C++ I could, remove any magic numbers and allow the solution to scale for different sets of numbers.



#include "pch.h"
#include <iostream>
#include <array>

const size_t INPUTSIZE = 10;
const size_t FREQUENCYSIZE = 6;
const int MINLEGALVALUE = 80;
const int MAXLEGALVALUE = 85;

std::array<int, INPUTSIZE> getUserInput()

std::array<int, INPUTSIZE> inputValues;

size_t i = 0;
do

int inputValue = 0;
std::cout << "Please enter a number between " << MINLEGALVALUE << " and " << MAXLEGALVALUE << ":" ;
std::cin >> inputValue;

if (inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)

inputValues[i] = inputValue;
i++;

else

std::cout << "The number must be between" << MINLEGALVALUE << " and " << MAXLEGALVALUE << "n";


while (i < INPUTSIZE);

return inputValues;


std::array<unsigned, FREQUENCYSIZE> getFrequencyCounts(std::array<int, INPUTSIZE> inputValues)

std::array<unsigned, FREQUENCYSIZE> freqs = 0 ;

for (auto inputs : inputValues)

freqs[inputs - MINLEGALVALUE]++;


return freqs;


void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)

unsigned rowLabel = MINLEGALVALUE;
for (auto frequency : freqs)

std::cout << rowLabel << " " << frequency << "n";
rowLabel++;



int main()

std::array<int, INPUTSIZE> inputValues = getUserInput();
std::array<unsigned, FREQUENCYSIZE> freqs = getFrequencyCounts(inputValues);

std::cout << "n";

printFrequencies(freqs);







c++ performance c++14 c++17






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 9 hours ago









pacmaninbwpacmaninbw

7,2822 gold badges20 silver badges44 bronze badges




7,2822 gold badges20 silver badges44 bronze badges










  • 1




    $begingroup$
    You've asked for optimizations, but the input size is too small for the usual histogramming optimizations to matter, and anyway the program spends all of its time doing IO. Do you want to know about them anyway?
    $endgroup$
    – harold
    7 hours ago












  • 1




    $begingroup$
    You've asked for optimizations, but the input size is too small for the usual histogramming optimizations to matter, and anyway the program spends all of its time doing IO. Do you want to know about them anyway?
    $endgroup$
    – harold
    7 hours ago







1




1




$begingroup$
You've asked for optimizations, but the input size is too small for the usual histogramming optimizations to matter, and anyway the program spends all of its time doing IO. Do you want to know about them anyway?
$endgroup$
– harold
7 hours ago




$begingroup$
You've asked for optimizations, but the input size is too small for the usual histogramming optimizations to matter, and anyway the program spends all of its time doing IO. Do you want to know about them anyway?
$endgroup$
– harold
7 hours ago










3 Answers
3






active

oldest

votes


















2












$begingroup$

Names



All-caps names are typically reserved for macros. They don't seem to me to make much sense for const variables. In fact, they only make minimal sense for object-like macros--they were originally used for function-like macros as kind of a warning that you should be cautious about passing an argument with side-effects, because they might happen more than once.



Minimize Magic



I'd typically try to keep the magic numbers to a minimum. For example, instead of defining FREQUENCYSIZE by itself, I'd probably do something like this:



const int lower_bound = 80;
count int upper_bound = 85;
const int frequency_size = upper_bound - lower_bound + 1;


Separation of Concerns



I'd at least consider separating validating data from reading the data. I'd prefer to have a function on the general order of:



bool valid(int val) 
return val >= lower_bound && val < upper_bound;



Class Usage



We have a number of different things related to reading and working with numbers in a specified range. It might be worth considering wrapping those bits and pieces into a coherent class for dealing with a value in a range, and let the outside world create and use objects of that class.



template <class T, T lower_bound, T upper_bound>
class bounded
public:
static bool valid(T val) return val >= lower_bound && val < upper_bound;

friend std::istream &operator>>(std::istream &is, bounded &b)
T val;
is >> val;
if (valid(val))
b.val = val;
else
is.setstate(std::ios_base::failbit);
return is;


friend std::ostream &operator<<(std::ostream &os, bounded const &b)
return os << b.val;


size_t index() return size_t(val - lower_bound);

static constexpr size_t range() return upper_bound - lower_bound + 1;

private:
T val;
;


That let's us simplify the rest of the code a bit, something on this general order:



int main() 
using integer = bounded<int, 80, 85>;

std::array<integer, 10> inputs;
std::array<size_t, integer::range()> freqs ;

for (integer &i : inputs)
std::cin >> i;
++freqs[i.index()];


for (auto freq : freqs)
std::cout << freq << "n";



Technically, this doesn't meet the requirements as-is (e.g., it doesn't print out a prompt to tell the user to enter data), but I think it gives at least some idea of a direction things could go.






share|improve this answer









$endgroup$






















    1












    $begingroup$

    If you go for modern C++ the static variables should be marked as constexpr instead of plain old const.



    As was said in the other question, it should be beneficial to create an array of length MAXLEGALVALUE - MINLEGALVALUE and directly index into that array. That way there is probably less memory consumed and we count automatically.



    Personally I would use std::size_t or a well specified integer type like std::uint32_t rather than unsigned, which depends on the implementation.



    In range based for loops where the type is unambiguous I am not really a fan of auto.



    for (auto inputs : inputValues)


    How do you know that copying it is cheap here? You have to check the type of the container. Also you should consider const correctness so rather use const int or const auto if you prefere that.



    for (const int inputs : inputValues)


    Note that you have a truncation warning here as MINLEGALVALUE is of type int:



    unsigned rowLabel = MINLEGALVALUE;





    share|improve this answer









    $endgroup$






















      1












      $begingroup$

      One idea for simplification is to count frequencies directly instead of putting all the values in an array that you only use for counting frequencies. You can then remove the getFrequencyCounts function and the whole thing gets a little more efficient. This works well when you have a set of values in a dense range like [80,85]. If you have a lot of values far between eachother, using a set or unordered_set is probably a better choice. I found the code easy enough to read. Here are some ideas with comments in the code:



      #include <array>
      #include <iostream>

      constexpr size_t INPUTSIZE = 10;
      constexpr int MINLEGALVALUE = 80;
      constexpr int MAXLEGALVALUE = 85;
      constexpr size_t FREQUENCYSIZE = MAXLEGALVALUE - MINLEGALVALUE + 1;

      std::array<unsigned, FREQUENCYSIZE> getUserInputFreq()
      std::array<unsigned, FREQUENCYSIZE> inputValues0; // initialize with 0

      size_t i = 0;
      do
      int inputValue = 0;
      std::cout << "Please enter a number between " << MINLEGALVALUE << " and "
      << MAXLEGALVALUE << ":";

      // make sure the istream you read from succeeded in extracting
      if(std::cin >> inputValue)
      if(inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)
      // count frequencies directly if you don't actually need the
      // input values
      ++inputValues[static_cast<size_t>(inputValue - MINLEGALVALUE)];
      ++i; // prefer prefix operator++
      else
      std::cout << "The number must be between" << MINLEGALVALUE << " and "
      << MAXLEGALVALUE << "n";

      else
      break; // erroneous input or EOF

      while(i < INPUTSIZE);

      return inputValues;


      void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)
      int rowLabel = MINLEGALVALUE;
      for(auto frequency : freqs)
      std::cout << rowLabel << " " << frequency << "n";
      ++rowLabel; // prefer prefix operator++



      int main()
      std::array<unsigned, FREQUENCYSIZE> freqs = getUserInputFreq();

      std::cout << "n";

      printFrequencies(freqs);






      share|improve this answer









      $endgroup$

















        Your Answer






        StackExchange.ifUsing("editor", function ()
        StackExchange.using("externalEditor", function ()
        StackExchange.using("snippets", function ()
        StackExchange.snippets.init();
        );
        );
        , "code-snippets");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "196"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );













        draft saved

        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226448%2fcount-the-frequency-of-integers-in-an-array%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        2












        $begingroup$

        Names



        All-caps names are typically reserved for macros. They don't seem to me to make much sense for const variables. In fact, they only make minimal sense for object-like macros--they were originally used for function-like macros as kind of a warning that you should be cautious about passing an argument with side-effects, because they might happen more than once.



        Minimize Magic



        I'd typically try to keep the magic numbers to a minimum. For example, instead of defining FREQUENCYSIZE by itself, I'd probably do something like this:



        const int lower_bound = 80;
        count int upper_bound = 85;
        const int frequency_size = upper_bound - lower_bound + 1;


        Separation of Concerns



        I'd at least consider separating validating data from reading the data. I'd prefer to have a function on the general order of:



        bool valid(int val) 
        return val >= lower_bound && val < upper_bound;



        Class Usage



        We have a number of different things related to reading and working with numbers in a specified range. It might be worth considering wrapping those bits and pieces into a coherent class for dealing with a value in a range, and let the outside world create and use objects of that class.



        template <class T, T lower_bound, T upper_bound>
        class bounded
        public:
        static bool valid(T val) return val >= lower_bound && val < upper_bound;

        friend std::istream &operator>>(std::istream &is, bounded &b)
        T val;
        is >> val;
        if (valid(val))
        b.val = val;
        else
        is.setstate(std::ios_base::failbit);
        return is;


        friend std::ostream &operator<<(std::ostream &os, bounded const &b)
        return os << b.val;


        size_t index() return size_t(val - lower_bound);

        static constexpr size_t range() return upper_bound - lower_bound + 1;

        private:
        T val;
        ;


        That let's us simplify the rest of the code a bit, something on this general order:



        int main() 
        using integer = bounded<int, 80, 85>;

        std::array<integer, 10> inputs;
        std::array<size_t, integer::range()> freqs ;

        for (integer &i : inputs)
        std::cin >> i;
        ++freqs[i.index()];


        for (auto freq : freqs)
        std::cout << freq << "n";



        Technically, this doesn't meet the requirements as-is (e.g., it doesn't print out a prompt to tell the user to enter data), but I think it gives at least some idea of a direction things could go.






        share|improve this answer









        $endgroup$



















          2












          $begingroup$

          Names



          All-caps names are typically reserved for macros. They don't seem to me to make much sense for const variables. In fact, they only make minimal sense for object-like macros--they were originally used for function-like macros as kind of a warning that you should be cautious about passing an argument with side-effects, because they might happen more than once.



          Minimize Magic



          I'd typically try to keep the magic numbers to a minimum. For example, instead of defining FREQUENCYSIZE by itself, I'd probably do something like this:



          const int lower_bound = 80;
          count int upper_bound = 85;
          const int frequency_size = upper_bound - lower_bound + 1;


          Separation of Concerns



          I'd at least consider separating validating data from reading the data. I'd prefer to have a function on the general order of:



          bool valid(int val) 
          return val >= lower_bound && val < upper_bound;



          Class Usage



          We have a number of different things related to reading and working with numbers in a specified range. It might be worth considering wrapping those bits and pieces into a coherent class for dealing with a value in a range, and let the outside world create and use objects of that class.



          template <class T, T lower_bound, T upper_bound>
          class bounded
          public:
          static bool valid(T val) return val >= lower_bound && val < upper_bound;

          friend std::istream &operator>>(std::istream &is, bounded &b)
          T val;
          is >> val;
          if (valid(val))
          b.val = val;
          else
          is.setstate(std::ios_base::failbit);
          return is;


          friend std::ostream &operator<<(std::ostream &os, bounded const &b)
          return os << b.val;


          size_t index() return size_t(val - lower_bound);

          static constexpr size_t range() return upper_bound - lower_bound + 1;

          private:
          T val;
          ;


          That let's us simplify the rest of the code a bit, something on this general order:



          int main() 
          using integer = bounded<int, 80, 85>;

          std::array<integer, 10> inputs;
          std::array<size_t, integer::range()> freqs ;

          for (integer &i : inputs)
          std::cin >> i;
          ++freqs[i.index()];


          for (auto freq : freqs)
          std::cout << freq << "n";



          Technically, this doesn't meet the requirements as-is (e.g., it doesn't print out a prompt to tell the user to enter data), but I think it gives at least some idea of a direction things could go.






          share|improve this answer









          $endgroup$

















            2












            2








            2





            $begingroup$

            Names



            All-caps names are typically reserved for macros. They don't seem to me to make much sense for const variables. In fact, they only make minimal sense for object-like macros--they were originally used for function-like macros as kind of a warning that you should be cautious about passing an argument with side-effects, because they might happen more than once.



            Minimize Magic



            I'd typically try to keep the magic numbers to a minimum. For example, instead of defining FREQUENCYSIZE by itself, I'd probably do something like this:



            const int lower_bound = 80;
            count int upper_bound = 85;
            const int frequency_size = upper_bound - lower_bound + 1;


            Separation of Concerns



            I'd at least consider separating validating data from reading the data. I'd prefer to have a function on the general order of:



            bool valid(int val) 
            return val >= lower_bound && val < upper_bound;



            Class Usage



            We have a number of different things related to reading and working with numbers in a specified range. It might be worth considering wrapping those bits and pieces into a coherent class for dealing with a value in a range, and let the outside world create and use objects of that class.



            template <class T, T lower_bound, T upper_bound>
            class bounded
            public:
            static bool valid(T val) return val >= lower_bound && val < upper_bound;

            friend std::istream &operator>>(std::istream &is, bounded &b)
            T val;
            is >> val;
            if (valid(val))
            b.val = val;
            else
            is.setstate(std::ios_base::failbit);
            return is;


            friend std::ostream &operator<<(std::ostream &os, bounded const &b)
            return os << b.val;


            size_t index() return size_t(val - lower_bound);

            static constexpr size_t range() return upper_bound - lower_bound + 1;

            private:
            T val;
            ;


            That let's us simplify the rest of the code a bit, something on this general order:



            int main() 
            using integer = bounded<int, 80, 85>;

            std::array<integer, 10> inputs;
            std::array<size_t, integer::range()> freqs ;

            for (integer &i : inputs)
            std::cin >> i;
            ++freqs[i.index()];


            for (auto freq : freqs)
            std::cout << freq << "n";



            Technically, this doesn't meet the requirements as-is (e.g., it doesn't print out a prompt to tell the user to enter data), but I think it gives at least some idea of a direction things could go.






            share|improve this answer









            $endgroup$



            Names



            All-caps names are typically reserved for macros. They don't seem to me to make much sense for const variables. In fact, they only make minimal sense for object-like macros--they were originally used for function-like macros as kind of a warning that you should be cautious about passing an argument with side-effects, because they might happen more than once.



            Minimize Magic



            I'd typically try to keep the magic numbers to a minimum. For example, instead of defining FREQUENCYSIZE by itself, I'd probably do something like this:



            const int lower_bound = 80;
            count int upper_bound = 85;
            const int frequency_size = upper_bound - lower_bound + 1;


            Separation of Concerns



            I'd at least consider separating validating data from reading the data. I'd prefer to have a function on the general order of:



            bool valid(int val) 
            return val >= lower_bound && val < upper_bound;



            Class Usage



            We have a number of different things related to reading and working with numbers in a specified range. It might be worth considering wrapping those bits and pieces into a coherent class for dealing with a value in a range, and let the outside world create and use objects of that class.



            template <class T, T lower_bound, T upper_bound>
            class bounded
            public:
            static bool valid(T val) return val >= lower_bound && val < upper_bound;

            friend std::istream &operator>>(std::istream &is, bounded &b)
            T val;
            is >> val;
            if (valid(val))
            b.val = val;
            else
            is.setstate(std::ios_base::failbit);
            return is;


            friend std::ostream &operator<<(std::ostream &os, bounded const &b)
            return os << b.val;


            size_t index() return size_t(val - lower_bound);

            static constexpr size_t range() return upper_bound - lower_bound + 1;

            private:
            T val;
            ;


            That let's us simplify the rest of the code a bit, something on this general order:



            int main() 
            using integer = bounded<int, 80, 85>;

            std::array<integer, 10> inputs;
            std::array<size_t, integer::range()> freqs ;

            for (integer &i : inputs)
            std::cin >> i;
            ++freqs[i.index()];


            for (auto freq : freqs)
            std::cout << freq << "n";



            Technically, this doesn't meet the requirements as-is (e.g., it doesn't print out a prompt to tell the user to enter data), but I think it gives at least some idea of a direction things could go.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 7 hours ago









            Jerry CoffinJerry Coffin

            29.8k4 gold badges62 silver badges132 bronze badges




            29.8k4 gold badges62 silver badges132 bronze badges


























                1












                $begingroup$

                If you go for modern C++ the static variables should be marked as constexpr instead of plain old const.



                As was said in the other question, it should be beneficial to create an array of length MAXLEGALVALUE - MINLEGALVALUE and directly index into that array. That way there is probably less memory consumed and we count automatically.



                Personally I would use std::size_t or a well specified integer type like std::uint32_t rather than unsigned, which depends on the implementation.



                In range based for loops where the type is unambiguous I am not really a fan of auto.



                for (auto inputs : inputValues)


                How do you know that copying it is cheap here? You have to check the type of the container. Also you should consider const correctness so rather use const int or const auto if you prefere that.



                for (const int inputs : inputValues)


                Note that you have a truncation warning here as MINLEGALVALUE is of type int:



                unsigned rowLabel = MINLEGALVALUE;





                share|improve this answer









                $endgroup$



















                  1












                  $begingroup$

                  If you go for modern C++ the static variables should be marked as constexpr instead of plain old const.



                  As was said in the other question, it should be beneficial to create an array of length MAXLEGALVALUE - MINLEGALVALUE and directly index into that array. That way there is probably less memory consumed and we count automatically.



                  Personally I would use std::size_t or a well specified integer type like std::uint32_t rather than unsigned, which depends on the implementation.



                  In range based for loops where the type is unambiguous I am not really a fan of auto.



                  for (auto inputs : inputValues)


                  How do you know that copying it is cheap here? You have to check the type of the container. Also you should consider const correctness so rather use const int or const auto if you prefere that.



                  for (const int inputs : inputValues)


                  Note that you have a truncation warning here as MINLEGALVALUE is of type int:



                  unsigned rowLabel = MINLEGALVALUE;





                  share|improve this answer









                  $endgroup$

















                    1












                    1








                    1





                    $begingroup$

                    If you go for modern C++ the static variables should be marked as constexpr instead of plain old const.



                    As was said in the other question, it should be beneficial to create an array of length MAXLEGALVALUE - MINLEGALVALUE and directly index into that array. That way there is probably less memory consumed and we count automatically.



                    Personally I would use std::size_t or a well specified integer type like std::uint32_t rather than unsigned, which depends on the implementation.



                    In range based for loops where the type is unambiguous I am not really a fan of auto.



                    for (auto inputs : inputValues)


                    How do you know that copying it is cheap here? You have to check the type of the container. Also you should consider const correctness so rather use const int or const auto if you prefere that.



                    for (const int inputs : inputValues)


                    Note that you have a truncation warning here as MINLEGALVALUE is of type int:



                    unsigned rowLabel = MINLEGALVALUE;





                    share|improve this answer









                    $endgroup$



                    If you go for modern C++ the static variables should be marked as constexpr instead of plain old const.



                    As was said in the other question, it should be beneficial to create an array of length MAXLEGALVALUE - MINLEGALVALUE and directly index into that array. That way there is probably less memory consumed and we count automatically.



                    Personally I would use std::size_t or a well specified integer type like std::uint32_t rather than unsigned, which depends on the implementation.



                    In range based for loops where the type is unambiguous I am not really a fan of auto.



                    for (auto inputs : inputValues)


                    How do you know that copying it is cheap here? You have to check the type of the container. Also you should consider const correctness so rather use const int or const auto if you prefere that.



                    for (const int inputs : inputValues)


                    Note that you have a truncation warning here as MINLEGALVALUE is of type int:



                    unsigned rowLabel = MINLEGALVALUE;






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered 7 hours ago









                    misccomiscco

                    3,6726 silver badges17 bronze badges




                    3,6726 silver badges17 bronze badges
























                        1












                        $begingroup$

                        One idea for simplification is to count frequencies directly instead of putting all the values in an array that you only use for counting frequencies. You can then remove the getFrequencyCounts function and the whole thing gets a little more efficient. This works well when you have a set of values in a dense range like [80,85]. If you have a lot of values far between eachother, using a set or unordered_set is probably a better choice. I found the code easy enough to read. Here are some ideas with comments in the code:



                        #include <array>
                        #include <iostream>

                        constexpr size_t INPUTSIZE = 10;
                        constexpr int MINLEGALVALUE = 80;
                        constexpr int MAXLEGALVALUE = 85;
                        constexpr size_t FREQUENCYSIZE = MAXLEGALVALUE - MINLEGALVALUE + 1;

                        std::array<unsigned, FREQUENCYSIZE> getUserInputFreq()
                        std::array<unsigned, FREQUENCYSIZE> inputValues0; // initialize with 0

                        size_t i = 0;
                        do
                        int inputValue = 0;
                        std::cout << "Please enter a number between " << MINLEGALVALUE << " and "
                        << MAXLEGALVALUE << ":";

                        // make sure the istream you read from succeeded in extracting
                        if(std::cin >> inputValue)
                        if(inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)
                        // count frequencies directly if you don't actually need the
                        // input values
                        ++inputValues[static_cast<size_t>(inputValue - MINLEGALVALUE)];
                        ++i; // prefer prefix operator++
                        else
                        std::cout << "The number must be between" << MINLEGALVALUE << " and "
                        << MAXLEGALVALUE << "n";

                        else
                        break; // erroneous input or EOF

                        while(i < INPUTSIZE);

                        return inputValues;


                        void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)
                        int rowLabel = MINLEGALVALUE;
                        for(auto frequency : freqs)
                        std::cout << rowLabel << " " << frequency << "n";
                        ++rowLabel; // prefer prefix operator++



                        int main()
                        std::array<unsigned, FREQUENCYSIZE> freqs = getUserInputFreq();

                        std::cout << "n";

                        printFrequencies(freqs);






                        share|improve this answer









                        $endgroup$



















                          1












                          $begingroup$

                          One idea for simplification is to count frequencies directly instead of putting all the values in an array that you only use for counting frequencies. You can then remove the getFrequencyCounts function and the whole thing gets a little more efficient. This works well when you have a set of values in a dense range like [80,85]. If you have a lot of values far between eachother, using a set or unordered_set is probably a better choice. I found the code easy enough to read. Here are some ideas with comments in the code:



                          #include <array>
                          #include <iostream>

                          constexpr size_t INPUTSIZE = 10;
                          constexpr int MINLEGALVALUE = 80;
                          constexpr int MAXLEGALVALUE = 85;
                          constexpr size_t FREQUENCYSIZE = MAXLEGALVALUE - MINLEGALVALUE + 1;

                          std::array<unsigned, FREQUENCYSIZE> getUserInputFreq()
                          std::array<unsigned, FREQUENCYSIZE> inputValues0; // initialize with 0

                          size_t i = 0;
                          do
                          int inputValue = 0;
                          std::cout << "Please enter a number between " << MINLEGALVALUE << " and "
                          << MAXLEGALVALUE << ":";

                          // make sure the istream you read from succeeded in extracting
                          if(std::cin >> inputValue)
                          if(inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)
                          // count frequencies directly if you don't actually need the
                          // input values
                          ++inputValues[static_cast<size_t>(inputValue - MINLEGALVALUE)];
                          ++i; // prefer prefix operator++
                          else
                          std::cout << "The number must be between" << MINLEGALVALUE << " and "
                          << MAXLEGALVALUE << "n";

                          else
                          break; // erroneous input or EOF

                          while(i < INPUTSIZE);

                          return inputValues;


                          void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)
                          int rowLabel = MINLEGALVALUE;
                          for(auto frequency : freqs)
                          std::cout << rowLabel << " " << frequency << "n";
                          ++rowLabel; // prefer prefix operator++



                          int main()
                          std::array<unsigned, FREQUENCYSIZE> freqs = getUserInputFreq();

                          std::cout << "n";

                          printFrequencies(freqs);






                          share|improve this answer









                          $endgroup$

















                            1












                            1








                            1





                            $begingroup$

                            One idea for simplification is to count frequencies directly instead of putting all the values in an array that you only use for counting frequencies. You can then remove the getFrequencyCounts function and the whole thing gets a little more efficient. This works well when you have a set of values in a dense range like [80,85]. If you have a lot of values far between eachother, using a set or unordered_set is probably a better choice. I found the code easy enough to read. Here are some ideas with comments in the code:



                            #include <array>
                            #include <iostream>

                            constexpr size_t INPUTSIZE = 10;
                            constexpr int MINLEGALVALUE = 80;
                            constexpr int MAXLEGALVALUE = 85;
                            constexpr size_t FREQUENCYSIZE = MAXLEGALVALUE - MINLEGALVALUE + 1;

                            std::array<unsigned, FREQUENCYSIZE> getUserInputFreq()
                            std::array<unsigned, FREQUENCYSIZE> inputValues0; // initialize with 0

                            size_t i = 0;
                            do
                            int inputValue = 0;
                            std::cout << "Please enter a number between " << MINLEGALVALUE << " and "
                            << MAXLEGALVALUE << ":";

                            // make sure the istream you read from succeeded in extracting
                            if(std::cin >> inputValue)
                            if(inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)
                            // count frequencies directly if you don't actually need the
                            // input values
                            ++inputValues[static_cast<size_t>(inputValue - MINLEGALVALUE)];
                            ++i; // prefer prefix operator++
                            else
                            std::cout << "The number must be between" << MINLEGALVALUE << " and "
                            << MAXLEGALVALUE << "n";

                            else
                            break; // erroneous input or EOF

                            while(i < INPUTSIZE);

                            return inputValues;


                            void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)
                            int rowLabel = MINLEGALVALUE;
                            for(auto frequency : freqs)
                            std::cout << rowLabel << " " << frequency << "n";
                            ++rowLabel; // prefer prefix operator++



                            int main()
                            std::array<unsigned, FREQUENCYSIZE> freqs = getUserInputFreq();

                            std::cout << "n";

                            printFrequencies(freqs);






                            share|improve this answer









                            $endgroup$



                            One idea for simplification is to count frequencies directly instead of putting all the values in an array that you only use for counting frequencies. You can then remove the getFrequencyCounts function and the whole thing gets a little more efficient. This works well when you have a set of values in a dense range like [80,85]. If you have a lot of values far between eachother, using a set or unordered_set is probably a better choice. I found the code easy enough to read. Here are some ideas with comments in the code:



                            #include <array>
                            #include <iostream>

                            constexpr size_t INPUTSIZE = 10;
                            constexpr int MINLEGALVALUE = 80;
                            constexpr int MAXLEGALVALUE = 85;
                            constexpr size_t FREQUENCYSIZE = MAXLEGALVALUE - MINLEGALVALUE + 1;

                            std::array<unsigned, FREQUENCYSIZE> getUserInputFreq()
                            std::array<unsigned, FREQUENCYSIZE> inputValues0; // initialize with 0

                            size_t i = 0;
                            do
                            int inputValue = 0;
                            std::cout << "Please enter a number between " << MINLEGALVALUE << " and "
                            << MAXLEGALVALUE << ":";

                            // make sure the istream you read from succeeded in extracting
                            if(std::cin >> inputValue)
                            if(inputValue >= MINLEGALVALUE && inputValue <= MAXLEGALVALUE)
                            // count frequencies directly if you don't actually need the
                            // input values
                            ++inputValues[static_cast<size_t>(inputValue - MINLEGALVALUE)];
                            ++i; // prefer prefix operator++
                            else
                            std::cout << "The number must be between" << MINLEGALVALUE << " and "
                            << MAXLEGALVALUE << "n";

                            else
                            break; // erroneous input or EOF

                            while(i < INPUTSIZE);

                            return inputValues;


                            void printFrequencies(std::array<unsigned, FREQUENCYSIZE> freqs)
                            int rowLabel = MINLEGALVALUE;
                            for(auto frequency : freqs)
                            std::cout << rowLabel << " " << frequency << "n";
                            ++rowLabel; // prefer prefix operator++



                            int main()
                            std::array<unsigned, FREQUENCYSIZE> freqs = getUserInputFreq();

                            std::cout << "n";

                            printFrequencies(freqs);







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered 7 hours ago









                            Ted LyngmoTed Lyngmo

                            1434 bronze badges




                            1434 bronze badges






























                                draft saved

                                draft discarded
















































                                Thanks for contributing an answer to Code Review Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                Use MathJax to format equations. MathJax reference.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226448%2fcount-the-frequency-of-integers-in-an-array%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                                Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                                199年 目錄 大件事 到箇年出世嗰人 到箇年死嗰人 節慶、風俗習慣 導覽選單