Как мне очистить эти утверждения If? - PullRequest
1 голос
/ 27 мая 2020
if (calculation == "help") {
    cout << "add, subtract, multiplication, divide\nsquare root, sin, cos, power\n";
}
else if (calculation == "add") {
    cout << num1 << " + " << num2 << " = " << num1 + num2 << endl;
}
else if (calculation == "subtract") {
    cout << num1 << " - " << num2 << " = " << num1 - num2 << endl;
}
else if (calculation == "multiplication") {
    cout << num1 << " x " << num2 << " = " << num1 * num2 << endl;
}
else if (calculation == "divide") {
    cout << num1 << " / " << num2 << " = " << num1/ num2 << endl;
}
else if (calculation == "square root") {
    cout << "The square root of the first number is " << sqrt(num1) << ". The square root of the second number is " << sqrt(num2) << "." << endl;
}
else if (calculation == "sin") {
    cout << "The sine of the first number is " << sin(num1) << ". The sine of the second number is " << sin(num2) << "." << endl;
}
else if (calculation == "cos") {
    cout << "The cosine of the first number is " << cos(num1) << ". The cosine of the second number is " << cos(num2) << "." << endl;
}
else if (calculation == "power") {
    cout << num1 << " to the power of " << num2 << " = " << pow(num1, num2) << endl;
}

У меня есть идея исправить эти операторы if, например, создать карту или словарь. Я также не верю, что в C ++ можно использовать строки с операторами switch. Любая помощь очень ценится!

РЕДАКТИРОВАТЬ: Я смог использовать карту.

map<string, int> Choices = {
        { "help", 0 },
        { "add", 1 },
        { "subtract", 2 },
        { "multiply", 3 },
        { "divide", 4 },
        { "square root", 5 },
        { "sine", 6 },
        { "cosine", 7 },
        { "power", 8 }
        };

    it = Choices.find(choice);
    i = it->second;

Если есть более быстрый способ сделать это, сообщите мне. Спасибо за все ответы!

Ответы [ 4 ]

2 голосов
/ 27 мая 2020

Если вы сопоставите первые два символа и преобразуете их в число, можно создать переключатель. Это не будет красиво, но будет быстро.

РЕДАКТИРОВАТЬ: Я сделал пример того, как создать переключатель, используя «строки», если первая часть в строке уникальна. Вы можете сделать это с более чем двумя символами, если это необходимо, и у вас могут быть переключатели на случай частей, если есть дубликаты.

Делайте это, только если производительность очень важна, это приведет к sh другим решениям в скорость

#include <iostream>
#include <string>

int main()
{
    // first some code to show how to calculate constant from string if the first part in string is unique
    unsigned int uNumber = (unsigned int)'A';
    std::cout << uNumber << std::endl;
    uNumber <<= 8;
    std::cout << uNumber << std::endl;
    uNumber += (unsigned int)'A';
    std::cout << uNumber << std::endl;

    unsigned int uNumberAA = (unsigned int)*(uint16_t*)"AA";
    std::cout << uNumberAA << std::endl;
    uNumberAA = (unsigned int)*(uint16_t*)"AAAA";
    std::cout << uNumberAA << std::endl;


    // How to create a switch with strings

    static constexpr unsigned int he_help = ((unsigned int)'h' << 8) + (unsigned int)'e';           // "help"
    static constexpr unsigned int ad_add = ((unsigned int)'a' << 8) + (unsigned int)'d';            // "add"
    static constexpr unsigned int su_subtract = ((unsigned int)'s' << 8) + (unsigned int)'u';       // "subtract"
    static constexpr unsigned int mu_multiplication = ((unsigned int)'m' << 8) + (unsigned int)'u'; // "multiplication"

    std::string calculation = "subtract";

    uNumber = ((unsigned int)calculation[0] << 8) + (unsigned int)calculation[1];
    switch(uNumber)
    {
    case he_help :
        std::cout << "help" << std::endl;
        break;
    case ad_add :
        std::cout << "add" << std::endl;
        break;
    case su_subtract :
        std::cout << "subtract" << std::endl;
        break;
    case mu_multiplication :
        std::cout << "multiplication" << std::endl;
        break;
    }
}
1 голос
/ 27 мая 2020

Вы можете легко их очистить. Рассмотрим этот пример:

#include <stdio.h>

int main(void) {
    int a, b, result;
    char calculation;
    .
    .
    switch (calculation) { // must be a character or integral type
        case 'a': result = a + b; break; // add
        case 's': result = a - b; break; // subtract
        .
        .
        default:
            printf("No such operation.\n"); // when invalid operation
            return -1;
    }
    // valid operation? continue...

    printf("The result is: %d\n", result);

    return 0;
}
0 голосов
/ 27 мая 2020

Подробнее о программировании на C ++ и о языке программирования C ++ и Как отлаживать небольшие программы и более поздних версий C ++ 11 стандартный n3337 . Рассмотрим кодирование в стиле функционального программирования . Книга SICP - отличное введение в него.

Помните, что в C ++ есть замыкания , созданные с помощью лямбда-выражений . Он также имеет несколько ассоциативных контейнеров , в том числе std::map или std::unordered_map

Возможна установка ассоциативной карты закрытия:

static std::map<std::string,
                std::function<int(const std::vector<int>&)>> 
       mapclosures= {
  { "add", [](const std::vector<int>& v) { return v[0]+v[1]; }},
  { "mult", [](const std::vector<int>& v) { return v[0]*v[1]; }},
  //// etc...
}

и более поздние версии используйте mapclosures[str](v) или mapclosures[str](std::vector({3,5}))

Конечно, реальный код проверяет, что v имеет два аргумента для add, а если нет throw какое-то исключение . Для деления позаботьтесь о делении на ноль.

Что касается производительности, это могло быть приемлемо (но, конечно, медленнее, чем обычный switch). Если производительность имеет большое значение и вы готовы тратить время на кодирование, узнайте больше о методах синтаксического анализа (например, с помощью Dragon book или вашего рекурсивного парсера спуска построения некоторое абстрактное синтаксическое дерево ) для преобразования строки "add" в какое-то значение enum.

Подробнее о интерпретациях методах и изучении для вдохновения исходного кода существующих интерпретаторов с открытым исходным кодом , написанных на C ++ (возможно, Linux fi sh shell или другие на gitlab или github ).

0 голосов
/ 27 мая 2020

@ Per Gho sh, Правильно! Использование переключателя для таких случаев может помочь вам изменить код в более аккуратный. Однако свитч мало чем отличается от условий. Это выглядит более всеобъемлющим только тогда, когда у вас так много условий, основанных только на одной вещи, которая может измениться. Вот вам пример переключателя: представьте, что я ввожу int в диапазоне от 1 до 4, а затем хочу напечатать число, указанное пользователем. Вот как вы можете использовать переключатель в таком случае:

int n;
cin>>n;
switch(n){
   case 1:{cout<<"one";break;}
   case 2:{cout<<"two";break;}
   case 3:{cout<<"three";break;}
   case 4:{cout<<"four";break;}
}

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...