Skip to content

Instantly share code, notes, and snippets.

@ApenasGabs
Created July 20, 2023 20:15
Show Gist options
  • Save ApenasGabs/aeb56e04a95dace813e74f4a0072fa79 to your computer and use it in GitHub Desktop.
Save ApenasGabs/aeb56e04a95dace813e74f4a0072fa79 to your computer and use it in GitHub Desktop.
exe3.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Class2
{
class Expression { }
class Number : Expression
{
public double value;
public Number(double _value) { value = _value; }
}
class BinaryOp : Expression
{
public Expression left;
public Expression right;
public BinaryOp(Expression l, Expression r)
{
left = l;
right = r;
}
}
class Addition : BinaryOp
{
public Addition(Expression l, Expression r) : base(l, r) { }
}
class Subtraction : BinaryOp
{
public Subtraction(Expression l, Expression r) : base(l, r) { }
}
class Multiplication : BinaryOp
{
public Multiplication(Expression l, Expression r) : base(l, r) { }
}
class Division : BinaryOp
{
public Division(Expression l, Expression r) : base(l, r) { }
}
class Negation : Expression
{
public Expression Value {get;}
public Negation(Expression v) { Value = v; }
}
public class Ex3
{
public static void run()
{
// Implemente três Visitors que operem na árvore dada.
// - O primeiro Visitor deve retornar a profundidade da árvore.
// - O segundo deve retornar o resultado das operações.
// - O terceiro deve gerar uma string com a árvore em forma de expressão matemática.
// Por exemplo, para a árvore
// ```
// Addition(Number(1), Multiplication(Number(2), Number(3)))
// ```
// os resultados devem ser:
// ```
// Profundidade: 3
// Resultado: 7
// Expressão: (1 + (2 * 3))
// ```
// Não é necessário implementar a precedência de operações: use parênteses em todas
// as operações binárias.
// Imprima os resultados no console.
Expression tree =
new Addition(
new Number(1),
new Subtraction(
new Number(5),
new Negation(
new Multiplication(
new Number(-3),
new Division(
new Number(10),
new Number(5)
)
)
)
)
);
// Visitor para obter a profundidade da árvore
DepthVisitor depthVisitor = new DepthVisitor();
depthVisitor.Visit(tree);
int depth = depthVisitor.Depth;
// Visitor para obter o resultado das operações
ResultVisitor resultVisitor = new ResultVisitor();
resultVisitor.Visit(tree);
double result = resultVisitor.Result;
// Visitor para gerar a string da expressão matemática
ExpressionStringVisitor expressionStringVisitor = new ExpressionStringVisitor();
expressionStringVisitor.Visit(tree);
string expressionString = expressionStringVisitor.ExpressionString;
// Imprime os resultados no console
Console.WriteLine("Profundidade: " + depth);
Console.WriteLine("Resultado: " + result);
Console.WriteLine("Expressão: " + expressionString);
}
}
class DepthVisitor
{
public int Depth { get; private set; }
public void Visit(Expression expression)
{
Depth = 0; // Inicializa a profundidade como 0 antes da visita
VisitNode(expression, 1); // Começa a visita a partir da raiz
}
private void VisitNode(Expression node, int depth)
{
Depth = Math.Max(Depth, depth); // Atualiza a profundidade máxima encontrada
if (node is BinaryOp binaryOp)
{
VisitNode(binaryOp.left, depth + 1); // Visita o nó esquerdo
VisitNode(binaryOp.right, depth + 1); // Visita o nó direito
}
else if (node is Negation negation)
{
VisitNode(negation.Value, depth + 1); // Visita o nó filho
}
}
}
// Implementação do Visitor para obter o resultado das operações
class ResultVisitor
{
public double Result { get; private set; }
public void Visit(Expression expression)
{
Result = Evaluate(expression); // Avalia a expressão e armazena o resultado
}
private double Evaluate(Expression node)
{
if (node is Number number)
{
return number.value; // Retorna o valor do número
}
else if (node is BinaryOp binaryOp)
{
double leftValue = Evaluate(binaryOp.left); // Avalia o nó esquerdo
double rightValue = Evaluate(binaryOp.right); // Avalia o nó direito
// Realiza a operação correspondente
if (node is Addition)
return leftValue + rightValue;
else if (node is Subtraction)
return leftValue - rightValue;
else if (node is Multiplication)
return leftValue * rightValue;
else if (node is Division)
return leftValue / rightValue;
}
else if (node is Negation negation)
{
double childValue = Evaluate(negation.Value); // Avalia o nó filho
return -childValue; // Retorna o valor negativo do filho
}
throw new ArgumentException("Invalid expression"); // Lança exceção se a expressão for inválida
}
}
// Implementação do Visitor para gerar a string da expressão matemática
class ExpressionStringVisitor
{
public string ExpressionString { get; private set; }
public void Visit(Expression expression)
{
ExpressionString = GetExpressionString(expression); // Obtém a string da expressão
}
private string GetExpressionString(Expression node)
{
if (node is Number number)
{
return number.value.ToString(); // Retorna o valor do número
}
else if (node is BinaryOp binaryOp)
{
string leftString = GetExpressionString(binaryOp.left); // Obtém a string do nó esquerdo
string rightString = GetExpressionString(binaryOp.right); // Obtém a string do nó direito
string operatorString = GetOperatorString(node); // Obtém o operador correspondente
return $"({leftString} {operatorString} {rightString})"; // Retorna a expressão com parênteses
}
else if (node is Negation negation)
{
string childString = GetExpressionString(negation.Value); // Obtém a string do nó filho
return $"(-{childString})"; // Retorna a expressão com o sinal de negativo
}
throw new ArgumentException("Invalid expression"); // Lança exceção se a expressão for inválida
}
private string GetOperatorString(Expression node)
{
if (node is Addition)
return "+";
else if (node is Subtraction)
return "-";
else if (node is Multiplication)
return "*";
else if (node is Division)
return "/";
throw new ArgumentException("Invalid operator"); // Lança exceção se o operador for inválido
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment