Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.06.19;
Скачать: CL | DM;

Вниз

Интересный алгоритм в обычном калькуляторе.   Найти похожие ветки 

 
Fergo ©   (2011-02-25 20:45) [0]

Товарищи помогите реализовать вот такой вот алгоритм: откройте обычный кальклятор Windows или любой электронный и далее жмем в нем "3" , "+" , "4", теперь когда нажимаем на "=" получаем ответ 7. Далее жмем еще раз сразу на "=" - прибавляется еще раз "4". Теперь жмем сразу на "+" и далее на "=". и видим что при дальнейших нажатиях на "="  прибавляется уже последний результат. Я перерыл всё что токо можно в интернете. все "калькуляторы" которые попадались такого алгоритма не имеют. Пытался реализовать сам, но получается очень много кода и слишком сложно все. может у вас чего нибудь получится. Есть вариант через дебаггер пропустить ВинКальк но эт на потом =)


 
Smile   (2011-02-25 20:51) [1]

Я не  модератор, но предлагаю подобные посты в ...


 
oldman ©   (2011-02-25 20:58) [2]


> Пытался реализовать сам, но получается очень много кода
> и слишком сложно все.


все очень просто при наличии мозгов


 
KilkennyCat ©   (2011-02-25 20:59) [3]

Легко:
Создаем три глобальных хрени:
var
 x, y, z : integer;

procedure TForm1.Create(..);
begin
 x := 3;
 y := 4;
 z := x + y;
end;

proceduer TForm1.ButtonRavnoClick(..);
begin
 inc(z, y);
 label1.caption := "rezultat: " + inttostrdef(z, "fig znaet");
end;


 
Pavia ©   (2011-02-25 21:01) [4]

Всё просто значение считывается из текстового поля.


 
Smile   (2011-02-25 21:02) [5]

Не пойму кому отдать предпочтение?
oldman © или
KilkennyCat ©
проблема однако
:)


 
И. Павел ©   (2011-02-25 21:04) [6]

Запоминайте предыдущую операцию и второй аргумент, и если кнопка "=" нажата, а первый аргумент еще не введен, то считайте, что требуется повтор операции.

А если первый аргумент введен, потом указана операция но не указан второй аргумент (но операция его требует) и сразу нажата "=", то просто считаете, что второй аргумент равен первому.


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

попытка хорошая. Но курсач все равно придется делать самостоятельно :)


 
Smile   (2011-02-25 21:07) [7]

> И. Павел ©   (25.02.11 21:04) [6]

Последняя фраза коронная
:)


 
Inovet ©   (2011-02-25 21:08) [8]

Конечно, в дебагер этот ВинКалк, и разобрать по винтикам.

В WinXP, кстати, у калькулятора 2 режима, в Win7 ещё бльше, и вот эти штуки работают по-разному в каждом.


 
Игорь Шевченко ©   (2011-02-25 21:16) [9]


> inttostrdef


это сильно


 
Fergo ©   (2011-02-25 21:21) [10]

KilkennyCat я наверное в вопросе забыл указать что мне не буквально эта операция нужна=). ты вот открой делфи кинь 4 кнопки( "3","4","+" и "=" ) и Edit или Panel или еще чего не важно и попробуй сделать так чтоб то что я выше описал работало. лично у меня не получается.


 
Fergo ©   (2011-02-25 21:25) [11]


> Запоминайте предыдущую операцию и второй аргумент, и если
> кнопка "=" нажата, а первый аргумент еще не введен, то считайте,
>  что требуется повтор операции.
>
> А если первый аргумент введен, потом указана операция но
> не указан второй аргумент (но операция его требует) и сразу
> нажата "=", то просто считаете, что второй аргумент равен
> первому.

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


 
Inovet ©   (2011-02-25 21:27) [12]

У такого калькулятора есть два регистра А и Б. Содержимое А отображается на дисплее, при вводе операции, содержимое копируется вместе с операцией в Б при нажатии на "=" А и Б обрабатывеются, согласно операции из Б.


 
Fergo ©   (2011-02-25 21:28) [13]

да кстати KilkennyCat ты учти еще что там еще есть и "/", "*", и "-" и они так же работают. но эт уже проще потом будет сделать.


 
Inovet ©   (2011-02-25 21:29) [14]

> [12] Inovet ©   (25.02.11 21:27)
> согласно операции из Б.

и результат помещается в А, в Б остаётся, что и было


 
Leon-Z ©   (2011-02-25 21:31) [15]

Удалено модератором
Примечание: п. 11 правил


 
KilkennyCat ©   (2011-02-25 21:33) [16]


> Игорь Шевченко ©   (25.02.11 21:16) [9]

э... а что нет такого? :) я думал, есть...


> Fergo ©   (25.02.11 21:28) [13]
>
> да кстати KilkennyCat ты учти еще что там еще есть и "/",
>  "*", и "-" и они так же работают. но эт уже проще потом
> будет сделать.


я обязательно учту, но я сейчас занят реализацией:

> открой делфи кинь 4 кнопки( "3","4","+" и "=" ) и Edit или
> Panel или еще чего не важно и попробуй сделать так чтоб
> то что я выше описал работало


 
Fergo ©   (2011-02-25 21:34) [17]


> У такого калькулятора есть два регистра А и Б. Содержимое
> А отображается на дисплее, при вводе операции, содержимое
> копируется вместе с операцией в Б при нажатии на "=" А и
> Б обрабатывеются, согласно операции из Б.


> и результат помещается в А, в Б остаётся, что и было

Да, но хотелось бы увидеть это все в виде: var
...
...

proceduer TForm1.Button"3"Click(..);
begin
...
end;

proceduer TForm1.Button"+"Click(..);
begin
...
end;
и т.д.


 
KilkennyCat ©   (2011-02-25 21:36) [18]


> Да, но хотелось бы увидеть это все в виде: var
> ...
> ...


var
 A, Б : extended;


 
Fergo ©   (2011-02-25 21:38) [19]

KilkennyCat не придирайся, я ж ничего не сказал про proceduer и  inttostrdef=)


 
KilkennyCat ©   (2011-02-25 21:42) [20]

я думаю, что полезно разбить действия на функции.

function plus(a : extended; б : extended; var z : extended) : boolean;
begin
 try
  z := a + б;
  result := (z > a) and (z > б); //проверяем, произошло ли сложение и сообщаем
 except
  result := false;//сложение однозначно навернулось.
 end;
end;


 
Leon-Z ©   (2011-02-25 21:45) [21]

Ну все таки Мелко-Мягкие всех обманули с калькулятором.
Я думаю что это просто ГЛЮК в программе, а не специально запрограммированная возможность данного приложения.


 
KilkennyCat ©   (2011-02-25 21:49) [22]


> KilkennyCat не придирайся

хорошо.
даю половину кода, может даже больше.

var
 a, b : extended;
 flag : boolean;
 oper : byte;
.....................

вычислитель
begin
 case oper of
   1 : a := a + b;
   2 : a := a - b;
   3 : a := a * b;
   4 : a := a / b;
 end;
end;

помня oper можно бесконечно вызывать вычислитель


 
Fergo ©   (2011-02-25 21:49) [23]

I>
> Ну все таки Мелко-Мягкие всех обманули с калькулятором.
> Я думаю что это просто ГЛЮК в программе, а не специально
> запрограммированная возможность данного приложения.

)))))) я тож так думал пока не попробовл на обычном электронном Citezen"е))


 
KilkennyCat ©   (2011-02-25 21:54) [24]


> Inovet ©   (25.02.11 21:08) [8]

калькулятор в вин 7 в режиме для программиста не позволяет вводить вещественные числа. это меня прикольнуло.


 
Fergo ©   (2011-02-25 21:58) [25]

Удалено модератором
Примечание: Offtopic


 
Германн ©   (2011-02-25 21:59) [26]


> KilkennyCat ©   (25.02.11 21:54) [24]
>
>
> > Inovet ©   (25.02.11 21:08) [8]
>
> калькулятор в вин 7 в режиме для программиста не позволяет
> вводить вещественные числа. это меня прикольнуло.

Знать уже поставили на учет.


 
Leon-Z ©   (2011-02-25 22:00) [27]


> Fergo ©   (25.02.11 21:49) [23]
> я тож так думал пока не попробовл на обычном электронном
> Citezen"е))

И Citezen глючный!!!
А вообще я думаю надо прочитать про "польскую запись" - специальный
алгоритм для вычисления выражений.
Может там ответ ???


 
KilkennyCat ©   (2011-02-25 22:10) [28]

предлагаю плюнуть на алгоритм и заняться интерфейсом.
кидаем на форму один едит, и 16 кнопок.
кнопкам с цифрами присваиваем тэг соответсвенно цифре.
кнопка равно тэг 10
умнож - 13
делен -  14
сложение - 11
вычитание - 12
сброс - 20
десятичная точка - 18

и все вешаем на один обработчик клика.

procedure TForm.btnClick(Sender: TObject);
begin
  case (sender as TComponent).tag of
     1..9 : edit1.text := edit1.text + inttostr( (sender as TComponent).tag);
      18 : if  pos("." edit1.text) < 1 then edit1.text := edit1.text + "."
     12..14 begin
                 oper := (sender as TComponent).tag - 10;
                 if a = 0 then a := strtofloat(edit1.text) else begin
                   b := strtofloat(edit1.text);
                   вычислитель(oper);
                   edit1.text := floattostr(a);
                 end;
              end;
       15 : if a = 0 then a := strtofloat(edit1.text) else begin
                   b := strtofloat(edit1.text);
                   вычислитель(oper);
                   edit1.text := floattostr(a);
                 end;
       20 : begin
               a := 0;
               b := 0;
               oper := 0;
             end;
   end;            
end;


вроде бы все.


 
Fergo ©   (2011-02-25 22:10) [29]

нашел ток "обратную польскую запись":

program calc;
{$APPTYPE console}

type
 Real = double;

const
 prs = "+-*/(";
 pri: array [1 .. 5] of byte = (1, 1, 2, 2, 0);

var
 s1, s2: String;
 q: array [0 .. 500] of Real;
 w: array [0 .. 500] of Char;
 n, len, len2: Cardinal;
 t: Real;
 ch: Char;

procedure Push(x: Real);
begin
 Inc(len);
 q[len] := x;
end;

function Pop: Real;
begin
 Pop := q[len];
 q[len] := 0;
 Dec(len);
end;

procedure PushC(x: Char);
begin
 Inc(len2);
 w[len2] := x;
end;

function Popc: Char;
begin
 Popc := w[len2];
 w[len2] := #0;
 Dec(len2);
end;

function Oper(s1, s2: Real; s3: Char): Real;
var
 x, y, z: Real;
begin
 x := s1;
 y := s2;
 case s3 of
   "+": z := x + y;
   "-": z := x - y;
   "*": z := x * y;
   "/": z := x / y;
 end;
 Oper := z;
end;

procedure PreChange(var s: String);
var
 i: Cardinal;
begin
 if s[1] = "-" then
   s := "0" + s;
 i := 1;
 while i <= n do
   if (s[i] = "(") and (s[i + 1] = "-") then
     insert("0", s, i + 1)
   else
     Inc(i);
end;

function Change(s: String): String;
var
 i: Cardinal;
 rezs: String;
 c: Boolean;
begin
 c := false;
 for i := 1 to n do
   begin
     if not(s[i] in ["+", "-", "*", "/", "(", ")"]) then
       begin
         if c then
           rezs := rezs + " ";
         rezs := rezs + s[i];
         c := false;
       end
     else
       begin
         c := true;
         if s[i] = "(" then
           PushC(s[i])
         else
           if s[i] = ")" then
             begin
               while w[len2] <> "(" do
                 begin
                   rezs := rezs + " " + Popc;
                 end;
               Popc;
             end
           else
             if s[i] in ["+", "-", "*", "/"] then
               begin
                 while pri[Pos(w[len2], prs)] >= pri[Pos(s[i], prs)] do
                   rezs := rezs + " " + Popc;
                 PushC(s[i]);
               end;
       end;
   end;
 while len2 <> 0 do
   rezs := rezs + " " + Popc;
 Change := rezs;
end;

function Count(s: String): Real;
var
 ss: String;
 x, s1, s2: Real;
 chh, s3: Char;
 p, i, j: Cardinal;
 tmp: Integer;
begin
 i := 0;
 repeat
   j := i + 1;
   repeat
     Inc(i)
   until s[i] = " ";
   ss := copy(s, j, i - j);
   chh := ss[1];
   if not(chh in ["+", "-", "*", "/"]) then
     begin
       Val(ss, p, tmp);
       Push(p);
     end
   else
     begin
       s2 := Pop;
       s1 := Pop;
       s3 := chh;
       Push(Oper(s1, s2, s3));
     end;
 until i >= n;
 x := Pop;
 Count := x;
end;

procedure WriteL(x: Real);
var
 y, a, b: Cardinal;
 q: Real;
begin
 y := Trunc(x);
 b := 0;
 if Abs(x - y) < (1E-12) then
   Writeln(y)
 else
   begin
     if y > 0 then
       a := round(ln(y) / ln(10)) + 1
     else
       a := 1;
     q := x;
     repeat
       q := q * 10;
       Inc(b);
     until Abs(q - Trunc(q)) < (1E-12);
     Writeln(x:a + b:b);
   end;
end;

