Como seria o fonte

Delphi

28/10/2003

caros amigos

como seria o fonte para este pequeno problema:

tenho um edit onde este recebera qualquer calculo.

ex: (20+10)/2 ou ((2*3)+(4-2)) etc.

o resultado destes calculos teria de aparecer em um outro componente, pode ser em um edit, um label, etc.

obs. tem que ser digitada a formula em um edit.

desde ja valeu....


Tornadofuracao

Tornadofuracao

Curtidas 0

Respostas

Rafael Heise

Rafael Heise

28/10/2003

você ta brincando comigo?
meu cara.. isso ai é muito dificil de fazer funcionar certo, porque você não sabe exatamente o que o usuário vai digitar... nós fizemos aqui na empresa onde eu trabalho, e levamos em uma equipe cerca de 3 dias pra fazer... usamos conceito de pilha e recursividade...
infelizmente não posso passar o fonte.. mas é isso que você vai ter de fazer
abraços e boa sorte mesmo!


GOSTEI 0
Bacalhau

Bacalhau

28/10/2003

A solução passa pelo conceito de pilha e não leva 3 dias a fazer. De facto é simples. Pesquisa na net uma coisa chamada ´Notação Polaca´. De momento não posso enviar porque não sei onde está. Mas é simples.


GOSTEI 0
Rafael Heise

Rafael Heise

28/10/2003

lamento.. mas não achei simples.. são conceitos pesados pra quem não está acostumado com programação...
eu disse 3 dias mas não foram 3 dias inteiros em cima disso, mas até que ficasse realmente completo levou isso...


GOSTEI 0
Bacalhau

Bacalhau

28/10/2003

Zerneo, de forma alguma quero subestimar o vosso trabalho desenvolvido. Se ofendi, peço desculpa imediatamente.

Mas no mundo da programação (como em todos os outros) existem soluções incrivelmente simples para problemas complexos. Simples depois de as vermos, claro!!!

Eu não consigo enviar a solução porque está numa pilha de papeis, impossível de achar. Mas lembro-me que um professor da universidade, deu a solução com 20 linhas de código. E já foi há alguns anos....


GOSTEI 0
Beppe

Beppe

28/10/2003

20 linhas? Só se for escrito na própria Notação Polonesa Reversa(cá chamamos assim, ora pois), que é bem chata de escrever.

São só estes operadores que tu quer? E só inteiros?

Ataliba


GOSTEI 0
Rafael Heise

Rafael Heise

28/10/2003

não me senti ofendido de forma alguma, mas a função para resolução de fórmulas que desenvolvemos aqui resolve todas as operações matemáticas de cálculo e testas diversas coisas, e a função também verifica se a fórmula está escrita correta e várias outras coisas..
a função está bem completa e bem testada....
mas ainda acho que não será possível resolver em 20 linhas pra fazer qualquer tipo de cálculo matemático, pois tem várias possibilidades de fórmulas...
abraços


GOSTEI 0
Edmarss

Edmarss

28/10/2003

Tenho um componente que possa te ajudar mande me um email, que eu te envio.


edmar@neosistem.com.br
Edmar Soethe da Silva
Programador


GOSTEI 0
Barcelos

Barcelos

28/10/2003

Olá amigos,

Para passar uma expressão para a notação Polonesa reversa, creio que o seguinte código funciona:

NOTA: Código da Professora Rosália Rodrigues em Métodos de Programação 1999/2000

{$APPTYPE CONSOLE}
program InfixPostfix(input, output);
var
car: char;

procedure procurar;
begin
repeat read(car);
until (car <> ´ ´) or eoln(input)
end (* procurar *);

