Задача 12 урок 18

Задача 12 урок 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 arithmetic (num1,num2: integer; x: string): integer ;
var num: integer;
begin
  if x = '*' then
    num:= num1 * num2
  else if x = '-' then
    num:= num1 - num2
  else
    num:= num1 + num2;
  result:= num;
end;

function calculation(s: string): integer;
var i,// см ниже
Code,//код ошибки при преобразовании строки в число
l,//длина строки. была нужна для нахождения последнего символ в строке,
//но чтоб убрать каждый раз проверку добавил "num"
num,//результат выраж.(когда строка кончается остается оператор и 2 числа) 
num1, num2, num3: integer;//3 перем. на случай если 2ой оператор * а 1й +/-
oper1, oper2,// операторы (знаки *,+,- между числами)
numstr1, numstr2, numstr3: string;// строковые значения чисел
begin
  i:= 1;//счетчик цикла и индекс символа в строке
  num1:= 0;//в начале чтения 1е число далее промежуточный результат
  num2:= 0;//2е число либо результат умножения 2го на 3е
  num3:= 0;//если 2ой оператор * а 1й +/-
  l:= length(s);
  while (i <= l) do
  begin
    if (s[i]>= '0') and (s[i] <= '9') then
    begin
      while (s[i]>= '0') and (s[i] <= '9') do
      begin
        if (num1 = 0) then
        begin
          numstr1:= s[i];
          inc(i);
        end
        else if (num2 = 0) then
        begin
          numstr2:= numstr2 + s[i];
          inc(i);
        end;
      end;
      if (numstr2 <> '') then
        val(numstr2,num2,Code)
      else
        val(numstr1,num1,Code) ;
    end

    else if (oper1 = '') then
    begin
      oper1:= s[i];
      inc(i);
      if (oper1 = '*') then
      begin
        while (s[i]>= '0') and (s[i] <= '9') do
        begin
          numstr2:= numstr2 + s[i];
          inc(i);
        end;
        val(numstr2,num2,Code);
        num1:= arithmetic(num1,num2,oper1);
        oper1:= '';
        num2:= 0;
        numstr2:= '';
      end;
    end

    else if (oper2 = '') then
    begin
      oper2:= s[i];
      inc(i);
      if (oper2 = '*') then
      begin
        while (s[i]>= '0') and (s[i] <= '9') do
        begin
          numstr3:= numstr3 + s[i];
          inc(i);
        end;
        val(numstr3,num3,Code);
        num2:= arithmetic(num3,num2,oper2);
        numstr3:= '';
        num3:= 0;
        oper2:= '';
      end
      else
      begin
        num1:= arithmetic(num1,num2,oper1);
        numstr2:= '';
        num2:= 0;
        oper1:= oper2;
        oper2:= '';
      end;
    end;

  end;
  num:= arithmetic(num1,num2,oper1);
  result:= num;
end;

begin
  s:= '5*6+7-3*2*3+11';
  write(s);
  write(' = ',calculation(s));
  readln();
end.
vedro-compota's picture

аналогично вот этому замечанию, просьба прокомментировать назначение переменных, в т.ч. этих:

num1:= 0;
num2:= 0;
num3:= 0;

-- смущает то, их три, а не напр. десять)

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

Дополнение к комментарию "l" : эту переменную можно убрать и просто писать
"length(s)" ).