Задание 11 урок 18

Задание 11 Урок 18

Задана последовательность символов, имеющая следующий вид: p1q1p2q2p3...qn–1pn
, где pi
— число, а qi
— знак арифметического действия из набора {+, –, *}. Вычислите значение выражения, предполагая, что действия выполняются согласно правилам арифметики.
Входные данные: На вход программе подается строка указанного вида, состоящая не более чем из 9 чисел, разделенных символами арифметических операций.
Выходные данные: Выведите значение арифметического выражения.
Примеры:

Входные данные   Результат 
 
5+2               7
1-2*5+2          -7
5*6+7-3*2+11      42
5*6+7-3*2*3+11    30
var
  S :string;

function calc(s: string): integer;
var
  temp1, temp2, temp3, znak: string;
  flag1, flag2, flagZnak1: boolean;
  intChislo, intChislo1, intChislo2, intChislo3, Code, sum, sumTemp, i: integer;
begin
  sum := 0;
  sumTemp := 0;
  temp1 := '';
  temp2 := '';
  temp3 := '';
  flag1 := true;
  flag2 := true;
  flagZnak1 := false;
  znak := '';
  i := 1;

  while (i < (length(s)+1)) do   // итерируем по выражению
  begin
    if (i > 1) and (flagZnak1) then
    begin
      znak := s[i-1];
      flagZnak1 := false;
    end;

    if (flag1) then
    begin
      temp1 := temp1 + s[i];
      Val(s[i+1], intChislo, Code);
      if (Code = 0) then  // если число то добавляем в temp1 и переходим к следующему
      begin
        i := i + 1;
        continue;
      end
      else
      begin
        if (s[i+1] <> '*') then
        begin
          Val(znak + temp1, intChislo1, Code);
          sum := sum + intChislo1;
        end
        else
        begin
          flag1 := false;
          i := i + 2;
          continue;
        end
      end
    end
    else
    begin

      if (flag2) then
      begin
        temp2 := temp2 + s[i];
        Val(s[i+1], intChislo, Code);
        if (Code = 0) then  // если число то добавляем в temp2 и переходим к следующему
        begin
          i := i + 1;
          continue;
        end
        else
        begin
          if (s[i+1] <> '*') then
          begin
            Val(znak + temp1, intChislo1, Code);
            Val(temp2, intChislo2, Code);
            sum := sum + intChislo1 * intChislo2;
          end
          else
          begin
            Val(znak + temp1, intChislo1, Code);
            Val(temp2, intChislo2, Code);
            sumTemp := intChislo2;
            flag2 := false;
            i := i + 2;
            continue;
          end
        end
      end
      else
      begin
        temp3 := temp3 + s[i];
        Val(s[i+1], intChislo, Code);
        if (Code = 0) then  // если число то добавляем в temp3 и переходим к следующему
        begin
          i := i + 1;
          continue;
        end
        else
        begin
          if (s[i+1] = '*') then
          begin
            Val(temp3, intChislo3, Code);
            sumTemp := sumTemp * intChislo3;
            temp3 := '';
            i := i + 2;
            continue;
          end
          else
          begin
            Val(temp3, intChislo3, Code);
            Val(znak+temp1, intChislo1, Code);
            sumTemp := sumTemp * intChislo3;
            sum := sum + sumTemp * intChislo1;
          end

        end
      end
    end;

    temp1 := '';
    temp2 := '';
    temp3 := '';
    flag1 := true;
    flag2 := true;
    flagZnak1 := true;
    znak := '';
    i := i + 2;
  end;

  result := sum;
end;



begin
    writeln('vvedite virajenie');
    readln(S);
    writeln(S, ' = ', calc(S));
    readln();
end.  



консоль:

vvedite vyrajenie
5*6+7-3*2*3+11
5*6+7-3*2*3+11 = 30

vvedite vyrajenie
10*10*10-10*10
10*10*10-10*10 = 900
vedro-compota's picture

  sum := 0;
  sumTemp := 0;
  temp1 := '';
  temp2 := '';
  temp3 := '';
  flag1 := true;
  flag2 := true;
  flagZnak1 := false;

-- просьба прокомментировать назначение переменных, имена у них не сильно информативные

_____________
матфак вгу и остальная классика =)

var
  S :string;

function calc(s: string): integer;
var
  temp1, temp2, temp3, znak: string;
  flag1, flag2, flagZnak1: boolean;
  intChislo, intChislo1, intChislo2, intChislo3, Code, sum, sumTemp, i: integer;
begin
  sum := 0;           // общая сумма
  sumTemp := 0;       // временная сумма (для слагаемых типа ...a*b*c*...)

  // если только слагаемые то используем temp1, если слагаемые состоят максимум из 2х множителей то
  // temp1 и temp2, если слагаемое состоит из нескольких множителей(...a*b*c*...) то temp1, temp2, temp3

  temp1 := '';        // временное число 1
  temp2 := '';        // временное число 2
  temp3 := '';        // временное число 3
  flag1 := true;      // флаг для перехода
  flag2 := true;      // флаг для перехода
  flagZnak1 := false; // флаг + или -
  znak := '';         // знак перед числом
  i := 1;             //

  while (i < (length(s)+1)) do   // итерируем по выражению
  begin
    if (i > 1) and (flagZnak1) then
    begin
      znak := s[i-1];
      flagZnak1 := false;
    end;

    if (flag1) then
    begin
      temp1 := temp1 + s[i];         //заполняем 1 временное число
      Val(s[i+1], intChislo, Code);  // смотрим на следующий символ
      if (Code = 0) then  // если это цифра то добавляем в temp1 и переходим к следующему символу
      begin
        i := i + 1;
        continue;
      end
      else
      begin
        if (s[i+1] <> '*') then  // если это + или - (множитель ..a*b*c*... закончился)
        begin
          Val(znak + temp1, intChislo1, Code);
          sum := sum + intChislo1; // увеличиваем общую сумму на накопленное число temp1 учитывая знак перед ним
        end
        else                    // если это умножение то идем дальше
        begin
          flag1 := false;       // переходим ко второму временному множителю  \/
          i := i + 2;                                                //       \/
          continue;                                                  //       \/
        end                                                          //       \/
      end                                                            //       \/
    end                                                              //       \/
    else                                                             //       \/
    begin                       // переходим ко второму временному множителю
      if (flag2) then
      begin
        temp2 := temp2 + s[i];      //заполняем 2 временное число
        Val(s[i+1], intChislo, Code);
        if (Code = 0) then  // если число то добавляем в temp2 и переходим к следующему символу
        begin
          i := i + 1;
          continue;
        end
        else
        begin
          if (s[i+1] <> '*') then             // если это + или - (множитель ..a*b*c*... закончился)
          begin
            Val(znak + temp1, intChislo1, Code);
            Val(temp2, intChislo2, Code);
            sum := sum + intChislo1 * intChislo2;  // увеличиваем общую сумму на произведение 2х предыдущих множителей
          end
          else              // если это * (множитель ..a*b*c*... НЕ закончился)
          begin
            Val(znak + temp1, intChislo1, Code);
            Val(temp2, intChislo2, Code);
            sumTemp := intChislo2;        // делаем временную сумму предыдущих множителей
            flag2 := false;               // переходим ко третьему временному множителю     \/
            i := i + 2;                                                            //       \/
            continue;                                                              //       \/
          end                                                                      //       \/
        end                                                                        //       \/
      end                                                                          //       \/
      else                               // переходим ко третьему временному множителю
      begin
        temp3 := temp3 + s[i];           //заполняем 3 временное число
        Val(s[i+1], intChislo, Code);
        if (Code = 0) then  // если число то добавляем в temp3 и переходим к следующему символу
        begin
          i := i + 1;
          continue;
        end
        else
        begin
          if (s[i+1] = '*') then   // если это * (множитель ..a*b*c*... НЕ закончился)
          begin
            Val(temp3, intChislo3, Code);
            sumTemp := sumTemp * intChislo3;    // увеличиваем временную накопительную переменную (произведение)
            temp3 := '';
            i := i + 2;
            continue;
          end
          else                             // если это + или - (множитель ..a*b*c*... закончился)
          begin
            Val(temp3, intChislo3, Code);
            Val(znak+temp1, intChislo1, Code);
            sumTemp := sumTemp * intChislo3;    // увеличиваем временную накопительную переменную (произведение)
            sum := sum + sumTemp * intChislo1;  // увеличиваем общую сумму на произведение текущего числа и временной накопительной переменной
          end

        end
      end
    end;

    temp1 := '';       // сброс  (например, множитель ..a*b*c*... закончился)
    temp2 := '';
    temp3 := '';
    flag1 := true;
    flag2 := true;
    flagZnak1 := true;
    znak := '';
    i := i + 2;
  end;

  result := sum;
end;



begin
    S := '5*6+7-3*2*3+11';
    //writeln('vvedite virajenie');
    //readln(S);
    writeln(S, ' = ', calc(S));
    readln();
end. 



vedro-compota's picture

Замечание по комментариям: https://youtu.be/--sfOsVdfH4 (можно поправить в последнем комменте с кодом, без копирования)

_____________
матфак вгу и остальная классика =)

var
  S :string;

function calc(s: string): integer;
var
  temp1, temp2, temp3, znak: string;
  flagNextMultTwoMember, flagNextMultMultipleMember: boolean;
  intChislo, intChislo1, intChislo2, intChislo3, Code, sum, multTemp, i: integer;
