Logo Hardware.com.br
{Nando}
{Nando} Novo Membro Registrado
12 Mensagens 0 Curtidas

Entender algoritmo em C.

#1 Por {Nando} 08/07/2008 - 15:46
Tem um algorítmo que não estou entendo. É de um livro do Jaime Evaristo "Aprendendo a Programar Programando em C"

"Tomando como base o ano de 1600, e sabendo que o primeiro dia deste ano foi um sábado, para se determinar o dia da semana de uma data dada basta se calcular o número de dias decorridos entre a data dada e o dia 01/01/1600. Como a associação do dia da semana a uma data é periódica, de período 7, o resto da divisão do número de dias referido acima por 7 indica a relação entre o dia da semana procurado e o sábado: se o resto for 1, o dia da semana é sábado; se o resto for 2 o dia da semana é domingo, e assim sucessivamente.

Para se calcular o número de dias entre uma data dada e 01/01/1600, basta multiplicar o número de anos por 365, acrescentar a quantidade de anos bissextos e o número de dias decorridos no ano corrente:"


/* Algoritmo para determinar o dia da semana entre uma data dada. */
#include <stdio.h>
main()
{
int Dia, Mes, Ano, DiasDoAno, Dias31, AnosBiss;
long int Anos, NumDias;

printf ( "Digite dia, mes e ano: \n" );
scanf ( "%d %d %d", &Dia, &Mes, &Ano );
Anos = Ano - 1600;

/* Número de mêses com 31 dias até o mes dado. */
if ( Mes < 9 )
Dias31 = Mes / 2;
else
Dias31 = ( Mes + 1 ) / 2;

/* Números de dias do ano dado, considerando fevereiro como
* tendo 30 dias. */
DiasDoAno = 30 * ( Mes - 1 ) + Dia + Dias31;

/* Retifica o número de dias de fevereiro */
if ( Mes >= 2 )
if ( ( Ano % 4 != 0 ) || ( ( Ano % 100 == 0 ) && ( Ano % 400 != 0 ) ) )
DiasDoAno = DiasDoAno - 2;
else
DiasDoAno = DiasDoAno - 1;

/* Número de anos bissextos entre o ano dado e 1600 */
AnosBiss = Ano / 4 - 400 - ( Ano / 100 - 16 ) + ( Ano / 400 - 4 ) + 1;

/* Número de dias entre a dara dada e 01/01/1600. */
if ( Ano == 1600 )
NumDias = DiasDoAno;
else
NumDias = Anos * 365 + DiasDoAno + AnosBiss;

/* Dia da semana. */
switch ( NumDias % 7 )
{
case 1 : printf ( "\n Sábado." ); break;
case 2 : printf ( "\n Domingo." ); break;
case 3 : printf ( "\n Segunda." ); break;
case 4 : printf ( "\n Terça." ); break;
case 5 : printf ( "\n Quarta." ); break;
case 6 : printf ( "\n Quinta." ); break;
case 7 : printf ( "\n Sexta." ); break;
}
}


Aqui está o código com a sintaxe colorida.
http://pastebin.com/f3a97c9c4

Bom, aprincípio não estou entendeno a parte /* Número de mêses com 31 dias até o mes dado. */ e a parte
/* Número de anos bissextos entre o ano dado e 1600 */.

Preciso entender a lógica deste programa para ir adinate no livro.

Qualquer "dialogo" sobre este algoritmo é bem vindo.
Responder
faguirre
faguirre Super Zumbi Registrado
4.2K Mensagens 1.5K Curtidas
#2 Por faguirre
08/07/2008 - 16:45
a parte do número de meses com 31 dias se deve ao fato que os meses se alternam por exemplo o mês 5 (maio) divide por 2 dá 2,5, que é arredondado para 2, o mês de agosto quebra a sequência por isso para meses acima de 8 tem que dividir por 2 e somar 1 (agosto), para o número de anos bissexto vem de uma convenção na qual o ano é bissexto se é divisível por 4 exceto se for divisível por 100 (1900 não foi bissexto) porém se for divisível por 400 é bissexto (2000 foi bissexto mesmo sendo divisível por 100), a propósito este programa erra o dia da semana (coloque 09 07 2008) você saberia dizer por que?
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas
#3 Por tpcvasco
08/07/2008 - 16:54
{Nando} disse:

Bom, aprincípio não estou entendeno a parte /* Número de mêses com 31 dias até o mes dado. */


Até Agosto, ou seja, até o mês <9, metade dos meses têm 31 dias. Se o mês atual for impar, é a parte inteira da divisão.
Faça as contas:
Até o mês 1 (JAN), tem 1 mês com 31 dias.
Até o mês 2 (FEV), tem 1 mês com 31 dias.
Até o mês 3 (MAR), tem 2 mês com 31 dias.
Até o mês 4 (ABR), tem 2 mês com 31 dias.
Até o mês 5 (MAI), tem 3 mês com 31 dias.
etc....

A partir de Agosto, deve-se adicionar 1 a essa conta.


{Nando} disse:
e a parte
/* Número de anos bissextos entre o ano dado e 1600 */.


Essa parte eu não entendi direito não, hehe tá bem complicada, mas vc pode dar uma olhada nesse tópico, q tem uma discussão bem interessante e explicadinha sobre anos bissextos:
https://www.hardware.com.br/comunidade/showthread.php?t=226116
"Milhouse: - Médicos e bombeiros são heróis.
Bart Simpson: - Olha, as casas continuam pegando fogo e as pessoas continuam doentes. Os verdadeiros heróis são os Schwarzenegger's, os Stallone's, e, em menores proporções, os Vandame's..."
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas
#6 Por tpcvasco
08/07/2008 - 18:30
jose_silva_neto disse:

Alguém compilou esse programa ? Posso ter feito alguma bobagem é claro, mas não retorna o dia correto da semana.


Relendo minha explicação, na parte /* Número de mêses com 31 dias até o mes dado. */ percebi q, qdo o mês atual é ímpar, ele faz a conta errada.
Por exemplo, se Mes = 1, Dias31 deveria ser 1, mas Dias31 = Mes/2 dá 0 como resultado. Se Mes = 3, Dias31 deveria ser 2, mas Dias31 = Mes/2 dá 1, E assim por diante.
Na parte do else isso tb está errado.

Não sei se é só esse o erro do algoritmo.
"Milhouse: - Médicos e bombeiros são heróis.
Bart Simpson: - Olha, as casas continuam pegando fogo e as pessoas continuam doentes. Os verdadeiros heróis são os Schwarzenegger's, os Stallone's, e, em menores proporções, os Vandame's..."
{Nando}
{Nando} Novo Membro Registrado
12 Mensagens 0 Curtidas
#7 Por {Nando}
08/07/2008 - 22:18
Hmm. Então a var Dias31 seria algo como "Meses31Dias" ?

E esta parte:

if ( Mes < 9 )
Dias31 = Mes / 2;

Ok, mas se o mês for o mês um ? Como que fica a situação ?

E realmente, eu já havia percebido que o programa retorna resultado errado
as vêzes. Aos poucos vou tentar resolver isto...

E aproveitando, eu estou conseguindo entender legal a sintaxe de C, mas estou penando
nos algoritmos/lógica. Gostaria que me indicassem algúm material/apostila/livro/site
que me ajudasse com lógica. Talvêz até lógica associada com alguma linguagem (qulaquer uma), pois acredtito ser mais legal aplicar lógica já direto em algúma lang do que em pseudocódigo.

Bom, vou dar mais uma estudada. Logo posto mais alguma coisa. Deixem eu
ir me situando aqui big_green.png

Muito obrigado pelos replays de todos.
jose_silva_neto
jose_silva_n... General de Pijama Registrado
4.6K Mensagens 98 Curtidas
#8 Por jose_silva_n...
09/07/2008 - 02:50
Bom dia,


/* Algoritmo para determinar o dia da semana entre uma data dada. */

#include <stdio.h>

int main(int argc, char **argv)
{
int Dia, Mes, Ano, DiasDoAno, Dias31, AnosBiss;
int Meses31[12] = {1,1,2,2,3,3,4,5,5,6,6,7};
long int Anos, NumDias;

printf ( "Digite dia, mes e ano: \n" );
scanf ( "%d %d %d", &Dia, &Mes, &Ano );
printf("\n&quot;
Anos = Ano - 1600;

/* Número de mêses com 31 dias até o mes dado. */
Dias31 = Meses31[Mes - 1];



/* Números de dias do ano dado, considerando fevereiro como
* tendo 30 dias. */
if ( Mes >= 2 )
DiasDoAno = 30 * ( Mes - 1 ) + Dia + Dias31;
else
DiasDoAno = 30 * ( Mes - 1 ) + Dia;

/* Retifica o número de dias de fevereiro */
if ( Mes >= 2 )
{
if ( ( Ano % 4 != 0 ) || ( ( Ano % 100 == 0 ) && ( Ano % 400 != 0 ) ) )
DiasDoAno -= 2;
}
else
--DiasDoAno;


/* Número de anos bissextos entre o ano dado e 1600 */
AnosBiss = Ano / 4 - 400 - ( Ano / 100 - 16 ) + ( Ano / 400 - 4 ) + 1;


/* Número de dias entre a data dada e 01/01/1600. */
if ( Ano == 1600 )
NumDias = DiasDoAno;
else
NumDias = Anos * 365 + DiasDoAno + AnosBiss;

/* Dia da semana. */
switch ( NumDias % 7 )
{
case 1 :
printf ( "Sábado. \n" );
break;

case 2 :
printf ( "Domingo. \n" );
break;

case 3 :
printf ( "Segunda. \n" );
break;

case 4 :
printf ( "Terça. \n" );
break;

case 5 :
printf ( "Quarta. \n" );
break;

case 6 :
printf ( "Quinta. \n" );
break;

case 0 :
printf ( "Sexta. \n" );
break;
}
return(0);
}

Mudei praticamente nada, e como não estudei a teoria dos cálculos (anos bissextos e cia), é claro que ainda não funciona. Os dados que o autor passa no livro seriam bem vindos.


Fique com Deus
mcv
mcv Veterano Registrado
1.2K Mensagens 40 Curtidas
#9 Por mcv
09/07/2008 - 07:04
Mudei bastante, mas tá funcionando. A lógica quanto mais simples melhor.

/* Algoritmo para determinar o dia da semana entre uma data dada. */

#include <stdio.h>

int main(int argc, char **argv)
{
int Dia, Mes, Ano, DiasDoAno, Dias31, AnosBiss;
int Meses[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
long int Anos = 0, NumDias = 0;

printf ( "Digite dia, mes e ano: \n" );
scanf ( "%d %d %d", &Dia, &Mes, &Ano );
printf("\n&quot;
Anos = Ano - 1600;

NumDias = Anos*365;

int i = 0;
for( i = 0; i < Mes - 1; i++)
NumDias += Meses[i];

NumDias += Dia;

NumDias += Anos / 4 - Anos / 100 + Anos / 400 + 1;

// Dá pra fazer essa parte mais elegante.
NumDias += (!(Ano%4) && (!(Ano%400) || (Ano%100)) && (Mes <= 2) )? -1 : 0;

/* Dia da semana. */
switch ( NumDias % 7 )
{
case 1 :
printf ( "Sábado. \n" );
break;

case 2 :
printf ( "Domingo. \n" );
break;

case 3 :
printf ( "Segunda. \n" );
break;

case 4 :
printf ( "Terça. \n" );
break;

case 5 :
printf ( "Quarta. \n" );
break;

case 6 :
printf ( "Quinta. \n" );
break;

case 0 :
printf ( "Sexta. \n" );
break;
}
return(0);
}

Responder Tópico
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal