Created
July 20, 2023 20:15
-
-
Save ApenasGabs/aeb56e04a95dace813e74f4a0072fa79 to your computer and use it in GitHub Desktop.
exe3.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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