Ir para conteúdo

  • Entrar usando o Facebook Entrar usando o Twitter Entrar usando o Windows Live Login com Steam Login com Google      Entrar   
  • Cadastre-se

Ícone Classificados

Adicionar um Anúncio

Redes Sociais

Membros mais bem avaliados

Membros VIP mais recentes


Foto
- - - - -

Transfomar seculo em algarismo romano


Este tópico foi arquivado. Isto significa que você não pode mais responder ao tópico.
13 respostas neste tópico

#1 User_G

User_G
  • Membros Plenos
  • 124 posts
  • Membro desde 31/07/2008
0
Neutra

Postado 14 de maio de 2010 - 17h38min

Ola, estou tentando fazer um programa que possibilite pegar o século de QUALQUER ano e transforma-lo em algarismos romanos. Deve ser:
- Não deve conter nenhum printf, apenas a entrada do ano e a saida do seculo em algarismos romanos;
- Não deve conter bibliotecas complexas, apenas as comuns (stdio,math);
- Não deve estourar o tempo limite (que eu acho que é alto, então este item não é problema).

Obrigado desde ja

Pesquisar geralmente é melhor do que perguntar!

i7 920 / DX58SO / 3x2GB DDr3 1333 OCZ XMS/ 2x500GB Seagate Barracuda 7200.12 / Saphire 4870 1gb XFX Series / OCZ 600W MODXSTREAM / Eclipse OCZ

#2 dontpanic

dontpanic
  • Membros Plenos
  • 804 posts
  • Membro desde 15/09/2009
16
Boa

Postado 14 de maio de 2010 - 23h49min

Faça ele por partes pra ficar mais simples

Dado um ano, pegue os números do século
Dado um número, transforme em algarismos romanos

A parte de pegar o século é relativamente simples:

x = 2010; //ano

y = x / 100; //um século são 100 anos, então divide por 100
//y vai ser igual a 20 agora

Se x > (y * 100) ... y = y + 1
//se x for maior que o número redondo, é porque já entrou em outro século

No final y vai ser igual a 21.

A parte de passar pra algarismos romanos é mais complicada, não por ser difícil, mas por ser mais complexa... você vai ter que criar um monte de IFs.
Mas a ideia básica é a seguinte:

Século 21...
21 é o mesmo que 20 + 1.
É importante separar os números em casas decimais pois os números romanos são todos a união das casas.

Pra separar eles você usa, exemplo:
x = 123;
unid = x % 10 é igual a 3
dezn = x % 100 é igual a 23... subtraindo (x % 10), você tem 20.
cent = x % 1000 é igual a 123... subtraindo (x % 100), você tem 100.

Então fica:
unid = (x % 10); //3
dezn = (x % 100) - unid; //20
cent = (x % 1000) - dezn - unid; //100

Depois que tiver as casas decimais separadas, é a hora de fazer o monte de ifs.

No exemplo anterior 3 se torna III, 20 se torna XX e 100 se torna C...
Então no final fica CXXIII... acho que é isso.

.
Favor usar as tags code ao postar código

.
Dont Panic


#3 User_G

User_G
  • Membros Plenos
  • 124 posts
  • Membro desde 31/07/2008
0
Neutra

Postado 15 de maio de 2010 - 02h32min

esse é que é o problema, não posso criar muitos IFs porque tenho um tempo limite pra execução. Preciso que seja quase instantaneo. E outra, o SÉCULO pode ir até 399, ou seja, ele pode digitar, sei la, o ano 288888. Ai que complica, porque até chegar nesse if.

Ou então não entendi o que você quis dizer.

Pesquisar geralmente é melhor do que perguntar!

i7 920 / DX58SO / 3x2GB DDr3 1333 OCZ XMS/ 2x500GB Seagate Barracuda 7200.12 / Saphire 4870 1gb XFX Series / OCZ 600W MODXSTREAM / Eclipse OCZ

#4 dontpanic

dontpanic
  • Membros Plenos
  • 804 posts
  • Membro desde 15/09/2009
16
Boa

Postado 15 de maio de 2010 - 03h00min

A parte dos ifs eu quis dizer o seguinte:

- se o número for menor que 4:
I repetido X vezes

- Se o número for igual a 4:
IV

- Se for igual a 5:
V

- Se for menor que 9:
V + I repetido X vezes... onde x é a diferença entre o número e 5 (ex: 8... 8 - 5 = 3... V + 3I)

- Se for igual a 9:
IX

Depois faz a mesma coisa pras dezenas e centenas.
Eu sei que o código fica bem feio assim... e talvez exista um modo melhor de fazer, mas eu já encontrei esse problema antes e no final era mais rápido criar 5 IFs do que escrever 20 linhas de código pra fazer a mesma coisa. E IFs são bem rápidos.

.
Favor usar as tags code ao postar código

.
Dont Panic


#5 User_G

User_G
  • Membros Plenos
  • 124 posts
  • Membro desde 31/07/2008
0
Neutra

Postado 17 de maio de 2010 - 21h29min

ainda nao consegui copilar, acho que esta muito restrito, nao estou conseguindo colocar numeros muito grandes
Olha como ficou o começo:

int main() {
int ano, sec;
scanf("%d",&ano);

if (ano%100 == 0)
sec = ano/100;
else
sec = ano/100 + 1;
printf("%d\n",sec);

system("Pause");
return 0;
}

Editado por User_G, 18 de maio de 2010 - 12h28min.

Pesquisar geralmente é melhor do que perguntar!

i7 920 / DX58SO / 3x2GB DDr3 1333 OCZ XMS/ 2x500GB Seagate Barracuda 7200.12 / Saphire 4870 1gb XFX Series / OCZ 600W MODXSTREAM / Eclipse OCZ

#6 loprogramador

loprogramador
  • Membros Juniores
  • 2 posts
  • Membro desde 19/05/2010
0
Neutra

Postado 19 de maio de 2010 - 22h31min

Ola USER_G, beleza?

tomei o seu problema pra compilar, e esbarrei em alguns problemas tb! Mas to quase terminando, porém fzendo com os ifs que outro usuario recomendou!

você ja conseguiu termina-lo? gostaria de ver como ficou, se puder postar aqui no topico, ficaria agradecido. Nao entendi muito bem o que você fez no seu programa aqui em cima. nao usou as bibliotecas?

vou terminar de rodar o meu e ponho assim que possivel aqui tambem!
valeu!

^_^


#7 loprogramador

loprogramador
  • Membros Juniores
  • 2 posts
  • Membro desde 19/05/2010
0
Neutra

Postado 20 de maio de 2010 - 14h00min

ainda nao consegui copilar, acho que esta muito restrito, nao estou conseguindo colocar numeros muito grandes
Olha como ficou o começo:

int main() {
int ano, sec;
scanf("%d",&ano);

if (ano%100 == 0)
sec = ano/100;
else
sec = ano/100 + 1;
printf("%d\n",sec);

system("Pause");
return 0;
}



Ola USER_G, beleza?

tomei o seu problema pra compilar, e esbarrei em alguns problemas tb! Mas to quase terminando, porém fzendo com os ifs que outro usuário recomendou!

você ja conseguiu termina-lo? gostaria de ver como ficou, se puder postar aqui no topico, ficaria agradecido. Nao entendi muito bem o que você fez no seu programa aqui em cima. nao usou as bibliotecas?

vou terminar de rodar o meu e ponho assim que possivel aqui também!
valeu!


#8 User_G

User_G
  • Membros Plenos
  • 124 posts
  • Membro desde 31/07/2008
0
Neutra

Postado 21 de maio de 2010 - 00h28min

Ola USER_G, beleza?

tomei o seu problema pra compilar, e esbarrei em alguns problemas tb! Mas to quase terminando, porém fzendo com os ifs que outro usuário recomendou!

você ja conseguiu termina-lo? gostaria de ver como ficou, se puder postar aqui no topico, ficaria agradecido. Nao entendi muito bem o que você fez no seu programa aqui em cima. nao usou as bibliotecas?

vou terminar de rodar o meu e ponho assim que possivel aqui também!
valeu!



Ola, desculpe a demora para a resposta. Então, as bibliotecas são as simples, como a stdio que eu coloquei la.
Uma coisa que eu li que poderia ser interessante é a função atoi, mas não entendi como ela é.
Tudo que eu fiz até agora não deu certo, vou pegar um dos que deram quase certo e coloco aqui, mas não tenho muito sucesso :\

E outra, esqueci que o ano, se for posto a.C., tem que sair o seculo em a.C. tambem, mas esse sai com um if acho.

Pesquisar geralmente é melhor do que perguntar!

i7 920 / DX58SO / 3x2GB DDr3 1333 OCZ XMS/ 2x500GB Seagate Barracuda 7200.12 / Saphire 4870 1gb XFX Series / OCZ 600W MODXSTREAM / Eclipse OCZ

#9 dontpanic

dontpanic
  • Membros Plenos
  • 804 posts
  • Membro desde 15/09/2009
16
Boa

Postado 21 de maio de 2010 - 02h22min

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void returnRoman(char sec[], int ano);
void getNums(int num[], int ano);

int main() {
   int x;
   char sec[20];
   
   returnRoman(sec, 2010);
   printf("%s\n", sec);

   return 0;
}

void returnRoman(char sec[], int ano) {
   int nSec;
   int num[3];
   
   nSec = ano / 100;
   if (ano > (nSec * 100)) nSec++;
   
   getNums(num, nSec);
   
      switch (num[2]) {
          case 1: strcat(sec, "C"); break;
          case 2: strcat(sec, "CC"); break;
          case 3: strcat(sec, "CCC"); break;
          case 4: strcat(sec, "CD"); break;
          case 5: strcat(sec, "D"); break;
          case 6: strcat(sec, "DC"); break;
          case 7: strcat(sec, "DCC"); break;
          case 8: strcat(sec, "DCCC"); break;
          case 9: strcat(sec, "CM"); break;
      }
      
      switch (num[1]) {
          case 1: strcat(sec, "X"); break;
          case 2: strcat(sec, "XX"); break;
          case 3: strcat(sec, "XXX"); break;
          case 4: strcat(sec, "XL"); break;
          case 5: strcat(sec, "L"); break;
          case 6: strcat(sec, "LX"); break;
          case 7: strcat(sec, "LXX"); break;
          case 8: strcat(sec, "LXXX"); break;
          case 9: strcat(sec, "XC"); break;
      }

      switch (num[0]) {
          case 1: strcat(sec, "I"); break;
          case 2: strcat(sec, "II"); break;
          case 3: strcat(sec, "III"); break;
          case 4: strcat(sec, "IV"); break;
          case 5: strcat(sec, "V"); break;
          case 6: strcat(sec, "VI"); break;
          case 7: strcat(sec, "VII"); break;
          case 8: strcat(sec, "VIII"); break;
          case 9: strcat(sec, "IX"); break;
      }

}

void getNums(int num[], int ano) {
   num[0] = ano % 10;
   num[1] = ((ano % 100) - num[0]) / 10;
   num[2] = ((ano % 1000) - (num[1] + num[0])) / 100;
}

A parte dos switchs tá bem feia, dá pra fazer com apenas 1 switch, trocando os caracteres dependendo da posição do vetor num[]... mas tá aí, como pode ver não é um código muito complicado...

Qualquer dúvida é só mandar.

.
Favor usar as tags code ao postar código

.
Dont Panic


#10 User_G

User_G
  • Membros Plenos
  • 124 posts
  • Membro desde 31/07/2008
0
Neutra

Postado 21 de maio de 2010 - 04h36min

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void returnRoman(char sec[], int ano);
void getNums(int num[], int ano);

int main() {
   int x;
   char sec[20];
   
   returnRoman(sec, 2010);
   printf("%s\n", sec);

   return 0;
}

void returnRoman(char sec[], int ano) {
   int nSec;
   int num[3];
   
   nSec = ano / 100;
   if (ano > (nSec * 100)) nSec++;
   
   getNums(num, nSec);
   
      switch (num[2]) {
          case 1: strcat(sec, "C"); break;
          case 2: strcat(sec, "CC"); break;
          case 3: strcat(sec, "CCC"); break;
          case 4: strcat(sec, "CD"); break;
          case 5: strcat(sec, "D"); break;
          case 6: strcat(sec, "DC"); break;
          case 7: strcat(sec, "DCC"); break;
          case 8: strcat(sec, "DCCC"); break;
          case 9: strcat(sec, "CM"); break;
      }
      
      switch (num[1]) {
          case 1: strcat(sec, "X"); break;
          case 2: strcat(sec, "XX"); break;
          case 3: strcat(sec, "XXX"); break;
          case 4: strcat(sec, "XL"); break;
          case 5: strcat(sec, "L"); break;
          case 6: strcat(sec, "LX"); break;
          case 7: strcat(sec, "LXX"); break;
          case 8: strcat(sec, "LXXX"); break;
          case 9: strcat(sec, "XC"); break;
      }

      switch (num[0]) {
          case 1: strcat(sec, "I"); break;
          case 2: strcat(sec, "II"); break;
          case 3: strcat(sec, "III"); break;
          case 4: strcat(sec, "IV"); break;
          case 5: strcat(sec, "V"); break;
          case 6: strcat(sec, "VI"); break;
          case 7: strcat(sec, "VII"); break;
          case 8: strcat(sec, "VIII"); break;
          case 9: strcat(sec, "IX"); break;
      }

}

void getNums(int num[], int ano) {
   num[0] = ano % 10;
   num[1] = ((ano % 100) - num[0]) / 10;
   num[2] = ((ano % 1000) - (num[1] + num[0])) / 100;
}

A parte dos switchs tá bem feia, dá pra fazer com apenas 1 switch, trocando os caracteres dependendo da posição do vetor num[]... mas tá aí, como pode ver não é um código muito complicado...

Qualquer dúvida é só mandar.



