1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

[c++] programa para converter numeros

Discussão em 'Programação' iniciada por PTBlueDragon, 10 de Abril de 2006. (Respostas: 15; Visualizações: 4955)

  1. PTBlueDragon

    PTBlueDragon Power Member

    um programa que converta números positivos introduzidos pelo utilizador em numeração binária, hexadecimal e romana. Crie as funções que entender adequadas.

    será k alguem consegue?
    é urgente
     
  2. HecKel

    HecKel The WORM

    Boas!

    Uma das regras não escritas deste fórum é que não se dá trabalho, ajudamos com todo o gosto se soubermos e pudermos, agora fazer ninguém te vai fazer! Tenta por ti mesmo, se tiveres dúvida no algoritmo ou quiseres dicas para te ajudar na implementação o pessoal ainda te ajuda ;)

    abraços, HecKel

    PS -> Pesquisa antes como se fazem conversões e vais ver que não é nada do outro mundo :)
     
  3. alph

    alph Power Member

    Tu consegues. :)

    Usa o google, wikipedia, aprende a converter números de base 10 para outras bases, e quanto à numeração romana, bem, é a mesma coisa, apenas tens que pensar um pouco mais, o que não deve ser problema para uma pessoa que sabe ir a um fórum de informática e colocar um post.

    Boa sorte.
     
  4. ScOrpion-boy

    ScOrpion-boy Banido

    Estava mesmo a estudar c++, por isso até deu jeito que fez-me relembrar isto:


    Só faz para hexa, nao querias tudo feito pois não :P
     
  5. HecKel

    HecKel The WORM

    Isso é uma beca à frente para mim :p Qual é o objectivo de pedirem um programa para fazer conversões se nem as contas fazes?

    Dando uma ajuda nas pesquisas:
    http://en.wikipedia.org/wiki/Hexadecimal#Converting_from_other_bases
    http://pt.wikipedia.org/wiki/Sistema_hexadecimal
    http://www.the-eggman.com/seminars/about_hex.html
    http://www.novaroma.org/via_romana/numbers.html
    http://en.wikipedia.org/wiki/Roman_numerals
    http://met.open.ac.uk/group/jwl/info/rom_num.htm
    http://www.gwydir.demon.co.uk/jo/roman/number.htm

    Nem me dei ao trabalho por procurar por binário..., é tão trivial que dá medo :p, já agora..., usa uma variável do tipo "String" para guardares os resultados das conversões..., senão vais ter problemas :)

    abraços, HecKel
     
  6. ScOrpion-boy

    ScOrpion-boy Banido

    :x2: Por isso é que dizem que c++ é muito poderosa ;) :victory:
     
  7. PTBlueDragon

    PTBlueDragon Power Member

    estudas onde scorpion?
     
  8. HecKel

    HecKel The WORM

    ya ya, de facto isso faz-te a papinha toda..., mas suponho que o pretendido seja mesmo ele estudar a forma de converter os numeros..., tal como o Alph referiu a unica que é capaz de trazer um pouco mais de complicação é decimal para romana..., de resto são apenas divisões :)

    abraços, HecKel
     
  9. para binario e hexa é mt facil (divisoes sucessivas) .. para numeraçao romana ja n é tao simples... mas tmb nd doutro mundo.

    caso percebas de scheme aqui tens 1 soluçao (google is a nice friend ;)):

    Código:
    ; decimal->roman : integer -> string
    ;   format the integer num using roman numerals
    (define (decimal->roman num)
      (let ((decimal-numbers (list 1000 900 500 400 100 90 50 40 10 9 5 4 1))
            (roman-numbers   (list "M" "CM" "D" "CD" "C" "XC" "L" 
                                   "XL" "X" "IX" "V" "IV" "I")))
        (decimal->roman-aux num "" decimal-numbers roman-numbers)))
    
    ; decimal->roman-aux : integer string (list number) (list string) -> string
    ;   append the numbers num formatted as roman numerals to the string s,
    ;   using the roman numerals in roman-numbers with corresponding
    ;   decimal values in decimal-values
    (define (decimal->roman-aux num s decimal-numbers roman-numbers)
      (if (null? decimal-numbers)
          s
          (if (>= num (car decimal-numbers))
              (decimal->roman-aux (- num (car decimal-numbers)) 
                                  (string-append s (car roman-numbers)) 
                                  decimal-numbers roman-numbers)
              (decimal->roman-aux num s 
                                  (cdr decimal-numbers) (cdr roman-numbers)))))
    podia-te passar isto pa c mas assim n tinhas qse trabalho nenhum a passar dps pa c++ :P
     
  10. JuSt_Me_AnD_yOu

    JuSt_Me_AnD_yOu What is folding?

    Para binario e hexadecimal tens uma biblioteca que podes adicionar que te faz isso logo. Agora para romana tens que fazer a pata penso eu
     
  11. ScOrpion-boy

    ScOrpion-boy Banido

    Fiz um pugraminha para passar para romanos!
    Só funciona de 0 a 99 :002:

    Edit:
    Retirei a ideia deste site:
    http://home.hiwaay.net/~lkseitz/math/roman/
     
    Última edição: 12 de Abril de 2006
  12. HecKel

    HecKel The WORM

    Bem..., e não notas nenhum padrão na numeração romana? :p Dava para simplificares isso BEM MAIS e alargares facilmente para mil..., ou mais...

    A numeração romana funciona segundo vários critérios (agrupamentos)
    - Padrão dos multiplos de 5 (unidade 1)
    - Padrão dos multiplos de 10 (unidade 10)
    - Padrão dos multiplos de 50 (5*10) (unidade 10)
    - Padrão dos multiplos de 100 (10*10) (unidade 100)
    (blablabla)

    Depois sabes que consoante a unidade escolhida (referido entre parentesis) encontras um outro padrão:
    - 1ª-3ª unidades incrementa-se apenas o simbolo
    - 4ª unidade simbolo da unidade + simbolo do próximo multiplo de 5

    Nada como decompor os números e facilitares as contas..., usa divisões..., restos..., e afins..., com isso consegues facilmente detectar qual o padrão que vais aplicar, depois só tens de concatenar as strings :)

    Este algoritmo é "ligeiramente" atrofiante de perceber..., aparentemente resulta, nunca o estudei estou agora a analizar o caso pela primeira vez, simplesmente não gosto muito de alguns cases que usas para poupares calculos..., por vezes os cáculos mais complexos são os melhores na extensibilidade do programa (nem sempre....), e da forma como estás a fazer sempre que quisesses "extender" a "banda" do teu programa terias de alterar o código..., recompilar..., blá blá blá...., excelente para quem faz um software e já está a contar com o guito que vai cobrar no suporte :x2:

    abraços, HecKel
     
  13. badsatan

    badsatan Power Member

    DE facto a solução do scorpio é "à preguiçoso"... Existe de facto um padrão como disse o heckel. Há uns anos, argh... há muitos anos... fiz umas funções desse tipo lembro-me que na altura ainda deram algum trabalho.
    Divirtam-se.

    Código:
    /* to_roman.c -- convert a value to a roman string */
    
    /* $Id$ */
    /* Carlos Duarte, 950816/980104 */
    
    /*
     * int to_roman(unsigned int rval, char *str, size_t max);
     *         converts `rval', into a string that represents that value in
     *         roman, and write results on `str', but no more than `max' chars
     *         (including the final \0)
     * 
     * The above is all that is necessary to use this file: just compile it,
     * with no special options, to get code for `to_roman()' function
     * 
     * --
     * 
     * But, to go further:
     * 
     * . there are 3 != implementations, each can be obtained by defining ROMAN
     *   to a number (1 for first, 2 for second and 3 for third)
     * 
     * . the first is the default
     * 
     * . also, a test is provided, define -DTEST to get it
     * 
     * . and a demo, which is obtained with -DDEMO
     * 
     * . and finally, a PROF, that measure time performance of the three routines, 
     *   this is obtained with -DPROF.
     *   Also, with -DPROF, also -DTOP_ROMAN will be recognized as 1 .. TOP_ROMAN
     *   values to convert
     * 
     * --
     * 
     * As for the algorithms: the first, use a table with all possible
     * combinations of roman digits or pairs, and keep removing
     * the biggest value, while it can. This is the faster.
     * 
     * The other two, use the same algorithm, but implemented
     * on a diferent way. The roman value, is parsed from lowest
     * to greatest digit (as oposed above). But, while `to_roman2'
     * does a base of 10, then base of 5 way of convert, `to_roman3'
     * use only a base of 10 parser and convert all possible
     * 10 digits directly. `to_roman2' use symmetry to convert 6-9
     * into 1-5, and then convert only 1-5. 
     * 
     * As for time speed, #1 > #3 > #2. 
     */
    
    #ifndef ROMAN
    #define ROMAN 1
    #endif
    
    #if ROMAN == 1
    /*=======================================================================*/
    
    #include <stddef.h>
    
    const static struct roman_table {
            int val; 
            char *sym; 
    } r_tab[] = { 
            { 1000,  "M" }, 
            {  900, "CM" }, 
            {  500,  "D" }, 
            {  400, "CD" }, 
            {  100,  "C" }, 
            {   90, "XC" }, 
            {   50,  "L" }, 
            {   40, "XL" }, 
            {   10,  "X" }, 
            {    9, "IX" }, 
            {    5,  "V" }, 
            {    4, "IV" }, 
            {    1,  "I" }
    }; 
    
    int 
    to_roman(unsigned int rval, char *str, size_t max)
    {
            const struct roman_table *t; 
            char *s, *top; 
    
            if (max < 3)
                    return 0; 
    
            s = str; 
            top = s+(max-3);        /* save space for 3 chars write */
            t = r_tab; 
            while (rval) {
                    while (rval >= t->val) {
                            if (s > top)
                                    return (*s=0)-1; 
                                    
                            rval -= t->val; 
                            *s++ = t->sym[0]; 
                            if (t->sym[1])
                                    *s++ = t->sym[1]; 
                    }
                    t++; 
            }
            *s = 0; 
            return s-str; 
    }
    
    #endif /* ROMAN == 1 */
    
    
    #if ROMAN == 2
    /*=======================================================================*/
    
    #include <stddef.h>
    
    static const char rr_dig[] = "IVXLCDM";
    
    int 
    to_roman(unsigned int rval, char *str, size_t max)
    {
            const char *r, *top; 
            char *s; 
            int dig; 
    
            if (max < 5)
                    return 0; 
            r = rr_dig; 
            s = str; 
            top = s+(max-5);        /* ensure space for 5 chars write */
            while (rval) {
                    if (s > top)
                            return (*s=0)-1; 
    
                    dig = rval%10; 
                    rval /= 10; 
                    if (dig != 0) {
                            int c0, c1, c2; 
                            c1 = r[0]; 
                            c0 = 0; 
                            c2 = r[1]; 
                            if (dig > 5) {
                                    dig -= 5; 
                                    c0 = r[1]; 
                                    c2 = r[2]; 
                            }
                            switch (dig) {
                            case 3: *s++ = c1; 
                            case 2: *s++ = c1; 
                            case 1: *s++ = c1; if (c0) *s++ = c0; break; 
                            case 4: *s++ = c2; *s++ = c1; break; 
                            case 5: *s++ = c2; break; 
                            }
                    }
                    if (*++r == 0 || *++r == 0 || r[1] == 0) {
                            top += 3;       /* ensure space for 2 (5-3) chars */
                            if (rval) do {
                                    if (s > top)
                                            return (*s=0)-1; 
                                    *s++ = 'M'; 
                            } while (--rval > 0); 
                    }
            }
            *s = 0; 
            /* reverse str */
            {char*t=s-1;char*tt=str;while(t>tt){int c= *t;*t-- = *tt;*tt++ =c;}}
            return s-str; 
    }
    
    #endif /* ROMAN == 2 */
    
    #if ROMAN == 3
    /*=======================================================================*/
    
    #include <stddef.h>
    
    static const char r_dig[] = "IVXLCDM";
    
    int 
    to_roman(unsigned int rval, char *str, size_t max)
    {
            const char *r, *top; 
            char *s; 
            int dig; 
    
            if (max < 5)
                    return 0; 
            r = r_dig; 
            s = str; 
            top = s+(max-5);        /* ensure space for 5 chars write */
            while (rval) {
                    if (s > top)
                            return (*s=0)-1; 
    
                    dig = rval%10; 
                    rval /= 10; 
                    switch (dig) {
                    default: 
                    case 0: break; 
                    case 3: *s++ = r[0]; 
                    case 2: *s++ = r[0]; 
                    case 1: *s++ = r[0]; break; 
                    case 4: *s++ = r[1]; *s++ = r[0]; break; 
                    case 5: *s++ = r[1]; break; 
                    case 8: *s++ = r[0]; 
                    case 7: *s++ = r[0]; 
                    case 6: *s++ = r[0]; *s++ = r[1]; break; 
                    case 9: *s++ = r[2]; *s++ = r[0]; break; 
                    }
                    if (*++r == 0 || *++r == 0 || r[1] == 0) {
                            top += 3;       /* ensure space for 2 (5-3) chars */
                            if (rval) do {
                                    if (s > top)
                                            return (*s=0)-1; 
                                    *s++ = 'M'; 
                            } while (--rval > 0); 
                    }
            }
            *s = 0; 
            /* reverse str */
            {char*t=s-1;char*tt=str;while(t>tt){int c= *t;*t-- = *tt;*tt++ =c;}}
            return s-str; 
    }
    
    #endif /* ROMAN == 3 */
    
    Código:
    /* fr_roman.c -- from roman string to integer */
    
    /* $Id$ */
    /* Carlos Duarte, 971226 */
    
    
    /* 
     * int fr_roman(const char *str);
     *      
     *      converts `str', that should represent a valid 
     *      roman number, to its value
     * 
     *      returns the value, or -1, in case the string
     *      is not valid
     */
    
    
    int
    fr_roman(const char *str)
    {
            int sum, v, v0; 
    
            sum = 0; 
            v0 = 1001; 
            for (;;) {
                    switch (str[0]) {
                    case 'M': v = 1000; break; 
                    case 'D': v = 500; break; 
                    case 'C': switch (str[1]) {
                            case 'M': v = 900; str++; break; 
                            case 'D': v = 400; str++; break; 
                            default:  v = 100; break; 
                            }
                            break; 
                    case 'L': v = 50; break; 
                    case 'X': switch (str[1]) {
                            case 'C': v = 90; str++; break; 
                            case 'L': v = 40; str++; break; 
                            default:  v = 10; break; 
                            }
                            break; 
                    case 'V': v = 5; break; 
                    case 'I': switch (str[1]) {
                            case 'X': v = 9; str++; break; 
                            case 'V': v = 4; str++; break; 
                            default:  v = 1; break; 
                            }
                            break; 
                    case 0:  return sum; 
                    default: return -1; 
                    }
                    if (v > v0) 
                            break; 
                    v0 = v; 
                    sum += v; 
                    ++str; 
            }
            return -1; 
    }
    
     
  14. lplc

    lplc Power Member

    Aqui está uma possível resolução, espero que ajude, dá para converter todas as bases da binaria à hexadecimal


    #include <stdio.h>
    int main(void){
    int n,b,q,r,base[10]={0},i=0,z,j=0;
    printf("Qual o número na base decimal?\n");
    scanf (" %d",&n);
    printf("Qual a base para que quer transformar o número?\n");
    scanf (" %d",&b);
    q=n;
    while(q!=0){
    r=(q%b);
    q=(q/b);
    if(r==10) r='A';
    else if (r==11) r='B';
    else if (r==12) r='C';
    else if (r==13) r='D';
    else if (r==14) r='E';
    else if (r==15) r='F';
    base=r;
    i++;
    j++;
    }
    for (i=0;i<(j/2);i++){
    z=base;
    base=base[j-i-1];
    base[j-i-1]=z;
    }
    printf("O número %d em base decimal é igual a ",n);
    for(i=0;i<j;i++) {
    if (base<9 && base>0) printf(" %d ", base);
    else printf(" %c ", base);
    }
    printf(" na base %d\n",b);
    return 0;
    }
     
  15. Zed_Blade

    Zed_Blade Power Member

    7 anos depois... acredito que ele já tenha conseguido.. Se não conseguiu, provavelmente estava na área errada
     
  16. HLopes

    HLopes Power Member

    Por falar em necrothreading :D

    7 anos depois ainda usam os mesmos exercícios...

    :lol:
     

Partilhar esta Página