Logo Hardware.com.br
Jeanks
Jeanks Tô em todas Registrado
2K Mensagens 45 Curtidas

Fatoração em C [ resolvido]

#1 Por Jeanks 12/04/2011 - 17:03
Fala moçada, tudo certo?

To precisando da ajuda de alguém aqui. Ontem tive prova e tomei um belo de um zero. Um dos exercicios era escrever um programa em C que fatora-se um numero com numeros primos e escreve na tela uma saída assim:

n = 600

fator 2 multiplicidade 3
fator 3 multiplicidade 1
fator 5 multiplicidade 2

Bom, eu não consegui escrever ontem mas hoje eu "quase" consegui, só ta dando uma falha. Segue o código:

[code=rich]
#include

int main(void) {
int i;
int n;
int primo;
int aux;
int tmp;

primo = 1;
i = 1;
printf("Digite n: ");
scanf("%d", &n);

aux = 0 ;

while ( n > 0 ) {
tmp = 2;
i = 0;
primo++;
/* nesse while ele pega o proximo n primo, aqui passa normal */
while ( tmp < primo )
{
if ( primo % tmp == 0 )
{
primo++;
tmp = 2;
}
tmp++;
}

while ( n % primo == 0 )
{
i++;
n = n / primo;
}
printf("Fator %d multiplicidade %d \n", primo, i);
}

return 0;
}

[/code]Do jeito que ele está, entra num loop infinito, da o resultado só que ele continua dividindo toda vida. Se eu mudo o While para n > 1, resolve o problema.
Mas aí que tá, nao era pra funcionar com n > 0?
já que ( usando o exemplo, depois da ultima divisão ):
n = 1
1 / 7 = 0
logo n = 0, e nisso esse saí-se do laço?


Agradeço desde já!

obs, prova com 2 questões, essa era a segunda. A primeira era para ver se um numero era palindromo. Inventei, tentei, rebolei, chorei e não consegui fazer o primeiro, tentava comparar o primeiro com o ultimo, segundo com penultimo e no final não consegui. Na saída da faculdade, conversando com o pessoal, um falou "mas você não tentou inverter o numero?" daa.png Cheguei em casa e consegui fazer, coisa mais simples mas não pensei nisso na hora. To fulo com esse zero
Jeanks
Jeanks Tô em todas Registrado
2K Mensagens 45 Curtidas
#4 Por Jeanks
13/04/2011 - 15:32
Mais ou menos, é assim:

6 /2, resto 0 , quoc 3.
Pega esse quociente e tenta dividir por 2 novamente, se não for divisível, escreve:
"fator 2 divisibilidade 1"
E parte na procura do próximo numero primo. No caso, 3.
Pega o quociente da ultima divisão ( 3 ) e divide pelo numero primo atual ( 3 ).
3 / 3 resto 0 quociente 1.

E assim até o quociente ser 0. Quando for zero, é para sair do primeiro While e terminar o programa.

Cara, valeu!! Se puder me dizer aonde ta os erros, eu agradeço muito!
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas
#5 Por tpcvasco
13/04/2011 - 18:03
Leite Estragado disse:
Do jeito que ele está, entra num loop infinito, da o resultado só que ele continua dividindo toda vida. Se eu mudo o While para n > 1, resolve o problema.
Mas aí que tá, nao era pra funcionar com n > 0?
já que ( usando o exemplo, depois da ultima divisão ):
n = 1
1 / 7 = 0
logo n = 0, e nisso esse saí-se do laço?


Não... O código certo é com n>1 mesmo.
A questão é a seguinte: vc esquece q o último número de uma fatoração não é 0, é 1. 1/7 dá resto 1, assim como 1/11, 1/13, etc... Ou seja, dá sempre 1, por isso está dando um loop infinito.
Imprima
printf("Fator %d multiplicidade %d n=%d\n", primo, i, n);
e vc irá perceber.
"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..."
Jeanks
Jeanks Tô em todas Registrado
2K Mensagens 45 Curtidas
#6 Por Jeanks
14/04/2011 - 09:23
Ha blz. Eu tava confundindo com outro algoritimo pra separar os digitos do numeros.

Valeu pela ajuda!


O código de correção que o professor passou é esse:


#include <stdio.h>
/* Recebe um número inteiro n > 0 e mostra sua decomposição em
fatores primos, calculando a multiplicidade de cada fator */
int main(void)
{
int n, p, q, primo, div;
printf("Informe n: &quot;
scanf("%d", &n);
p = 2;
while (n > 1) {
q = 0;
while (n % p == 0) {
q = q + 1;
n = n / p;
}
if (q > 0)
printf("fator %d com multiplicidade %d\n", p, q);
primo = 0;
while (! primo) {
p = p + 1;
div = 2;
primo = 1;
while (div <= p / 2 && primo) {
if (p % div == 0)
primo = 0
else
div = div + 1;
}
}
}
return 0;
}
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas
#7 Por tpcvasco
14/04/2011 - 09:51
Certo, mas pode ficar tranquilo q no fundo esse código é quase a mesma coisa q vc fez, só q de uma maneira diferente (lembre-se sempre q, na computação, haverá sempre infinitas maneiras diferentes de implementar o mesmo algoritmo).
A única coisa q ele fez de diferente foi testar se um número é primo com divisores só até a metade do valor do número. Existe uma maneira (q não lembro qual é rsrs) q define isso.

Mas se vc quiser tirar uma onda na sua turma, na próxima aula vc pode mardar pro seu professor q ainda existe uma maneira de melhorar esse algoritmo. É só vc lembrar q, com exceção do 2, nenhum outro número par é primo. Então, vc pode incrementar p de 2 em 2, não apenas de 1 em 1, e testar só os números ímpares.
"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..."
Felipe Fontes
Felipe Fonte... Veterano Registrado
1.4K Mensagens 15 Curtidas
#8 Por Felipe Fonte...
15/04/2011 - 06:32
tpcvasco disse:
Certo, mas pode ficar tranquilo q no fundo esse código é quase a mesma coisa q vc fez, só q de uma maneira diferente (lembre-se sempre q, na computação, haverá sempre infinitas maneiras diferentes de implementar o mesmo algoritmo).
A única coisa q ele fez de diferente foi testar se um número é primo com divisores só até a metade do valor do número. Existe uma maneira (q não lembro qual é rsrs) q define isso.

Mas se vc quiser tirar uma onda na sua turma, na próxima aula vc pode mardar pro seu professor q ainda existe uma maneira de melhorar esse algoritmo. É só vc lembrar q, com exceção do 2, nenhum outro número par é primo. Então, vc pode incrementar p de 2 em 2, não apenas de 1 em 1, e testar só os números ímpares.


Sem falar que não precisa testar até a metade do numero, basta até a raiz quadrada do numero. Isso diminuiria significativamente o numero de iteraçoes do algoritmo.

Uma forma de enxergar isso, sem muito rigor matemático e a seguinte:
Seja um numero A qualquer. Seja b o arrendondamento para cima da raiz quadrada de A.
Nesse casso b*b>=A. ( >= denota "maior ou igual" )
Caso A não seja primo, ele sera composto de no minimo 2 fatores (diferentes de 1 e A). f1 e f2
Suponha que no caso f1 seja maior que b. Se f1*f2=A, logo f2
Assim, pelo menos um dos fatores é menor do que a raiz quadrada do numero.
Consequentemente basta efetuar a verificação até a raiz quadrada do numero, pois se não houver um fator menor que b, não é possível que haja dois fatores maiores que b, que ao multiplicados de A.
And the heavens shall tremble

"Life can only be understood backwards, but it must be lived forwards." Soren Kierkegaard
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas
#9 Por tpcvasco
15/04/2011 - 11:00
Felipe Fontes disse:
Sem falar que não precisa testar até a metade do numero, basta até a raiz quadrada do numero.


É, isso mesmo, não é metade, é raiz quadrada. Ótima lembrança.
"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..."
Jeanks
Jeanks Tô em todas Registrado
2K Mensagens 45 Curtidas
#10 Por Jeanks
16/04/2011 - 12:01
Rapaz, só tem fera!

Gente, valeu mesmo, achei interessante a idéia da raiz quadrada e do incremento de 2 em 2. Pena que da raiz quadrada eu não posso usar ainda, o professor quer que a gente use só o stdio.h, e pra usar raiz eu precisaria da math.h, certo?
Essa prova já foi, na próxima to mais esperto...


Valeu pela força, gente.

abraços!


[edit]

Olha eu enchendo o saco de novo hehehe

Eu fiquei interessado nessas dicas e tentei implementar aqui, pelo visto deu quase certo.


#include <stdio.h>
#include <math.h>

int main(void) {
int i;
int n;
int primo;
int aux;
int tmp;

primo = 1;
i = 1;
printf("Digite n: &quot;
scanf("%d", &n);

aux = 0 ;

while ( n > 1 ) {
tmp = 2;
i = 0;
primo++;
/* nesse while ele pega o proximo n primo, aqui passa normal */
while ( tmp <= sqrt(primo))
{
if ( primo % tmp == 0 )
{
primo++;
tmp = 2;
}
tmp++;
}

while ( n % primo == 0 )
{
i++;
n = n / primo;
}
if (i)
printf("Fator %d multiplicidade %d \n", primo, i);
}

return 0;
}


Assim funcionou, só que quando tentei implementar o primo de 2 em 2, entrou num loop infinito.
Eu tentei bolar uma idéia de depois do 3 ele começar a incrementar de 2 em 2, mas dai eu teria que colocar um if dentro do while, o que geraria um processamento a mais, certo?
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal