Transformar Decimais em Romanos

17 respostas
Mitnick8

Boas,

Estou com uma tremenda duvida em como fazer esse exercício, é o seguinte:

Escreva um método que converta números deciamais em números romanos. Não
é permitido usar uma tabela de conversão.

Não quero que façam, mais que me dêem uma noção de como fazer…

17 Respostas

lucianoaac

encadeamente de if ???

Mitnick8

mais aí o professor pode achar que usei uma tabela, não e teria outro modo além desse?

lucianoaac

a de haver.
como quer ele quer a leitura?

Mitnick8

O professor não exemplificou nada só postou isso:

Escreva um método que converta números deciamais em números romanos. Não
é permitido usar uma tabela de conversão.

davidbuzatto

O primeiro passo é pegar o número decimal e ir divindindo ele para obter as os algaristmos romanos.
Como vc sabe, os símbolos no sistema romano são M, D, etc.
M significa 1000, D signidica 500, etc.

1 - Pegue o número, divida por 1000. Isso lhe dará a quantidade de Ms do número.
2 - Pegue o resto da divisão anterior, divida por 500. Isso lhe dará a quantidade Ds do número.
3 - Faça o mesmo processo até chegar na divisão por 1.
4 - Com isso vc tem a quantidade de Ms, Ds, …, Is.
5 - Com as quantidades, vc precisa fazer os agrupamentos. Por exemplo. 9 viraria um V mais quatro Is, mas como vc sabe, 9 em romanos é IX. Então vc tem que reorganizar “VIIII” (que está errado) para virar “IX”.

Seu professor não deu um limite para conversão? Digo isso pq com esse algoritmo vc chega até 3999. A partir do 4000 vc usa o símbolo “barra” em cima do número para indicar multiplicação por 1000. Cada multiplicação por 1000 é uma barra a mais. E não dá p/ fazer isso no console e é uma baita de uma perda de tempo fazer isso como Java2D por exemplo…
Outra coisa, talvez ele não esteja exigindo que haja o agrupamento dos algarismos, então o seu programa vai estar pronto assim que chegar no passo 4 acima.

[]´s

P.S. 1: Opsss. D é 500. L é 50. Falha a minha :oops:
P.S. 2: Lembre-se que a não existe símbolo para zero nos algaristmos romanos (foram os árabes que inventaram a notação para o zero).
P.S. 3: Não existem números negativos em romanops tbm.

lucianoaac

opa aprendi uma coisa boa, não sabia que tinha sido os arabes que inseriram o 0.

Mitnick8

Só respondendo minha própria pergunta, resolvi postar o codigo que fiz para aqueles que um dia quiserem e para quem achar que pode estar errado e corrigir…

import javax.swing.JOptionPane;

/**
 *
 * @author Maico
 */
public class Questao_05 {

    public String buscaNumero() {
        String num = JOptionPane.showInputDialog(null, "Número:");
        int n = Integer.parseInt(num);
        if(n <= 3000){
        }else{
            JOptionPane.showMessageDialog(null,"Só converte números menores que 3 mil");
        }
        return num;
    }

    public String seperaNumero() {
        String result = "";
        String n = buscaNumero();
        int contNumero = n.length();
        if (contNumero == 1) {
            int num = Integer.parseInt(n.substring(0, 1));
            result = retorna9(num);
        } else if (contNumero == 2) {
            int num = Integer.parseInt(n.substring(0, 1));
            int num2 = Integer.parseInt(n.substring(1, 2));
            result = retorna99(num) + retorna9(num2);
        } else if (contNumero == 3) {
            int num = Integer.parseInt(n.substring(0, 1));
            int num2 = Integer.parseInt(n.substring(1, 2));
            int num3 = Integer.parseInt(n.substring(2, 3));
            result = retorna999(num) + retorna99(num2) + retorna9(num3);
        } else {
            int num = Integer.parseInt(n.substring(0, 1));
            int num2 = Integer.parseInt(n.substring(1, 2));
            int num3 = Integer.parseInt(n.substring(2, 3));
            int num4 = Integer.parseInt(n.substring(3, 4));
            result = retorna3(num) + retorna999(num2) + retorna99(num3) + retorna9(num4);
        }
        return result;
    }

    public String retorna9(int num) {
        String numSt = new String();
        if (num <= 3) {
            for (int i = 0; i < num; i++) {
                if (num > i) {
                    numSt += "I";
                }
            }
        } else if (num >= 5 && num < 9) {
            if (num == 5) {
                numSt = "V";
            } else {
                numSt = "V";
                for (int i = 5; i < num; i++) {
                    if (num > i) {
                        numSt += "I";
                    }
                }
            }
        } else if (num == 4) {
            numSt = "IV";
        } else {
            numSt = "IX";
        }
        return numSt;
    }

    public String retorna99(int num) {
        String numSt = new String();
        if (num <= 3) {
            for (int i = 0; i < num; i++) {
                if (num > i) {
                    numSt += "X";
                }
            }
        } else if (num >= 5 && num < 9) {
            if (num == 5) {
                numSt = "L";
            } else {
                numSt = "L";
                for (int i = 5; i < num; i++) {
                    if (num > i) {
                        numSt += "X";
                    }
                }
            }
        } else if (num == 4) {
            numSt = "XD";
        } else {
            numSt = "XC";
        }
        return numSt;
    }

    public String retorna999(int num) {
        String numSt = new String();
        if (num <= 3) {
            for (int i = 0; i < num; i++) {
                if (num > i) {
                    numSt += "C";
                }
            }
        } else if (num >= 5 && num < 9) {
            if (num == 5) {
                numSt = "D";
            } else {
                numSt = "D";
                for (int i = 5; i < num; i++) {
                    if (num > i) {
                        numSt += "M";
                    }
                }
            }
        } else if (num == 4) {
            numSt = "CD";
        } else {
            numSt = "CM";
        }
        return numSt;
    }

    public String retorna3(int num) {
        String numSt = new String();
        if (num <= 3) {
            for (int i = 0; i < num; i++) {
                if (num > i) {
                    numSt += "M";
                }
            }
        }
        return numSt;
    }

    public static void main(String[] args) {
        Questao_05 q = new Questao_05();
        System.out.println(q.seperaNumero());
    }
}
davidbuzatto

Mitnik, não resisti e criei alguns métodos para conversão.
Se tiver dúvida em alguma coisa, poste ai.

import javax.swing.JOptionPane;

/**
 *
 * @author David Buzatto
 */
public class NumerosRomanos {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        teste1();
        teste2();

    }

    private static void teste1() {

        for ( int i = 1; i < 1001; i++ ) {
            System.out.println( String.format( "%d: %s => %s",
                    i,
                    gerarRepresentacaoBase( i ),
                    decimalParaRomano( i ) ) );
        }

    }

    private static void teste2() {

        try {

            int v = Integer.parseInt( JOptionPane.showInputDialog( "Entre com um valor" ) );

            String resultado = String.format( "Decimal: %d\nRomano: %s",
                    v,
                    decimalParaRomano( v ) );

            JOptionPane.showMessageDialog( null, resultado );

        } catch ( NumberFormatException exc ) {
            JOptionPane.showMessageDialog( null, "Número mal formatado!" );
        } catch ( ArithmeticException exc ) {
            JOptionPane.showMessageDialog( null, "Intervalo de conversão inválido!" );
        }

    }
    

    /**
     * Gera um número romano.
     *
     * @param decimal Número decimal a ser usado.
     * @return Número em algarismos romanos gerado com base no número decimal.
     * @throws ArithmeticException Caso o valor decimal não esteja entre 1 (inclusive) e 3999 (inclusive).
     */
    public static String decimalParaRomano( int decimal ) 
            throws ArithmeticException {

        return rearranjarNumero( gerarRepresentacaoBase( decimal ) );

    }

    /**
     * Gera a representação base do número. Exemplo: 495 = CCCCLXXXXV
     * 
     * @param decimal Número decimal a ser usado.
     * @return Número em algarismos romanos gerado com base no número decimal.
     * @throws ArithmeticException Caso o valor decimal não esteja entre 1 (inclusive) e 3999 (inclusive).
     */
    public static String gerarRepresentacaoBase( int decimal )
            throws ArithmeticException {

        if ( decimal > 0 && decimal < 4000 ) {

            StringBuilder sb = new StringBuilder();

            // M
            sb.append( gerarNumeroBase( decimal, 1000, 'M' ) );
            decimal %= 1000;

            // D
            sb.append( gerarNumeroBase( decimal, 500, 'D' ) );
            decimal %= 500;

            // C
            sb.append( gerarNumeroBase( decimal, 100, 'C' ) );
            decimal %= 100;

            // L
            sb.append( gerarNumeroBase( decimal, 50, 'L' ) );
            decimal %= 50;

            // X
            sb.append( gerarNumeroBase( decimal, 10, 'X' ) );
            decimal %= 10;

            // V
            sb.append( gerarNumeroBase( decimal, 5, 'V' ) );
            decimal %= 5;

            // I
            sb.append( gerarNumeroBase( decimal, 1, 'I' ) );

            return sb.toString();

        } else {

            throw new ArithmeticException( "O intervalo para conversão é [1;3999]" );

        }

    }

    /**
     * Rearraja o número romano. Exemplo CCCC = CD, CCCCLXXXXV = CDXCV, etc.
     *
     * @param numero Número em algarismos romanos que deve ser rearranjado.
     * @return Número em algarismos romanos rearranjado.
     */
    private static String rearranjarNumero( String numero ) {

        StringBuilder sb = new StringBuilder();

        int qM = 0;
        int qD = 0;
        int qC = 0;
        int qL = 0;
        int qX = 0;
        int qV = 0;
        int qI = 0;

        // conta a quantidade de cada algarismo
        for ( char n : numero.toCharArray() ) {

            switch ( n ) {
                case 'M': qM++; break;
                case 'D': qD++; break;
                case 'C': qC++; break;
                case 'L': qL++; break;
                case 'X': qX++; break;
                case 'V': qV++; break;
                case 'I': qI++; break;
            }

        }

        // reconstrói o número invertido, começando pela unidade
        boolean pularProximo = false;

        // trata I, V e X
        if ( qI == 4 ) {
            if ( qV == 1 ) {
                sb.append( "XI" );
                pularProximo = true;
            } else {
                sb.append( "VI" );
                pularProximo = true;
            }
        } else {
            sb.append( replicarSimbolo( qI, 'I' ) );
            pularProximo = false;
        }

        if ( !pularProximo ) {
            sb.append( replicarSimbolo( qV, 'V' ) );
        }

        // trata X, L e C
        if ( qX == 4 ) {
            if ( qL == 1 ) {
                sb.append( "CX" );
                pularProximo = true;
            } else {
                sb.append( "LX" );
                pularProximo = true;
            }
        } else {
            sb.append( replicarSimbolo( qX, 'X' ) );
            pularProximo = false;
        }

        if ( !pularProximo ) {
            sb.append( replicarSimbolo( qL, 'L' ) );
        }

        // trata C, D e M
        if ( qC == 4 ) {
            if ( qD == 1 ) {
                sb.append( "MC" );
                pularProximo = true;
            } else {
                sb.append( "DC" );
                pularProximo = true;
            }
        } else {
            sb.append( replicarSimbolo( qC, 'C' ) );
            pularProximo = false;
        }

        if ( !pularProximo ) {
            sb.append( replicarSimbolo( qD, 'D' ) );
        }

        // M
        sb.append( replicarSimbolo( qM, 'M' ) );

        // inverte
        return sb.reverse().toString();

    }

    /**
     * Gera o número base. Exemplo: 400 = CCCC
     *
     * @param valor Valor usado para gerar o número.
     * @param dividirPor Qual a divisão que deve ser feita.
     * @param simbolo Símbolo do algarismo que será gerado.
     * @return O número base gerado.
     */
    private static String gerarNumeroBase( int valor, int dividirPor, char simbolo ) {
        return replicarSimbolo( valor / dividirPor, simbolo );
    }

    /**
     * Replica um determinado simbolo.
     *
     * @param quantidade Quantidade de símbolos a serem gerados.
     * @param simbolo Símbolo a ser usado.
     * @return Uma String com a quantidade especificada de símbolos.
     */
    private static String replicarSimbolo( int quantidade, char simbolo ) {

        StringBuilder sb = new StringBuilder();

        for ( int i = 0;  i < quantidade; i++ ) {
            sb.append( simbolo );
        }

        return sb.toString();

    }

}
davidbuzatto

Aqui - http://en.wikipedia.org/wiki/Roman_numerals - tem um algoritmo beeem mais simples.

[]´s

Mitnick8

davidbuzatto:
Aqui - http://en.wikipedia.org/wiki/Roman_numerals - tem um algoritmo beeem mais simples.

[]´s

Amigo, e como seria se eu quisesse fazer ao contrario, transformar números romanos em decimais?

davidbuzatto

Agora é com vc.
Tá na hora de queimar um pouco de fosfato :smiley:

Implemente algo e poste suas ideias, dúvidas e resultados.
Ai a gente ajuda :wink:

[]´s

A

ola apesar de estar bem claro a resposta aki, tenho que fazer quase a mesma coisa, estou recem no inicio do curso, e nao consigo fazer.

no meu caso tenho que digitar um numero inteiro ate 100, e ele teve retornar em romano, posso utilizar case, while, if, e o import java.util.Scanner;, nada de muito complicado mas eu nao to conseguindo fazer esse trem andar. preciso para amanha isso. se alguem puder ajudar.

nao pode ter o “for” pq ainda nao aprendi.

davidbuzatto

O que você já fez até o momento?
No que está com dificuldade?
Pode postar?

[]´s

E

arkemo:
ola apesar de estar bem claro a resposta aki, tenho que fazer quase a mesma coisa, estou recem no inicio do curso, e nao consigo fazer.

no meu caso tenho que digitar um numero inteiro ate 100, e ele teve retornar em romano, posso utilizar case, while, if, e o import java.util.Scanner;, nada de muito complicado mas eu nao to conseguindo fazer esse trem andar. preciso para amanha isso. se alguem puder ajudar.

nao pode ter o “for” pq ainda nao aprendi.

Só para você aprender, você pode pegar o código que gentilmente lhe ofereceram de graça, e transformar o “for” em um “while”. É tão simples…

Basicamente, um

for (parte1; parte2; parte3) {
    ...
}

é equivalente a:

parte1;
while (parte2) {
    ...
    parte3;
}
E

Você não tem um colega mais esperto na sua sala que pode lhe fazer o exercício depois que você lhe pagar umas cervejas? Aqui não temos PayPal por isso não dá para fazer isso… :slight_smile:

A
}

}

Mitnick8

O que consegui fazer do programa foi isso:

import javax.swing.JOptionPane;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Maico
 */
public class Questao_06 {

    int saida = 0;

    public String buscaNumero() {
        String num = JOptionPane.showInputDialog(null, "Entre com o Número:");
        return num;
    }

    public int transformaDecimal_10(String num) {
        int contaNum = num.length();
        String stNum = num.substring(0, 1);
        String stNum2;
        if (contaNum == 2) {
            stNum2 = num.substring(1, 2);
        } else {
            stNum2 = "";
        }
        if (stNum.equalsIgnoreCase("I")) {
            saida = contaNum;
            if (stNum2.equalsIgnoreCase("V")) {
                saida = 4;
            } else if (stNum2.equalsIgnoreCase("X")) {
                saida = 9;
            }
        }
        if (stNum.equalsIgnoreCase("V")) {
            saida = 5;
        }
        if (stNum.equalsIgnoreCase("V")) {
            int cont = 1;
            int cont2 = 2;
            for (int i = 6; i < (contaNum + 5); i++) {
                stNum2 = num.substring(cont, cont2);
                if (stNum2.equalsIgnoreCase("I")) {
                    saida = i;
                }
                cont++;
                cont2++;
            }
        }
        return saida;
    }

    public int transformaDecimal_100(String num) {
        int contaNum = num.length();
        String stNum = num.substring(0, 1);
        String stNum2;
        if (contaNum == 2) {
            stNum2 = num.substring(1, 2);
        } else {
            stNum2 = "";
        }
        if (stNum.equalsIgnoreCase("X")) {
            saida = contaNum * 10;
            if (stNum2.equalsIgnoreCase("L")) {
                saida = 40;
            } else if (stNum2.equalsIgnoreCase("C")) {
                saida = 90;
            }
        }
        if (stNum.equalsIgnoreCase("L")) {
            saida = 50;
        }
        if (stNum.equalsIgnoreCase("L")) {
            int cont = 1;
            int cont2 = 2;
            for (int i = 6; i < (contaNum + 50); i++) {
                stNum2 = num.substring(cont, cont2);
                if (stNum2.equalsIgnoreCase("X")) {
                    saida = i * 10;
                }
                cont++;
                cont2++;
            }
        }
        return saida;
    }

    public static void main(String[] args) {
        Questao_06 q = new Questao_06();
        System.out.println(q.transformaDecimal_100(q.buscaNumero()));
    }
}

Bem se alguém tiver alguma dica de como fazer, ficaria grato.

Criado 27 de novembro de 2010
Ultima resposta 1 de dez. de 2010
Respostas 17
Participantes 5