Range checks using a switch statement

后端 未结 7 1147
陌清茗
陌清茗 2020-12-23 02:15

My teacher has assigned a program to use both if-else statements and switch statements, so we understand how to implement both. The program asked u

相关标签:
7条回答
  • 2020-12-23 02:52

    We need to fit in the input, so, instead of this code:

    if (BMI < 18.5) {
            q = 1;
        }
        else if (BMI >= 18.5 && BMI < 25.0) {
            q = 2;
        }
        else if (BMI >= 25.0 && BMI < 30.0) {
            q = 3;
        }
        else if (BMI >= 30.0 && BMI < 35) {
            q = 4;
        }
        else {
            q = 5;
        }
    
        switch (q) {
        case 1: cout << "You are underweight" << endl; break;
        case 2: cout << "You are a normal weight " << endl; break;
        case 3: cout << "You are overweight" << endl; break;
        case 4: cout << "You are obese" << endl; break;
        case 5: cout << "You are gravely overweight" << endl; break;
    
        }
    

    You need something like

    switch (1 + (BMI >= 18.5) + (BMI >= 25) + (BMI >= 30) + (BMI >= 35)) {
        case 1: cout << "You are underweight" << endl; break;
        case 2: cout << "You are a normal weight " << endl; break;
        case 3: cout << "You are overweight" << endl; break;
        case 4: cout << "You are obese" << endl; break;
        case 5: cout << "You are gravely overweight" << endl; break;
    }
    

    The logic is to convert the if-elses into a mathematical formula, returning an int.

    0 讨论(0)
  • 2020-12-23 02:52

    A switch in C++ only allows you to check for the values of integers and chars.

    The BMI is a double type, so it's not possible to check its value in a switch.

    In your solution with the switch you also should declare the variable BMI as double. If you declare it as integer all decimal results will be casted to an integer, and you will lose the decimal places.

    0 讨论(0)
  • 2020-12-23 02:54

    Unless you have an absolutely ghastly compiler extension, you can't switch on a range in C++.

    But you could use a switch elegantly if you create a std::vector of the BMI ranges:

    std::vector<double> v = {18.5, 25.0 /*etc*/}

    Then use std::lower_bound along with std::distance to get the position of a given BMI in the above ranges. This is the quantity that you switch on.

    You could then go one stage further and define a std::vector<std::string> of the output messages. Then you need neither a switch nor an if block! All the selection logic is delegated to std::lower_bound.

    I deliberately haven't given you the full code: I trust these hints are sufficient.

    0 讨论(0)
  • 2020-12-23 02:56

    You could calculate your case labels dynamically from an array/vector instead of hardcoding an if/else expression:

    //#include "stdafx.h"
    #include <iostream>
    
    using namespace std;
    
    
    inline int seg(double d){ //calculate segment for a BMI of d
      constexpr double segs[] = { 18.5, 25, 30, 35 };
      constexpr int n = sizeof(segs)/sizeof(double);
      int r; for(r=0; r<n; r++)
        if(d<segs[r]) return r;
      return r;
    }
    
    int main()
    {
      double height, weight, heightMeters, weightKilo;
      int BMI, q;
      const double KILOGRAMS_PER_POUND = 0.45359237;
      const double METERS_PER_INCH = 0.0245;
    
      cout << "Please enter your height (inches) and weight (pounds)" << endl;
      cin >> height >> weight;
    
      weightKilo = weight*KILOGRAMS_PER_POUND;
      heightMeters = height*METERS_PER_INCH;
      BMI = weightKilo / (heightMeters*heightMeters);
    
    
    
      switch (seg(BMI)) {
        case 0: cout << "You are underweight" << endl; break;
        case 1: cout << "You are a normal weight " << endl; break;
        case 2: cout << "You are overweight" << endl; break;
        case 3: cout << "You are obese" << endl; break;
        case 4: cout << "You are gravely overweight" << endl; break;
      }
    
    }
    

    (You could even make the seg functions constexpr if your really wanted to).

    0 讨论(0)
  • 2020-12-23 03:07

    You can do something like:

    switch ((round)BMI)
    {
        case 1: case 2: case 3: .... case 15: case 16: case 17: cout<< "You are underweight " << endl; break;
        case 18: ... case 24: cout << "You are normal" << endl; break;
        case 25: ... case 29: cout << "You are overweight" << endl; break;
        case 30: ... case 34: cout << "You are obese" << endl; break;
        default: cout << "You are gravely overweight" << endl;
    }
    

    Also I couldn't help but notice this that since you are using if-else you can avoid the first condition in else-if statements like:

    if (BMI < 18.5)
    {
        cout << "You are underweight " << endl;
    }
    else if (BMI < 25.0)
    {
        cout << "You are normal" << endl;
    }
    else if (BMI < 30.0)
    {
        cout << "You are overweight" << endl;
    }
    else if(BMI < 35)
    {
        cout << "You are obese" << endl;
    }
    else
    {
        cout << "You are gravely overweight" << endl;
    }
    

    Apart from this, both of your implementations look good.

    0 讨论(0)
  • 2020-12-23 03:10

    You can not use a double inside a switch. The documentation says:

    switch ( expression )
       case constant-expression : statement
       [default   : statement]
    

    The expression must be of an integral type or of a class type for which there is an unambiguous conversion to integral type. Integral promotion is performed as described in Integral Promotions.

    On a side note:

    There are some compilers (like Clang 3.5.1) which are allowing the case x ... y as an extension to the C++ language. But that too is for an integral datatype. Something like

    switch(x){
           case 0:
                cout << "Test1";
                break;
           case 0 ... 9:
                cout << "Test2";
                break;
    
    0 讨论(0)
提交回复
热议问题