procedure expressao;
var
operaditivo: char;
procedure termo;
var
opermult: char;
procedure factor;
begin (* factor *)
if car = ´(´ then
begin
procurar;
expressao
end
else
write(car);
procurar
end (* factor *);
begin (* termo *)
factor;
while (car = ´*´) or (car = ´/´) do
begin
opermult := car;
procurar;
factor;
write(opermult)
end
end (* termo *);
begin (* expressao *)
termo;
while (car = ´+´) or (car = ´-´) do
begin
operaditivo := car;
procurar;
termo;
write(operaditivo)
end
end (* expressao *);
begin (* Programa Principal *)
procurar;
repeat expressao;
writeln
until car = ´.´
end (*InfixPostfix *).


Ele faz somente a transcrição do código na mencionada notação.
Mas como calcular a expressão????????????
Bacalhau, essa é pra você!!!!
:D :D :D :D :D


GOSTEI 0
Luizfernando777

Luizfernando777

28/10/2003

dá uma olhada

http://www.icmsc.sc.usp.br/manuals/sce182/pind.html


GOSTEI 0
Sistemald

Sistemald

28/10/2003

Olhe este exemplo.
tente o link abaixo:
http://www.delphibr.com.br/controle.php?tipo=1&id=1

Acho que serve para você.

Se o link não funcionar va em exemplos e faça download da calculadora no site www.delphibr.com.br


GOSTEI 0
Tornadofuracao

Tornadofuracao

28/10/2003

caros amigos

muito obrigado pela ajuda, foi de grande importancia para o meu desenvolvimento.

valeu....

TornadoFuracao


GOSTEI 0
E_gama

E_gama

28/10/2003

Bem, eu poderia simplesmente colocar uma função que escreví aqui para fazer isso, mas achei melhor explanar um pouco mais o assunto...

  Vou responder a esse post com outra pergunta,
  e também a resposta :-)

  - Como os compiladores fazem para transformar expressões
    matemáticas em instruções?

  Resposta: Alguns (se não todos) utilizam um método para
            "empilhar" a expressão por ordem de precedência
            Utilizam vários PUSH´s e POP´s para inserir e remover
            os ítens das expressões na na "Pilha". Mas antes disso,
            ele tem que converter a expressão passada para um formato
            mais "fácil", normalmente chamado de "PostFix".
            O que é o formato "PostFix" ? Um exemplo:

            A expressão (1+(1+4)/2)*(5+2) no formato "PostFix"

            fica assim: 1 1 4 + 2 / + 5 2 + *

            Mas aí, como avaliar a expressão:

            1  1   4    + 2  / +  5  2  + *
     1)     !  !----+---! !  ! !  !  !  ! ! 
            !       !     !  ! !  !  !  ! !
     2)     !       5     2  ! !  !  !  ! !
            !       !     !  ! !  !  !  ! !
            !       !----+---+ !  !  !  ! !
            !            !     !  !  !  ! !
     3)     1           2,5    !  !  !  ! !
            !            !     !  !  !  ! !
            +------------+-----+  !  !  ! !
                         !        !  !  ! !
                        3,5       !  !  ! !
     4)                  !        5  2  ! !  
                         +----+---+--+--+ !
                         !        !     ! !
                         !        +--+--+ +
                         !           !    !
     5)                 3,5          7    !
                         !           !    !
                         +-----------+----+
                                     !
                                    24,5
                                    ==== 
  
     Complicado? Um "pouco" ...

     Para implementar isso, é preciso criar um rotina para 
     converter a expressão para o formato "PostFix", e em
     seguida, executar as operações acima.

     Resumindo, comece da esquerda para a direita, 
     se o ítem é num número, então "empilhe-o".
     Quando encontrar um operador "+, -, *, /", 
     pegue os dois operandos do "topo" da pilha, 
     e execute a operação em questão. Quando checar 
     ao final da expressão, o conteúdo do "Topo" da pilha, 
     será o resultado a expressão.

     Escreví uma função para isso. Ela simula um "Pilha" para
     armazenar os dados que serão inseridos (Push) e 
     retirados (Pop).


e agora, a função (não me preocupei e verficar se a expressão está correta ou não, a função simplesmente avalia-a)

// ---------------------------------------------------------
// Função para avaliar expressões matemáticas...
// by e_gama
// Por enquanto, só executa expressões com número inteiros,
// mas o resultado é um ´Real´
// ---------------------------------------------------------