begin
  sum := 0;           // общая сумма
  multTemp := 0;       // временное произведение (для слагаемых типа ...a*b*c*...)

  // если только слагаемые то используем temp1 (каждое слагаемое помещаем в temp1 и увеличиваем общую сумму  sum += temp1)
  // если слагаемые состоят максимум из 2х множителей то temp1 и temp2
  // если слагаемое состоит из более чем 2х множителей (...a*b*c*d...) то используем 3 temp переменных:
  // предыдущие множители (a*b*c*...) на каждой итерации становятся multTemp, и умножаются на temp3
  // 1) multTemp = temp1 * temp2
  // 2) multTemp *= temp3
  // 3) goto 2)

  temp1 := '';        //
  temp2 := '';        //
  temp3 := '';        //
  flagNextMultTwoMember := true;           // флаг для перехода в случае 2х множителей в слагаемом
  flagNextMultMultipleMember := true;      // флаг для перехода в случае более 2х множителей в слагаемом
  znak := '';         // знак перед слагаемым
  i := 1;             //

  while (i < (length(s)+1)) do   // итерируем по выражению
  begin
    if (i > 1) then  // проверяем знак перед слагаемым
    begin
      if (s[i-1]='-')or(s[i-1]='+') then // и есть ли он вообще
      begin
        znak := s[i-1];
      end;
    end;

    if (flagNextMultTwoMember) then
    begin
      temp1 := temp1 + s[i];         //заполняем 1 временное число
      Val(s[i+1], intChislo, Code);  // смотрим на следующий символ
      if (Code = 0) then  // если это цифра то добавляем в temp1 и переходим к следующему символу
      begin
        i := i + 1;
        continue;
      end
      else
      begin
        if (s[i+1] <> '*') then  // если это + или - (множитель ..a*b*c*... закончился)
        begin
          Val(znak + temp1, intChislo1, Code);
          sum := sum + intChislo1; // увеличиваем общую сумму на накопленное число temp1 учитывая знак перед ним
        end
        else                    // если это умножение то идем дальше
        begin
          flagNextMultTwoMember := false;       // переходим ко второму временному множителю  \/
          i := i + 2;                                                //       \/
          continue;                                                  //       \/
        end                                                          //       \/
      end                                                            //       \/
    end                                                              //       \/
    else                                                             //       \/
    begin                       // переходим ко второму временному множителю
      if (flagNextMultMultipleMember) then
      begin
        temp2 := temp2 + s[i];      //заполняем 2 временное число
        Val(s[i+1], intChislo, Code);
        if (Code = 0) then  // если число то добавляем в temp2 и переходим к следующему символу
        begin
          i := i + 1;
          continue;
        end
        else
        begin
          if (s[i+1] <> '*') then             // если это + или - (множитель a*b закончился)
          begin
            Val(znak + temp1, intChislo1, Code);
            Val(temp2, intChislo2, Code);
            sum := sum + intChislo1 * intChislo2;  // увеличиваем общую сумму на произведение 2х предыдущих множителей
          end
          else              // если это * (множитель ..a*b... НЕ закончился и состоит из более 2-х множителей)
          begin
            Val(znak + temp1, intChislo1, Code);
            Val(temp2, intChislo2, Code);
            multTemp := intChislo1*intChislo2;        // делаем временное произведение предыдущих множителей
            flagNextMultMultipleMember := false;               // переходим ко третьему временному множителю     \/
            i := i + 2;                                                            //       \/
            continue;                                                              //       \/
          end                                                                      //       \/
        end                                                                        //       \/
      end                                                                          //       \/
      else                               // переходим ко третьему временному множителю
      begin
        temp3 := temp3 + s[i];           //заполняем 3 временное число
        Val(s[i+1], intChislo, Code);
        if (Code = 0) then  // если число то добавляем в temp3 и переходим к следующему символу
        begin
          i := i + 1;
          continue;
        end
        else
        begin
          if (s[i+1] = '*') then   // если это * (множитель ..a*b*c*... НЕ закончился)
          begin
            Val(temp3, intChislo3, Code);
            multTemp := multTemp * intChislo3;    // увеличиваем временную накопительную переменную (произведение)
            temp3 := '';
            i := i + 2;
            continue;
          end
          else                             // если это + или - (множитель ..a*b*c*... закончился)
          begin
            Val(temp3, intChislo3, Code);
            Val(znak+temp1, intChislo1, Code);
            multTemp := multTemp * intChislo3;    // увеличиваем временную накопительную переменную (произведение)
            sum := sum + multTemp;  // увеличиваем общую сумму на произведение текущего числа и временной накопительной переменной
          end

        end
      end
    end;

    temp1 := '';       // сброс  (например, множитель ..a*b*c*d... закончился)
    temp2 := '';
    temp3 := '';
    flagNextMultTwoMember := true;
    flagNextMultMultipleMember := true;
    znak := '';
    i := i + 2;
  end;
  result := sum;
end;



begin
    S := '5*6+7-3*2*3+11';
    //writeln('vvedite virajenie');
    //readln(S);
    writeln(S, ' = ', calc(S));
    //readln();
end.