Arquivo de Junho, 2008

Calculadora RPN

Posted in Java with tags , , on Junho 17, 2008 by maleiria

Uma expressão aritmética está em notação postfix (também chamada reverse polish notation ou RPN)se cada operador for colocado depois dos seus operandos. Por exemplo 3*(4+5) fica 3 4 5 + *. A notação 3*(4+5) chama-se infix. As expressões quando estão em notação postfix, são mais fáceis de serem processadas pelos computadores do que as expressões infix.
A seguinte classe processa expressões rpn e efectua as respectivas operações aritméticas. O centro nevrálgico do programa é o interface Deque e a classe ArrayDeque. Um deque é uma queue com duas saídas, ou seja, é uma estrutura linear que permite inserções e remoções só nos dois extremos (Deque).
Então, temos:

/**
 * Esta classe faz o parsing de expressões em postfix
 * (reverse polish notation)
 * e efectua as respectivas operações aritméticas
 *
 * @author Manuel
 *
 */
public class RPNCalculator {

	private static Deque stack =
		new ArrayDeque();
	/**
	 *
	 * @param input
	 */
	public static void calculate(String input) {
		char ch = input.charAt(0);
		if (ch == '+' || ch == '-' || ch == '*'
			|| ch == '/') {
			double y =
			  Double.parseDouble(
                                          stack.pop());
			double x =
			  Double.parseDouble(
			    stack.pop());
			double z = 0.0;
			switch (ch) {
			case '+':
				z = x + y;
				break;
			case '-':
				z = x - y;
				break;
			case '*':
				z = x * y;
				break;
			case '/':
				z = x / y;
				break;
			}
			System.out.printf
			  ("\t%.2f %c %.2f = %.2f%n",
			    x, ch, y, z);
			stack.push(new Double(z).toString());
		} else {
			stack.push(input);
		}
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while (true) {
			String input = in.nextLine();
			calculate(input);
			if(input.equalsIgnoreCase("q"))
				break;
		}
	}
}

A parte chata é que para fazer uma qualquer operação, temo primeiro que converter a expresão para a sua correspondente versão RPN. Segue um programa que faz isso mesmo:

public class ConvertInfixToPostfix {

	public static void main(String[] args){

		Deque stack =
			new ArrayDeque();
		String line =
			new Scanner(System.in).nextLine();
		System.out.println(line);
		Scanner scanner = new Scanner(line);
		while(scanner.hasNext()){
			if(scanner.hasNextInt()){
				System.out.print(
				  scanner.nextInt() + " ");
			}else{
				String str = scanner.next();
				if("+-*/".indexOf(str) >= 0){
					stack.push(str);
				}else if(str.equals(")")){
				  System.out.print(
				    stack.pop() + " ");
				}
			}
		}
		while(!stack.isEmpty()){
			System.out.print(stack.pop() + " ");
		}
		System.out.println();
	}
}

Dicas: pesquisa binária e pesquisa sequêncial

Posted in Java with tags , on Junho 5, 2008 by maleiria
/**
 * Pesquisa um numero x num array ordenado.É
 * muito mais eficiente do que a pesquisa sequencial
 * mas requer que os elementos do array estejam ordenados.
 * Ele repetidamente divide a sequência em dois e em cada
 * vez restringe a pesquisa à metade que contém o elemento.
 *
 * Este algoritmo corre no tempo O(log(n)) o que quer dizer que
 * em média, o tempo de execução é proporcional ao logaritmo
 * do número de elementos no array.
 *
 *
 * @return o indice do numero x ou -1 se não encontrou
 */
public int binarySearch(int[] a, int x){

	int low = 0;
	int high = a.length;

	while(low < high){
		int i = (low + high) / 2;
		if(a[i] == x){
			return i;
		}else if(a[i] < x){
			low = i + 1;
		}else{
			high = i;
		}
	}
	return -1;
}
/**
 * Pesquisa sequencial (ou pesquisa linear) é o algoritmo
 * de pesquisa mais simples mas também é o menos eficiente.
 * Ele examina cada elemento sequencialmente começando
 * pelo primeiro elemento até chegar ao fim do array(se
 * eu estiver à procura de alguém num combóio, utilizo a
 * pesquisa sequencial)
 *
 * Este algoritmo corre no tempo O(n) o que quer dizer que
 * em média, o tempo de execução é proporcional ao número
 * de elementos no array.
 *
 * @return o indice do elemento a pesquisar ou 0 se não
 * o encontrar
 */
public int sequentialSearch(int[] a, int x){
	for(int i = 0, n = a.length; i < n; i++){
		if(a[i] == x){
			return i;
		}
	}
	return -1;
}
/**
 * O algoritmo de binarysearch pode encontrar elementos rapidamente
 * num array que já está ordenado o que sugere que devamos ter os
 * elementos ordenados no array.No entanto, inserir novos elementos
 * num array ordenado é difícil pois temos de transladar os elementos
 * maiores para arranjar espaço para o novo elemento.Podemos faze-lo
 * assim:
 * @param a o array
 * @param n o numero de elementos que já estão ordenados no array
 * @param x o elemento a ser inserido no meio dos elementos
 */
void insert(int[] a, int n, int x){
  /**PreCondicao: a[0] <= ... <= a[n-1], e n < a.length */
  /**PosCondicao: a[0] <= ... <= a[n], e x está entre eles */
  int i = 0;
  while(i < n && a[i] <= x){
  	i++;
  }
  System.arraycopy(a, i, a, i+1, n-i);
  a[i] = x;
}

Brincadeiras matemáticas 2

Posted in Matemática with tags , on Junho 5, 2008 by maleiria

Este também é interessante:

Provar que qualquer número a é igual a um número menor b:
Sejam a, b, c quaisquer números tais que

a = b + c

então, multiplicando os dois lados por a – b, obtemos

a (a – b) = (b + c)(a – b)
a^2 -ab = ba – b^2 + ca – cb

passemos ac para o lado esquerdo,

a^2 – ab -ac = ab – b^2 – bc

factorizar,

a(a – b – c) = b(a – b – c)

dividindo ambos os lados por a – b – c obtemos

a = b

e esta?

Brincadeiras matemáticas

Posted in Matemática with tags , on Junho 4, 2008 by maleiria

Eu tenho dois filhos e pelo menos um deles é rapaz.Qual é a probabilidade do outro ser rapaz?