function AvaliaExpressao(Expr: string): Real;
// Uses StrUtils...

var aOperadores   : array[0..99] of Char;
    aOperandos    : array[0..99] of Real;
    OperadorIndex : Integer;
    OperandosIndex: Integer;

    // Pilha de Operadoes
    // Procedure PUSH
    procedure Push(C: Char);
    begin
      Inc(OperadorIndex);
      aOperadores[OperadorIndex] := C;
    end;

    // Procedure POP
    function Pop: Char;
    begin
      Result := aOperadores[OperadorIndex];
      if OperadorIndex > 0 then
         Dec(OperadorIndex);
    end;

    // Pilha de Operandos
    // Procedure PUSH
    procedure PushOperando(V: Real);
    begin
      Inc(OperandosIndex);
      aOperandos[OperandosIndex] := V;
    end;

    // Procedure POP
    function PopOperando: Real;
    begin
      Result := aOperandos[OperandosIndex];
      if OperandosIndex > 0 then
         Dec(OperandosIndex);
    end;

var I, J        : Integer;
    C, X        : Char;
    strExpressao: string;
    AuxExpressao: string;
    Operando    : Real;

begin
  OperadorIndex  := 0;
  aOperadores[0] := ´ ´;
  Push(´(´);

  strExpressao := Expr + ´)´;
  AuxExpressao := ´´;
  X            := 0;
  I            := 0;

  while I < Length(strExpressao) do
    begin
      Inc(I);
      C := strExpressao[I];
      if C in [´0´..´9´] then
         begin
           AuxExpressao := AuxExpressao + C;
           if I < Length(strExpressao) then
              begin
                C := strExpressao[I + 1];
                if not (C in [´0´..´9´]) then
                   AuxExpressao := AuxExpressao + ´ ´;
              end;
         end
      else
         if C = ´(´ then
            Push(C)
         else
            if C = ´)´ then
               begin
                 C := Pop;
                 while (C <> ´ ´) and (C <> ´(´) do
                   begin
                     AuxExpressao := AuxExpressao + C + ´ ´;
                     C := Pop;
                   end;
               end
            else
               begin
                 if C in [´*´, ´/´, ´+´, ´-´] then
                    begin
                      if C in [´*´, ´/´] then
                         begin
                           while not (aOperadores[OperadorIndex] in [´ ´, ´+´, ´-´, ´(´]) do
                             begin
                               AuxExpressao := ´ ´ + AuxExpressao + Pop + ´ ´;
                             end;
                         end
                      else
                         begin
                           while not (aOperadores[OperadorIndex] in [´ ´, ´(´]) do
                             begin
                               AuxExpressao := AuxExpressao + Pop + ´ ´;
                             end;
                         end;
                      Push(C);
                    end;
               end;
      X := strExpressao[I];
    end;

  // Neste ponto, AuxEmpressão está no formato "PostFix"
  // Executa expressão
  OperadorIndex  := 0;
  OperandosIndex := 0;
  I              := 0;

  AuxExpressao := AuxExpressao;
  I := Pos(´ ´, AuxExpressao);
  J := 1;
  while I > 0 do
    begin
      strExpressao := Copy(AuxExpressao, J, I - J);
      C            := strExpressao[1];
      if not (C in [´+´, ´-´, ´*´, ´/´]) then
         begin
           Operando := StrToFloat(strExpressao);
           PushOperando(Operando);
         end
      else
         begin
           Operando := PopOperando;
           case C of
                ´+´: PushOperando(PopOperando + Operando);
                ´-´: PushOperando(PopOperando - Operando);
                ´*´: PushOperando(PopOperando * Operando);
                ´/´: PushOperando(PopOperando / Operando);
           end;
         end;
      J := I + 1;
      I := PosEx(´ ´, AuxExpressao, J);
    end;

  Result := PopOperando;
end;


Para utilizar:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := FloatToStr(AvaliaExpressao(Edit1.Text));
end;



GOSTEI 0
POSTAR