Então, não entendi o porque sai apenas o ano 2010. E, desculpe a ignorância, não compreendi como funciona a função strcat (). Vou tentar adaptar tb a colocar a.C. se caso digitarem um ano, por ex, 200 a.C..
PS: Preciso utilizar apenas C, não C++. Valeu (:

Pesquisar geralmente é melhor do que perguntar!

i7 920 / DX58SO / 3x2GB DDr3 1333 OCZ XMS/ 2x500GB Seagate Barracuda 7200.12 / Saphire 4870 1gb XFX Series / OCZ 600W MODXSTREAM / Eclipse OCZ

#11 dontpanic

dontpanic
  • Membros Plenos
  • 804 posts
  • Membro desde 15/09/2009
16
Boa

Postado 21 de maio de 2010 - 04h45min

Então, não entendi o porque sai apenas o ano 2010. E, desculpe a ignorância, não compreendi como funciona a função strcat (). Vou tentar adaptar tb a colocar a.C. se caso digitarem um ano, por ex, 200 a.C..
PS: Preciso utilizar apenas C, não C++. Valeu (:



Ah, o ano tá 2010 apenas porque eu coloquei esse ano pra testar mesmo:
returnRoman(sec, 2010);

Nessa parte pode substituir 2010 por qualquer outro ano, inclusive usando alguma variável com um valor que o usuário tenha digitado.

strcat é uma função pra concatenar strings...
Você tem uma string1 que tem o valor "abc"... e string2 tem o valor "def"...
O comando: strcat(string1, string2)
vai colocar dentro da string1 o valor de string2, de modo que string1 fica sendo "abcdef".

No código eu usei ela pra ir jogando as letras dentro da string.

.
Favor usar as tags code ao postar código

.
Dont Panic


#12 User_G

User_G
  • Membros Plenos
  • 124 posts
  • Membro desde 31/07/2008
0
Neutra

Postado 21 de maio de 2010 - 21h01min

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void returnRoman(char sec[], int ano);
void getNums(int num[], int ano);

int main() {
   int x, y, z;
   char sec[20];
   scanf ("%d", &z);
   for ( ; z>0 ; z-- )
    {
   scanf ("%d", &y);
   
   returnRoman(sec, y);
   printf("%s\n", sec);
}
   return 0;

   
}

void returnRoman(char sec[], int ano) {
   int nSec;
   int num[3];
   
   nSec = ano / 100;
   if (ano > (nSec * 100)) nSec++;
   
   getNums(num, nSec);
   
      switch (num[2]) {
          case 1: strcat(sec, "C"); break;
          case 2: strcat(sec, "CC"); break;
          case 3: strcat(sec, "CCC"); break;
          case 4: strcat(sec, "CD"); break;
          case 5: strcat(sec, "D"); break;
          case 6: strcat(sec, "DC"); break;
          case 7: strcat(sec, "DCC"); break;
          case 8: strcat(sec, "DCCC"); break;
          case 9: strcat(sec, "CM"); break;
      }
      
      switch (num[1]) {
          case 1: strcat(sec, "X"); break;
          case 2: strcat(sec, "XX"); break;
          case 3: strcat(sec, "XXX"); break;
          case 4: strcat(sec, "XL"); break;
          case 5: strcat(sec, "L"); break;
          case 6: strcat(sec, "LX"); break;
          case 7: strcat(sec, "LXX"); break;
          case 8: strcat(sec, "LXXX"); break;
          case 9: strcat(sec, "XC"); break;
      }

      switch (num[0]) {
          case 1: strcat(sec, "I"); break;
          case 2: strcat(sec, "II"); break;
          case 3: strcat(sec, "III"); break;
          case 4: strcat(sec, "IV"); break;
          case 5: strcat(sec, "V"); break;
          case 6: strcat(sec, "VI"); break;
          case 7: strcat(sec, "VII"); break;
          case 8: strcat(sec, "VIII"); break;
          case 9: strcat(sec, "IX"); break;
      }

}

void getNums(int num[], int ano) {
   num[0] = ano % 10;
   num[1] = ((ano % 100) - num[0]) / 10;
   num[2] = ((ano % 1000) - (num[1] + num[0])) / 100;
}

Olha como ficou: mudei la em cima, precisava colocar o numero de testes então coloquei no for. Agora esta saindo uns lixos no meio do seculo e alguns saem errado.
O que sera que ocorreu ?

Pesquisar geralmente é melhor do que perguntar!

i7 920 / DX58SO / 3x2GB DDr3 1333 OCZ XMS/ 2x500GB Seagate Barracuda 7200.12 / Saphire 4870 1gb XFX Series / OCZ 600W MODXSTREAM / Eclipse OCZ

#13 dontpanic

dontpanic
  • Membros Plenos
  • 804 posts
  • Membro desde 15/09/2009
16
Boa

Postado 21 de maio de 2010 - 23h49min

Ah... foi falha minha... esqueci que a função seria usada mais de uma vez e deixei de "resetar" a string onde guarda o século.

É só colocar essa linha no começo da função returnRoman:
sec[0] = '\0'; // primeiro caractere da string sec vai ser '0', que represente fim de string

void returnRoman(char sec[], int ano) {
   int nSec;
   int num[3];

   sec[0] = '\0';
   
   nSec = ano / 100;
   if (ano > (nSec * 100)) nSec++;
   
   getNums(num, nSec);

   // ... resto do código ...

Veja se isso corrige.

.
Favor usar as tags code ao postar código

.
Dont Panic


#14 User_G

User_G
  • Membros Plenos
  • 124 posts
  • Membro desde 31/07/2008
0
Neutra

Postado 21 de maio de 2010 - 23h59min

Hmm deu certo! Obrigado :D
Pode fechar o tópico modera.

Pesquisar geralmente é melhor do que perguntar!

i7 920 / DX58SO / 3x2GB DDr3 1333 OCZ XMS/ 2x500GB Seagate Barracuda 7200.12 / Saphire 4870 1gb XFX Series / OCZ 600W MODXSTREAM / Eclipse OCZ