begin
 repeat
   Writeln("Enter expression");
   Readln(s1);
   n := Length(s1);
   PreChange(s1);
   n := Length(s1);
   s2 := Change(s1);
   if s2[1] = " " then
     delete(s2, 1, 1);
   s2 := s2 + " ";
   n := Length(s2);
   t := Count(s2);
   WriteL(t);
   Writeln("One more expression?(Y/N)");
   Readln(ch);
 until UpCase(ch) = "N";

end.


 
KilkennyCat ©   (2011-02-25 22:12) [30]

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


 
Inovet ©   (2011-02-25 22:12) [31]

А что там видеть x, y doublе для аргументов, yo integr для операции


 
KilkennyCat ©   (2011-02-25 22:13) [32]


> Fergo ©   (25.02.11 22:10) [29]

ты меня пугаешь.


 
Inovet ©   (2011-02-25 22:17) [33]

> [24] KilkennyCat ©   (25.02.11 21:54)
> калькулятор в вин 7 в режиме для программиста не позволяет
> вводить вещественные числа. это меня прикольнуло.

Ага, тоже.


 
Palladin ©   (2011-02-25 22:17) [34]

найти мало, нужно понять


 
KilkennyCat ©   (2011-02-25 22:20) [35]


> KilkennyCat ©   (25.02.11 22:10) [28]

>        15 : if a = 0 then a := strtofloat(edit1.text) else
> begin
>                    b := strtofloat(edit1.text);
>                    вычислитель(oper);
>                    edit1.text := floattostr(a);
>                  end;


ошибся.
надо так:
        15 :  begin
                  if b := 0 then b := strtofloat(edit1.text);
                  вычислитель(oper);
                  edit1.text := floattostr(a);
                end;

но лучше ввести еще один флаг.


 
Fergo ©   (2011-02-25 22:21) [36]


> procedure TForm.btnClick(Sender: TObject);
> begin
>   case (sender as TComponent).tag of
>      1..9 : edit1.text := edit1.text + inttostr( (sender
> as TComponent).tag);
>       18 : if  pos("." edit1.text) < 1 then edit1.text :
> = edit1.text + "."
>      12..14 begin
>                  oper := (sender as TComponent).tag - 10;
>  
>                  if a = 0 then a := strtofloat(edit1.text)
> else begin
>                    b := strtofloat(edit1.text);
>                    вычислитель(oper);
>                    edit1.text := floattostr(a);
>                  end;
>               end;
>        15 : if a = 0 then a := strtofloat(edit1.text) else
> begin
>                    b := strtofloat(edit1.text);
>                    вычислитель(oper);
>                    edit1.text := floattostr(a);
>                  end;
>        20 : begin
>                a := 0;
>                b := 0;
>                oper := 0;
>              end;
>    end;            
> end;


а ты сам это проверял? просто мне кажется что тут будет ошибка в своевременности прсвоения переменной А и Б если А=0 или нет. а если мы А задали как "0"? но за вариант с тагами спс. что то о них не думал как то даж)


 
KilkennyCat ©   (2011-02-25 22:22) [37]

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


 
Inovet ©   (2011-02-25 22:23) [38]

> [24] KilkennyCat ©   (25.02.11 21:54)
> в вин 7

Меня порадовало ведение всей истории с возможностью выбора из неё в удобоваримом виде, по умолчанию отключена, и даже сохранить в файл можно, наверно тоже полезная возможность.


 
Fergo ©   (2011-02-25 22:23) [39]


> точнее, лучше сделать два обработчика кнопки равно и менять
> у нее тэг.
> собственно, фигня задача.


а вот это реальная мысль..)


 
KilkennyCat ©   (2011-02-25 22:24) [40]


>  тут будет ошибка в своевременности прсвоения переменной
> А и Б если А=0 или нет.

да, возможно.
это решается малюсенькой доработкой, как я уже сказал, двойной обработкой "равно" (чтобы не лепить громадье условий и не вводить лишнии переменные)
а проверять это мне лень было, это ж надо делфи запускать... столько баттнов кидать...



Страницы: 1 2 3 вся ветка

Текущий архив: 2011.06.19;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.011 c
15-1298803240
Дмитрий С
2011-02-27 13:40
2011.06.19
Помощь по дизайну


2-1299929528
mefodiy
2011-03-12 14:32
2011.06.19
Ввод со сканера штрих-кодов


2-1299926254
Сергей
2011-03-12 13:37
2011.06.19
Проблемы с запуском программы


15-1299063412
>|<
2011-03-02 13:56
2011.06.19
Что лучше, DOA или ODAC?


11-1212932481
Psy
2008-06-08 17:41
2011.06.19
Баг Grush