Нужна программная логика для конвертера

Это для моего Android-приложения конвертер. У меня есть три счетчика: единица, от и до. Например. Угол, градус и радиан.

Я добавил слушателя для блочного спиннера. При выборе единицы будут заполнены счетчики от и до. Пользователь будет вводить данные в поле от EditText, и после нажатия кнопки "Рассчитать" TextView будет содержать ответ.

Я реализовал это с помощью if else,

if unit_spinner is Angle
    if from_spinner is Degree
        if to_spinner is Radian
            return input*0.0174532925 //1 degree = 0.0174532925 rad
        else if to_spinner is Gradian
            return input*1.111111111111111 //1 degree = 1.111111111111111 grad

        ...and so on, the cartesian product of all units

Это стало очень долго для нескольких единиц. Так можете ли вы предложить другую логику?

3 ответа

Решение

В зависимости от ваших переменных, вы можете использовать switch заявление.

switch(someintegervariable){
  case SOME_INT_CONSTANT_1:
    /* ... */
    break;
  case SOME_INT_CONSTANT_2:
    /* ... */
    break;
  default:
    /* ... */
}

То, как у вас есть сейчас, у вас есть два пишут NxN if заявления для каждой категории, которая имеет N единиц.

if from_spinner is Degree
    if to_spinner is Degree
        return input
    if to_spinner is Radian
        return input * 0.0174532925199
    if to_spinner is Gradian
        return input * 1.11111111111
if from_spinner is Radian
    if to_spinner is Degree
        return input * 57.2957795131
    if to_spinner is Radian
        return input
    if to_spinner is Gradian
        return input * 63.6619772368
if from_spinner is Gradian
    if to_spinner is Degree
        return input * 0.9
    if to_spinner is Radian
        return input * 0.0157079632679
    if to_spinner is Gradian
        return input

Вместо этого выберите единицу, которая будет выступать в качестве посредника между входом и выходом. Тогда вам нужно N if операторы для преобразования от ввода до посредника, и N if операторы для преобразования из посредника в вывод, в общей сложности 2N.

//we will use degrees as the intermediary unit
intermediary = null
//caluclate intermediary
if from_spinner is Degree
    intermediary = input
if from_spinner is Radian
    intermediary = input * 57.2957795131
if from_spinner is Gradian
    intermediary = input * 0.9

//calculate final
if to_spinner is Degree
    return intermediary
if to_spinner is Radian
    return intermediary / 57.2957795131
if to_spinner is Gradian
    return intermediary / 0.9

Не кажется, что это намного эффективнее, когда у вас есть только три единицы, но для больших значений N это экономит вам много усилий. Например, сравните этот метод с двумя вложенными строками из 105 строк и его эквивалент из 29 строк, который использует промежуточные значения:

if from_spinner is Millimeter
    if to_spinner is Millimeter
        return input
    if to_spinner is Centimeter
        return input * 0.1
    if to_spinner is Meter
        return input * 0.001
    if to_spinner is Kilometer
        return input * 1e-06
    if to_spinner is Inch
        return input * 0.0393700787402
    if to_spinner is Foot
        return input * 0.00328083989501
    if to_spinner is Mile
        return input * 6.2137273665e-07
if from_spinner is Centimeter
    if to_spinner is Millimeter
        return input * 10.0
    if to_spinner is Centimeter
        return input
    if to_spinner is Meter
        return input * 0.01
    if to_spinner is Kilometer
        return input * 1e-05
    if to_spinner is Inch
        return input * 0.393700787402
    if to_spinner is Foot
        return input * 0.0328083989501
    if to_spinner is Mile
        return input * 6.2137273665e-06
if from_spinner is Meter
    if to_spinner is Millimeter
        return input * 1000.0
    if to_spinner is Centimeter
        return input * 100.0
    if to_spinner is Meter
        return input
    if to_spinner is Kilometer
        return input * 0.001
    if to_spinner is Inch
        return input * 39.3700787402
    if to_spinner is Foot
        return input * 3.28083989501
    if to_spinner is Mile
        return input * 0.00062137273665
if from_spinner is Kilometer
    if to_spinner is Millimeter
        return input * 1000000.0
    if to_spinner is Centimeter
        return input * 100000.0
    if to_spinner is Meter
        return input * 1000.0
    if to_spinner is Kilometer
        return input
    if to_spinner is Inch
        return input * 39370.0787402
    if to_spinner is Foot
        return input * 3280.83989501
    if to_spinner is Mile
        return input * 0.62137273665
if from_spinner is Inch
    if to_spinner is Millimeter
        return input * 25.4
    if to_spinner is Centimeter
        return input * 2.54
    if to_spinner is Meter
        return input * 0.0254
    if to_spinner is Kilometer
        return input * 2.54e-05
    if to_spinner is Inch
        return input
    if to_spinner is Foot
        return input * 0.0833333333333
    if to_spinner is Mile
        return input * 1.57828675109e-05
if from_spinner is Foot
    if to_spinner is Millimeter
        return input * 304.8
    if to_spinner is Centimeter
        return input * 30.48
    if to_spinner is Meter
        return input * 0.3048
    if to_spinner is Kilometer
        return input * 0.0003048
    if to_spinner is Inch
        return input * 12.0
    if to_spinner is Foot
        return input
    if to_spinner is Mile
        return input * 0.000189394410131
if from_spinner is Mile
    if to_spinner is Millimeter
        return input * 1609340.0
    if to_spinner is Centimeter
        return input * 160934.0
    if to_spinner is Meter
        return input * 1609.34
    if to_spinner is Kilometer
        return input * 1.60934
    if to_spinner is Inch
        return input * 63359.8425197
    if to_spinner is Foot
        return input * 5279.98687664
    if to_spinner is Mile
        return input

,

intermediary = null
if from_spinner is Millimeter
    intermediary = input * 0.001
if from_spinner is Centimeter
    intermediary = input * 0.01
if from_spinner is Meter
    intermediary = input * 1.0
if from_spinner is Kilometer
    intermediary = input * 1000.0
if from_spinner is Inch
    intermediary = input * 0.0254
if from_spinner is Foot
    intermediary = input * 0.3048
if from_spinner is Mile
    intermediary = input * 1609.34
if to_spinner is Millimeter
    return intermediary / 0.001
if to_spinner is Centimeter
    return intermediary / 0.01
if to_spinner is Meter
    return intermediary / 1.0
if to_spinner is Kilometer
    return intermediary / 1000.0
if to_spinner is Inch
    return intermediary / 0.0254
if to_spinner is Foot
    return intermediary / 0.3048
if to_spinner is Mile
    return intermediary / 1609.34

Я бы порекомендовал использовать switch/case заявление. При этом вы можете получить регистр для каждого типа единиц, а затем для расчетов.

Вы также можете написать методы для каждого расчета. Это может немного сократить его, но, вероятно, не намного.

Я бы просто пошел с case заявление. Это относительно просто, но я могу собрать для вас код, если вам нужна помощь. Просто дай мне знать.

Вот код, который я мог бы использовать:

static double DoCalc()
{
    int uid;
    if unit_roller is Angle
        uid = 1;
    else if unit_roller is Length
        uid = 2;
    //etc...

    switch(uid)
        case 1:
            return AngleCalc(input);
        case 2:
            return LengthCalc(input);
        //etc...
        default;
}

static double AngleCalc(double input)
{
    if (from_spinner == to_spinner)
        return input;
    else if (from_spinner is Degree && to_spinner is radian)
        return input*0.0174532925
    //etc...    
}

Я скажу, что на самом деле это было не намного короче, как только я увидел, что это воедино, но это позволяет избежать использования вложенных if заявления, и, возможно, может сократить ваш код, когда у вас есть большое количество вариантов.

Другие вопросы по тегам