Ir ao conteúdo
  • Cadastre-se
jujubasdeuva

C Contador de numeros primos com recursividade

Recommended Posts

Boa tarde,

 

     Tenho um exercício para fazer cujo enunciado é: "Construa um programa em C, que solicite ao usuário informar um número qualquer e o sistema deve calcular todos os números primos até o número informado. Deve ser utilizada uma função recursiva em lugar de uma estrutura de repetição para calcular os números primos."

     Fiz um código que mostra se determinado numero é primo ou não para depois tentar fazer o que o enunciado do exercicio diz, porém este código não está funcionando, gostaria de um auxílio pois não sei o que está errado, sou nova nessa área e não sei se minha estrutura do código está certa ou se a lógica está errada...

#include <stdio.h>
#include <stdlib.h>
    
int main(int tmp1, float tmp2, int numeros_primos) {
    printf("Digite um numero inteiro positivo:\n")
    scanf("%", tmp1)
    
    tmp2=tmp1
    
    if (tmp1%2==0 || tmp1 == 0) {
        printf("O numero nao e primo")
    }
    else {
        printf("O numero eh:\n", numeros_primos)
    }
    
    return 0;
}

int numeros_primos (int tmp1, float tmp2, int i) {
    while i<tmp1 {
        i++;
    }
        if tmp1%i==0 {
            return numeros_primos
        }
        else {
            return (1+numeros_primos)
        }
    return 0;
}

 

Editado por Simon Viegas
Ao postar um código, favor utilizar a tag CODE, botao <>

Compartilhar este post


Link para o post
Compartilhar em outros sites

:tw_bawling: '''Não basta apenas ser ou não ser divisível por 2 para definir que um número não é primo ou é primo!

 

Números Primos são divisíveis exatos, apenas por si.

 Ex.: 9 / 2 não é exato

        9 / 3 sim é exato

 

Portanto,  9 não é primo!

Importante perceber que 3 é menor que a metade de 9 isso é uma dica importante, pois qualquer número não primo tem um ou mais divisores menor que sua metade inteira.

 

Tente outra vez...

~~ / ~~

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá a todos.

 

 

@AnsiC, alguns pontos:

 

Sobre:

2 horas atrás, AnsiC disse:

:tw_bawling: '''Não basta apenas ser ou não ser divisível por 2 para definir que um número não é primo ou é primo!

 

Creio que esteja se referindo a esse trecho:

4 horas atrás, jujubasdeuva disse:

    if (tmp1%2==0 || tmp1 == 0) {
        printf("O numero nao e primo")
    }

 

Mas acho que @jujubasdeuva está tentando eliminar "uma parte do problema, no caso praticamente a metade das possibilidades", ou seja, "se o número for par" ou "o número for 0", ele de fato não pode ser primo! Logo, nem precisa verificar. A lógica está certa*.

 

Por que o *... ocorre que a premissa é FALSA.... nem todo número par não é primo, pois existe o número 2!, ou seja, 2 é par, e é primo também! Mas é só um detalhe...

 

 

 

Sobre:

2 horas atrás, AnsiC disse:

Números Primos são divisíveis exatos, apenas por si.

Por si e por 1 também, ou seja, todo número primo tem exatamente 2 divisores naturais distintos. Se tem mais de 2 (como o citado 9, ou 21, 0, 34 etc, assim como todo número par maior que 2) ; ou tem menos de 2 divisores naturais (como 1) NÃO É PRIMO.

 

 

 

@jujubasdeuva, sobre o enunciado.

4 horas atrás, jujubasdeuva disse:

     Tenho um exercício para fazer cujo enunciado é: "Construa um programa em C, que solicite ao usuário informar um número qualquer e o sistema deve calcular todos os números primos até o número informado. Deve ser utilizada uma função recursiva em lugar de uma estrutura de repetição para calcular os números primos."

 

A minha sugestão seria justamente essa:

4 horas atrás, jujubasdeuva disse:

     Fiz um código que mostra se determinado numero é primo ou não para depois tentar fazer o que o enunciado do exercício diz[...]

Ou seja, fazer o programa por partes.. primeiro precisa saber identificar um primo... achar "n" primos é moleza.

 

Então primeira coisa que precisa fazer é dar uma boa revisada sobre recursividade... mas pela forma que você implementou, talvez tenha que revisar antes sobre funções comuns (não recursivas mesmo). Veja:

 

Você definiu a função assim:

4 horas atrás, jujubasdeuva disse:

int numeros_primos (int tmp1, float tmp2, int i) {

 

Mas está tentando invocar ela assim:

4 horas atrás, jujubasdeuva disse:

    else {
        printf("O numero eh:\n", numeros_primos)
    }

 

Está "pecando" numa parte trivial para o uso de funções... ou seja, se a função tem 3 parâmetros, necessariamente teria que invocar a função com os tais 3 parâmetros.

 

 

 

CONCLUSÃO

Eu particularmente não vejo a recursividade como algo trivial... não é nada de outro mundo, mas é necessário um certo nível de amadurecimento... ou seja, se nem conseguiu invocar uma função corretamente, como seria capaz de idealizar uma recursividade? é colocar a carroça na frente dos bois. :)

 

 

Para facilitar e dar um empurrão, segue uma tentativa revisão:

 

Então, como já citado, para saber se um número é primo ou não, é necessário basicamente saber "quantos divisores naturais ele tem", ou seja, se tiver exatamente 2 número divisores, ele é primo. Caso contrário, adivinha?

 

Pronto... logo, a atual base, é encontrar quantos divisores um número tem.

 

Daí, faça uma função (esqueça a recursividade por enquanto) para calcular quantos divisores um número tem. A base do programa seria essa:

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

int numDivisores(int numero,int x);

int main() {
    setlocale(LC_ALL, "Portuguese");
    int n;
    printf("Digite um numero POSITIVO: \n");
    scanf(" %d",&n);
    printf("%d tem %d divisores",n,qtdDivisores(n,1));
}

/*
 FUNÇÃO QUE RETONA A QUANTIDADE DE DIVISORES NATURAIS QUE UM NÚMERO NATURAL TEM  
 */
int numDivisores(int numero,int x) {

    //aqui você implementa o método não recursivo (usando o velho for mesmo)

}

OBS.: Esse algoritmo só está tratando de número maiores que 0. Depois isso também pode ser verificado.

 

 

Ou seja, se eu digitar 12, a função qtdDivisores  (quantidade de divisores) terá que me retornar 6!!! E deve aparecer na tela algo como:
 

Citação

Digite um número positivo:
12
12 tem 6 divisores

 

 

Daí, após resolver assim, te passamos como "transformar um laço de repetição com for, para uma função recursiva".

 

 

No aguardo.

 

Editado por Simon Viegas
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
6 horas atrás, Simon Viegas disse:

Mas acho que @jujubasdeuva está tentando eliminar "uma parte do problema, no caso praticamente a metade das possibilidades", ou seja, "se o número for par" ou "o número for 0", ele de fato não pode ser primo! Logo, nem precisa verificar. A lógica está certa*.

Nenhum momento disse que estava errada!  Peço ate desculpa, @jujubasdeuva, se foi mal entendido.

 

@Simon Viegas  

6 horas atrás, Simon Viegas disse:

Por si e por 1 também

Vixxx :tw_bawling:  Pense... qualquer divisão deve implicar em separa por parte, dividir por 1 não implica em partes ou separação, por isso 1 é neutro. Mais não foi assim que aprendemos... 

 

Da nova Matemática temos

Citação

" ( Em matemática, um elemento neutro (ou identidade), é qualquer elemento cuja utilização numa operação binária bem definida não causa alteração )"

Sem causa, efeito ou importância diz neutro ... Sendo crítico dividir por 1 não é critério de primalidade. Mas foi assim que o professor te ensino, e eu entendo. De fato o único critério de primalidade é

9 horas atrás, AnsiC disse:

Números Primos são divisíveis exatos, apenas por si.

 

Editado por AnsiC

Compartilhar este post


Link para o post
Compartilhar em outros sites
6 horas atrás, Simon Viegas disse:

int n;

printf("Digite um numero POSITIVO: \n");

scanf(" %d",&n);

Existe números inteiros primos muito maior que int

Ex.: 44601021791

Logo int não é o bastante para que se Digite um numero Positivo sem bugs.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Recomendo que antes de entrar em áreas mais complicadas, como o caso das funções recursivas, primeiramente aprenda a lidar com as funções básicas da programação em , como o caso do scanf, olha como você o aborda em seu programa:

scanf("%", tmp1)

quando o uso correto seria:

scanf("%d", &tmp1);

 

o mesmo para a função while, olha como você usa:

  while i<tmp1

o correto seria:

  while(i < tmp1){}

o mesmo para o if tambem, e lembre-se de usar o ; no final dos comandos.

 

 

Boa sorte!

Editado por Simon Viegas
Remoção de "código pronto", pois quebra a linha de raciocínio definida inicialmente. (o usuário precisaria tentar fazer sem recursividade, para após tentarmos explicar como ficaria com recursividade). Att
  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá.

 

@AnsiC, sobre:

8 horas atrás, AnsiC disse:

@Simon Viegas  

Vixxx :tw_bawling:  Pense... qualquer divisão deve implicar em separa por parte, dividir por 1 não implica em partes ou separação, por isso 1 é neutro. Mais não foi assim que aprendemos...

 

Bacana... entendi essa lógica, mas essa definição de "divisão" é matemática ou está na etimologia (ou outra coisa) do termo "divisão"?

 

Para contextualizar tomemos como exemplo a "etimologia" do termo átomo... seria basicamente "não divisível" ou "indivisível", correto?. Mas no "âmbito da química/física" sabemos que o átomo é divisível, e inclusive multas partes.... A definição do termo não necessariamente tem implicações objetivas sobre as propriedades em todo ramo, ou seja, assim como podemos afirmar que o átomo é divisível no mundo real, mesmo com esse nome. Poderíamos dizer que "um é divisor de um número", mesmo com esse nome. Teríamos que ver como se aplica no mundo da matemática essa definição.

 

Você poderia citar algumas fontes para eu tentar entender melhor como funciona essa questão de "o um deixar de ser um divisor"?

 

 

 

@jujubasdeuva e @AnsiC, sobre:

15 horas atrás, AnsiC disse:

Números Primos são divisíveis exatos, apenas por si.

 

Então, apesar de coerente pelo o explicado por @AnsiC, sugiro que para o contexto, a definição de primo para o algoritmo siga o "convencional", ou seja, para retirar o um da conta seria necessário PROVAR formalmente o motivo...  Já que seria uma definição nova OU que é divergente do senso comum... (seria uma dor de cabeça a mais, rs). Faz da forma padrão e pronto. Caso entenda que o 1 também não é divisor, mesmo assim use-o, pois é o suposto padrão... ai a depender, cria um outro algoritmo separado retirando o 1 da conta.

 

Veja o que diz o Wikipedia:

Citação

Já um número natural primo tem unicamente dois divisores naturais distintos: o número um e ele mesmo.
Fonte: https://pt.wikipedia.org/wiki/Número_primo

 

Nesse contexto.. segue a manada.

 

 

 

@AnsiC, sobre:

7 horas atrás, AnsiC disse:

Existe números inteiros primos muito maior que int

Ex.: 44601021791

Logo int não é o bastante para que se Digite um numero Positivo sem bugs.

 

No Wikipedia também tem:

Citação

Existem infinitos números primos, como demonstrado por Euclides por volta de 300 a.C.

 

Ou seja, se fôssemos só trata os número positivos, seria necessário utilizar um "tipo numérico" que suportaria de 1 até o infinito. Acho que o int está de bom tamanho para o contexto. Creio que o foco do problema está no uso da recursividade... número primos é só um pretexto.

 

 

 

@Gabriel Custodio, sobre:

7 horas atrás, Gabriel Custodio disse:

Recomendo que antes de entrar em áreas mais complicadas, como o caso das funções recursivas, primeiramente aprenda a lidar com as funções básicas da programação[...]

Eu também vejo assim.

 

***

 

Então, @jujubasdeuva, sugiro que tente implementar o código que citei lá na minha primeira postagem. Ai "fazendo a sua parte", mas pra frente, poderíamos te dar dicas de como implementar com uma função recursiva e explicar mais ou menos como funciona. Como disse, acho que a recursividade não é trivial... mas tendo uma boa base anterior, conseguirá entender! (mas antes tem que demonstrar que já entende o básico).

 

 

RESUMINDO:

Resolva o código como sugerido:
 

14 horas atrás, Simon Viegas disse:

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

int numDivisores(int numero,int x);

int main() {
    setlocale(LC_ALL, "Portuguese");
    int n;
    printf("Digite um numero POSITIVO: \n");
    scanf(" %d",&n);
    printf("%d tem %d divisores",n,qtdDivisores(n,1));
}

/*
 FUNÇÃO QUE RETONA A QUANTIDADE DE DIVISORES NATURAIS QUE UM NÚMERO NATURAL TEM  
 */
int numDivisores(int numero,int x) {

    //aqui você implementa o método não recursivo (usando o velho for mesmo)

}

 

Que depois explicamos como transformar em uma função recursiva, ao mesmo tempo que tentamos explicar um funcionamento geral de uma função recursiva.

 

 

Essa é minha sugestão.

 

 

No aguardo.

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, Simon Viegas disse:

Para contextualizar tomemos como exemplo a "etimologia" do termo átomo... seria basicamente "não divisível" ou "indivisível", correto?. Mas no "âmbito da química/física" sabemos que o átomo é divisível, e inclusive multas partes.... A definição do termo não necessariamente tem implicações objetivas sobre as propriedades em todo ramo, ou seja, assim como podemos afirmar que o átomo é divisível no mundo real, mesmo com esse nome. Poderíamos dizer que "um é divisor de um número", mesmo com esse nome. Teríamos que ver como se aplica no mundo da matemática essa definição.

:tw_confounded:Duvido muito que algum matemático venha a dizer que 1 não é o elemento neutro das operações de multiplicação e divisão. Inclusive deixo aqui o desafio.

 

1 hora atrás, Simon Viegas disse:

Veja o que diz o Wikipedia:

Citação

Já um número natural primo tem unicamente dois divisores naturais distintos: o número um e ele mesmo.
Fonte: https://pt.wikipedia.org/wiki/Número_primo

 

Nesse contexto.. segue a manada.

Isso é um enlatado com muitos anos de idade, Não existe qualquer implicação lógica dizer que um primo é divisível por 1 já que todo número é. Na divisão e na multiplicação 1 é seu elemento neutro. Quantas vezes temos 1 em 11 e em 10 é a resposta 11 e 10. Qual seria o primo nessa situação???  Se isso faz alguma diferença para primalidade, quero provas;

 

1 hora atrás, Simon Viegas disse:

Bacana... entendi essa lógica, mas essa definição de "divisão" é matemática ou está na etimologia (ou outra coisa) do termo "divisão"?

é outra coisa! Ser crítico.

Editado por AnsiC

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Segue o código que fiz baseado no exemplo que mostra os numeros divisiveis pelo numero digitado.

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

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int numeroDivisores(int numero){
	int i;
	
	for (i=1; i<numero; i++) {
		if ((numero % i)==0) printf("Divisivel por %i \n", i);				
	}
	return 0;
}

int main() {
	int numero;
	
	printf("Digite um numero inteiro positivo\n");
	scanf("%i", &numero);

	printf(numeroDivisores(numero));
	return 0;
}

 

Editado por jujubasdeuva
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
3 horas atrás, Simon Viegas disse:

convencional

Olá

 

@jujubasdeuva, sobre:

2 horas atrás, jujubasdeuva disse:

Segue o código que fiz baseado no exemplo que mostra os numeros divisiveis pelo numero digitado.

 

Seu código está compilando? aqui da o seguinte erro:

C:\Users\simon.viegas\OneDrive\SLT-001446\_My Portable\Dev++\_FONTES\Untitled1.cpp	In function 'int main()':
21  31 C:\...\_My Portable\Dev++\_FONTES\Untitled1.cpp	[Error] invalid conversion from 'int' to 'const char*' [-fpermissive]
1   0  C:\...\_My Portable\Dev++\_FONTES\Untitled1.cpp	In file included from C:\...\_My Portable\Dev++\_FONTES\Untitled1.cpp
378 15 C:\...\_My Portable\Dev++\MinGW64\x86_64-w64-mingw32\include\stdio.h	[Note] initializing argument 1 of 'int printf(const char*, ...)'

Ou seja, dá dando erro no comando:

2 horas atrás, jujubasdeuva disse:

	printf(numeroDivisores(numero));

 

Aqui estou utilizando o Dev++5.11. Para corrigir, deixei assim:

	printf("%d ",numeroDivisores(numero));

 

Pronto.. agora o programa está compilando e rodando aqui.

 

Testei inserindo o número 9, deu:

Digite um numero inteiro positivo
9
Divisivel por 1
Divisivel por 3
 0
--------------------------------
Process exited after 0.6359 seconds with return value 0
Pressione qualquer tecla para continuar. . .

Ou seja, não é o que sugeri. Eu precisava (preciso) que fosse retornado "a quantidade de divisores de um número", ai você está tentando "mostrar os divisores de um número". São coisas distintas. :)

 

obs. 1: faltou o próprio número, ou seja, 9 também é divisível por 9.

obs. 2: ai entra também o que está sendo analisado no tópico: se o 1 entra ou não na conta. (como citado, por hora deixe assim, considere o 1 como sendo um divisor, pois teoricamente é a definição popular)

 

Por enquanto nada muda:

3 horas atrás, Simon Viegas disse:

Resolva o código como sugerido:
 

17 horas atrás, Simon Viegas disse:


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

int numDivisores(int numero,int x);

int main() {
    setlocale(LC_ALL, "Portuguese");
    int n;
    printf("Digite um numero POSITIVO: \n");
    scanf(" %d",&n);
    printf("%d tem %d divisores",n,qtdDivisores(n,1));
}

/*
 FUNÇÃO QUE RETONA A QUANTIDADE DE DIVISORES NATURAIS QUE UM NÚMERO NATURAL TEM  
 */
int numDivisores(int numero,int x) {

    //aqui você implementa o método não recursivo (usando o velho for mesmo)

}

 

Que depois explicamos como transformar em uma função recursiva, ao mesmo tempo que tentamos explicar um funcionamento geral de uma função recursiva.

 

 

RESUMINDO:

Apenas implemente a função acima. Caso tenha dúvidas, é só indicar onde. Caso não queira seguir a minha linha de raciocínio, informe que também podemos partir para outra.

 

 

 

 

 

 

 

@jujubasdeuva, sobre:

2 horas atrás, AnsiC disse:

Duvido muito que algum matemático venha a dizer que 1 não é o elemento neutro das operações de multiplicação e divisão. Inclusive deixo aqui o desafio.

Também duvidaria. Isso não foi contestado.

 

A questão não é se 1 (um) é neutro ou não (concordamos que é), mas sim, se ser neutro é argumento para tirar o mérito de ser divisor! ou seja, eu estou "seguindo o senso comum" dizendo que  "um é o elemento neutro da divisão E 1 é um divisor!". Logo, eu corroboro com o Wikipedia.

 

 

 

Sobre:

2 horas atrás, AnsiC disse:

Isso é um enlatado com muitos anos de idade

 

Se o que você propõe estiver correto, eu concordarei com esse argumento.

 

 

 

Sobre:

2 horas atrás, AnsiC disse:

Não existe qualquer implicação lógica dizer que um primo é divisível por 1 já que todo número é.

Pelo contrário, ao dizer que «se todo número é» você estará negando a tua própria premissa... tudo bem, deu para entender o que você quis dizer... Então, pelo que observei da frase, você estaria analisando como um programador, ou seja, tentando diminuir o custo de processamento... nesse sentido, independente da obviedade da não necessidade prática de verificar se é divisível por 1, essa questão é "imposta" pela premissa da definição de "primariedade". Segundo a comunidade entende (sendo errada ou não devido a tal argumento sobre o que é ser um divisor), um primo está definido como tendo exatamente 2 divisores naturais: «o número um e ele mesmo», ou seja, ser custoso verificar se é divisível por 1 ou não, não tira o mérito de 1 também ser um divisor! Está lá na "regra". Ai entra a tal questão do ônus que complementarei mais abaixo.

 

 

Sobre:

2 horas atrás, AnsiC disse:

Na divisão e na multiplicação 1 é seu elemento neutro. Quantas vezes temos 1 em 11 e em 10 é a resposta 11 e 10. Qual seria o primo nessa situação???

Uma coisa não tem a ver com a outra. A definição que que tomo como exemplo é:

 

2 horas atrás, AnsiC disse:
Citação

Já um número natural primo tem unicamente dois divisores naturais distintos: o número um e ele mesmo.
Fonte: https://pt.wikipedia.org/wiki/Número_primo

Ou seja, não basta ser divisível por um, tem que também apenas ter mais um divisor, que seria ele mesmo. No final, tem que ter apenas dois divisores naturais.

 

 

 

Sobre:

2 horas atrás, AnsiC disse:

Se isso faz alguma diferença para primalidade, quero provas;

Lógico que faz. Depende no que você se refere a fazer diferença. Na matemática o que vale é a definição. Nela consta que são 2 divisores. Caso o problema seja:

2 horas atrás, AnsiC disse:

Isso é um enlatado

O ônus da prova cabe a você ou a quem entende que a definição está errada ou defasada!!!

 

Fazendo uma analogia... imagine ai toda uma comunidade definindo que a Terra é cento do "Sistema Solar". Ai vem Galileu Galilei e diz que não. O Sol que é. Quem supostamente está certo? Galileu, correto? mas independente disso, de quem seria o ônus da prova? Entende? quem está indo "contra a maré" é você! Essa definição já teve seu ônus de provas ou está sendo entendido que teve. A comunidade aceitava que a Terra é p centro, logo ela é o centro para o contexto. É o que entendemos como válido. (o Geocentrismo era aceitado como válido, coube os contras mudarem isso)

 

Ainda em analogias... tá, imagine que toda uma comunidade definindo que a Terra é "esférica" (geoide). Ai vem um renomado e diz que não. A Terra é plana. Quem supostamente está certo? A comunidade, correto? mas independente disso, de quem seria o ônus da prova? Continua sendo de quem está indo contra a maré... as provas que corroboram para o quê entendemos já estão ai... caso contrário, não estaríamos entendendo assim! (A terra "esférica" é aceitada como válida, cabe aos contras mudarem isso)

 

Durante séculos, a humanidade tem se esforçado para continuar aceitando a existência de deuses... cabe a mim e outro ateus tentarmos mudar isso, ou seja, as definições estão aí, quem vai contra é que tem que dar os seus pulos, rs. (claro que filosoficamente não é assim, estou me referindo em termos práticos)

 

 


Em fim, eu entendo seu argumento, mas pelo que vemos, vai de contra ao sendo comum... daí, caberia a você demonstrar as evidências... como demonstrando fontes ou até mesmo, se for o caso, até editar o Wikepedia etc.

 

 

RESUMINDO:

Estou levantando que devemos nos basear pelas definições. Elas sendo certas ou erradas. Caso a definição esteja errada, apontar e demonstrar onde está o erro e corrigir elas antes de poder por em prática (por isso continuo sugerindo que o exercício de primos use o 1 ainda). Não usar o 1 como referência vai chegar exatamente no mesmo resultado, mas para a lógica, não importa só o fim, mas sim principalmente o meio (caminho para o fim). Se está definido que é 1 e ele mesmo, não usar é um erro de lógica!

 

 

Editado por Simon Viegas

Compartilhar este post


Link para o post
Compartilhar em outros sites
"Construa um programa em C, que solicite ao usuário informar um número 
qualquer e o sistema deve calcular todos os números primos até o número 
informado. Deve ser utilizada uma função recursiva em lugar de uma 
estrutura de repetição para calcular os números primos."

@jujubasdeuva

Vamos revisar o enunciado dividido (em partes)!

 

1#

Construa um programa em C, que solicite ao usuário informar um número 
qualquer[...]
int numero;
	
	printf("Digite um numero inteiro positivo\n");
	scanf("%i", &numero);

Sintaxe está correta, lógica também, porém quando se fala de um inteiro positivo e só, então esse valor pode ser qualquer um inclusive muitos maiores que um int. Por isso existe modificadores de tipos para lhe ajuda a elevar um pouco mais essa gama de valores: Aqui os importante é long e unsigned.

long long unsigned int numero;

	printf( "Digite um numero inteiro positivo\n" );
	scanf( "%llu", &numero );

Por que isso é importante? Porque elevar a gama de possibilidades para um inteiro positivo igual a 18446744073709551615 atendendo as necessidades do enunciado e acrescenta mais conhecimento da linguagem.

Existem aqui elementos novos dos quais quem aprendeu C tem que saber, ou gerará certos questionamentos. Mais uma vez, lógica está correta! Porém aqui me vale mais discutir a linguagem do que lógica. Daí o motivo de chamar atenção a esse ponto.

 

2#

 deve calcular todos os números primos até o número 
informado.[...]

Precisamos de função que nos dica se o número é primo.

int numeroDivisores(int numero){
	int i;
	
	for (i=1; i<numero; i++) {
		if ((numero % i)==0) printf("Divisivel por %i \n", i);				
	}
	return 0;
}

Aqui temos o problema com relação ao tamanho do número inteiro, que já mencionei, porém lógica esta correta! 

Apenas que você esqueceu o critérios/critério de primalidade. Ao dividir por 1 todo numero terá resto 0. Com alguns correções fica assim:

void numeroDivisores(long long unsigned int numero){
  long long unsigned int i;
  char eh_primo = 1;

	if( 2 > numero ) eh_primo = 0;

	for (i = 2; i < numero; i++) {
		if ((numero % i)==0) eh_primo = 0;

	}
	if( eh_primo )printf("%llu", numero );
	return;
}

As mudanças foram estas; Ao invés de imprimir quando não é primo dentro do loop nos modificamos esse momento do algoritmo para fora quando acaba os teste; Também adicionamos um IF: para o único par primo o 2. E resolveu! 

Agora temos uma função que determina se o numero e primo ou não é.

 

Realize teste na função e verifique isso para todos os primos e não que poderes. Caso não encontre erro, sua próxima etapa é usar essa função em uma outra nova função, porém em que o valor de um outronumero incrementa até numero a cada resposta, ou seja, o teste ocorrerá em outronumero ... recursiva. Lembrete a nova função não tem loop o loop é a recursividade!

 

Tenta outra vez!

adicionado 1 minuto depois
1 hora atrás, Simon Viegas disse:

Estou levantando que devemos nos basear pelas definições. Elas sendo certas ou erradas. Caso a definição esteja errada, apontar e demonstrar onde está o erro e corrigir elas antes de poder por em prática (por isso continuo sugerindo que o exercício de primos use o 1 ainda). Não usar o 1 como referência vai chegar exatamente no mesmo resultado, mas para a lógica, não importa só o fim, mas sim principalmente o meio (caminho para o fim). Se está definido que é 1 e ele mesmo, não usar é um erro de lógica!

Já apontei! 1 é o elemento NEUTROOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!

adicionado 49 minutos depois
1 hora atrás, Simon Viegas disse:

Ou seja, não basta ser divisível por um, tem que também apenas ter mais um divisor, que seria ele mesmo. No final, tem que ter apenas dois divisores naturais.

Se um divide, mais como de fato qualquer numero dividido por um é ele mesmo, essa operação é NEUTRA:D

 

Editado por AnsiC
Lembrete

Compartilhar este post


Link para o post
Compartilhar em outros sites

@AnsiC, sobre:

1#

13 minutos atrás, AnsiC disse:

Aqui temos o problema com relação ao tamanho do número inteiro, que já mencionei, porém lógica esta correta!

A lógica não está correta, pois está tentando "mostrar os divisores" (exibir os divisores do número repassado), onde o que se foi pedindo é para "retornar a quantidade de divisores" (dizer quantos divisores o número tem). São lógicas distintas!

 

 

 

Sobre:
2#

16 minutos atrás, AnsiC disse:

Apenas que você esqueceu o critérios/critério de primalidade. Ao dividir por 1 todo numero terá resto 0.

 

Você confirmou o que eu disse:

53 minutos atrás, Simon Viegas disse:

deu para entender o que você quis dizer... Então, pelo que observei da frase, você estaria analisando como um programador, ou seja, tentando diminuir o custo de processamento... nesse sentido, independente da obviedade da não necessidade prática de verificar se é divisível por 1, essa questão é "imposta" pela premissa da definição de "primariedade". Segundo a comunidade entende (sendo errada ou não devido a tal argumento sobre o que é ser um divisor), um primo está definido como tendo exatamente 2 divisores naturais: «o número um e ele mesmo», ou seja, ser custoso verificar se é divisível por 1 ou não, não tira o mérito de 1 também ser um divisor! Está lá na "regra". Ai entra a tal questão do ônus que complementarei mais abaixo.

 

Ou seja, estaria confundido "perda de tempo" com "não necessidade.

 

 

 

Sobre:

3#

18 minutos atrás, AnsiC disse:

As mudanças foram estas; Ao invés de imprimir quando não é primo dentro do loop nos modificamos esse momento do algoritmo para fora quando acaba os teste; Também adicionamos um IF: para o único par primo o 2. E resolveu!

Logo a lógica foi alterada... o que corrobora o 1#, ou seja, além de ser outra lógica, ela foi alterada para uma terceira.

 

 

 

Sobre:

4#

21 minutos atrás, AnsiC disse:

Já apontei! 1 é o elemento NEUTROOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!

Ué, e já contra-argumentei:
 

58 minutos atrás, Simon Viegas disse:

A questão não é se 1 (um) é neutro ou não (concordamos que é), mas sim, se ser neutro é argumento para tirar o mérito de ser divisor! ou seja, eu estou "seguindo o senso comum" dizendo que  "um é o elemento neutro da divisão E 1 é um divisor!". Logo, eu corroboro com o Wikipedia.

 

45 minutos atrás, AnsiC disse:

Tenta outra vez!

#VivaRaul

 

 

 

Sobre

5#

24 minutos atrás, AnsiC disse:

void numeroDivisores(long long unsigned int numero){
  long long unsigned int i;
  char eh_primo = 1;

	if( 2 > numero ) eh_primo = 0;

	for (i = 2; i < numero; i++) {
		if ((numero % i)==0) eh_primo = 0;

	}
	if( eh_primo )printf("%llu", numero );
	return;
}

 

Veja, aí cai no quero quero dizer sobre "definições"... o nome da função está "numeroDivisores"... mas dentro está "se o número for primo, imprima o número na tela". Ué, João é João, Maria é Maria...

 

O que foi proposto foi:

18 horas atrás, Simon Viegas disse:

encontrar quantos divisores um número tem.

Se quer seguir a definição, ok. O que não pode é supostamente querer seguir (já que está chamado o método de "numeroDivores"), e acabar fazer uma coisa completamente diferente. Em nenhum momento o algoritmo está "retornando o número de divisores".

 

Se vai seguir outra lógica, mude então a definição, ou seja, seria algo como:

Citação

@jujubasdeuva, você não precisa descobrir o número de divisores, apenas verifique se existe algum divisor entre 2 e o antecessor do número. Se não existir, então imprima o número na tela. Esse número na tela será primo!

Entende o que quero dizer?

 

Seu código acima entrega uma resposta útil/correta, mas não segue a lógica da definição inicial... é "um certo para outro contexto". Como já citei em algum momento aqui no Fórum: "peço um cachorro quente, mas o vendedor me entrega um delicioso X-Tudo", ou seja, PRIMEIRO se muda a definição, para depois desenvolver em relação a esta.

 

 

A nomenclatura da função poderia fica assim:

void imprimirSeForPrimo (long long unsigned int numero) {

}

"Um método que recebe um 'inteiro' e se ele for primo, a função imprime ele na tela.

 

É completamente diferente de:
 

19 horas atrás, Simon Viegas disse:

/*
 FUNÇÃO QUE RETONA A QUANTIDADE DE DIVISORES NATURAIS QUE UM NÚMERO NATURAL TEM
*/

Veja que até comentário tinha... ou seja, ou faz assim, ou MUDA a definição antes. "ah! não quero fazer assim". beleza! Não estou obrigando, apenas sugerindo!

 

Da mesma forma ratifico: o 1 também deve ser verificado para paridade! caso contrário, crie uma nova definição para paridade, ou demonstre qual é a definição correta. (que eu estou no aguardo, já que faz todo sentido biológico, mas que ainda precisa ser "provado" - como citado nas analogias da outra postagem)

 

***

 

 

No aguardo.

  • Haha 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Simon Viegas tudo errado!

 

adicionado 1 minuto depois
1 hora atrás, Simon Viegas disse:

A lógica não está correta, pois está tentando "mostrar os divisores" (exibir os divisores do número repassado), onde o que se foi pedindo é para "retornar a quantidade de divisores" (dizer quantos divisores o número tem). São lógicas distintas!

Sim está correta!

 
1 hora atrás, Simon Viegas disse:

Ou seja, estaria confundido "perda de tempo" com "não necessidade.

Sim, e mais pessoal que lógico!

 
1 hora atrás, Simon Viegas disse:

 

Veja, aí cai no quero quero dizer sobre "definições"... o nome da função está "numeroDivisores"... mas dentro está "se o número for primo, imprima o número na tela". Ué, João é João, Maria é Maria...

Isso fiz é para autora perceber, já fiz de proposito!

 
1 hora atrás, Simon Viegas disse:

"Um método que recebe um 'inteiro' e se ele for primo, a função imprime ele na tela.

Isso é para autora perceber, quem precisa aprender é ela! Não adiante acha que deixei isso despercebido!

adicionado 7 minutos depois
1 hora atrás, Simon Viegas disse:

A questão não é se 1 (um) é neutro ou não (concordamos que é), mas sim, se ser neutro é argumento para tirar o mérito de ser divisor! ou seja, eu estou "seguindo o senso comum" dizendo que  "um é o elemento neutro da divisão E 1 é um divisor!". Logo, eu corroboro com o Wikipedia.

Ainda sim, não tem implicações lógicas! Percebe que não muda nada se a site ou você usar 1 como divisor, o resultado de x/1 ainda é x. Se isso tivesse alguma implicação até mesma na matemática mais não há, existe apenas para ninguém dizer oh primo tem mais um divisor o 1. A é! e daí serve de nada dividir por 1. Mas tá lá se não tivesse com certeza surgiria um gênio para propor isso. Coloca o 1 como divisor de primos também!

 

Isto é uma operação de divisão: 1 / 1;

Porém não há divisão!

 

Esse poster não é mais sobre recursividade :D Nem o fórum sobre C hahahahah!

Editado por AnsiC
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Definição: Todo número primo tem como único divisor exato e primo ele mesmo!

Essa agrada gregos e troianos... ^_^

De minha autoria!

 

Parei com a zoação, foi só dessa vez!

~~ / ~~

Editado por AnsiC
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@jujubasdeuva, como prometido:

 

20 horas atrás, Simon Viegas disse:

Daí, após resolver assim, te passamos como "transformar um laço de repetição com for, para uma função recursiva".

 

Então, não foi exatamente como "defini", mas segue códigos e tentativas de explicação.

 

1#

Se entendendo que a recursividade se refere apenas a faixa, ou seja, fazer ir de 1 a Numero. (e não no cálculo em si se é primo ou não)

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

/*
 DEFINIÇÃO DO PROBLEMA

 Construa um programa em C, que solicite ao usuário informar um número qualquer e o sistema
 deve calcular todos os números primos até o número informado. Deve ser utilizada uma função
 recursiva em lugar de uma estrutura de repetição para calcular os números primos." 
*/


/*
  MÉTODO QUE RECEBE UM INTEIRO E SE ELE FOR PRIMO, EXIBE ELE NA TELA
*/
void imprimirSeForPrimo (long long unsigned int numero) {
    long long unsigned int i;
    char eh_primo = 1;
    
    if (numero < 2) //se menor que 2
        eh_primo = 0; //número não é primo
    for (i = 2; i < numero; i++) { //verifica se exsite divisores entre 2 e o antessessor ao número
        if ((numero % i)==0) //se é divisor
            eh_primo = 0; //número não é primo
    }
    
    if (eh_primo) //após a verificação acima, se a flag contém 1, então o número é primo
        printf("%llu ",numero); //imprime o número na tela
    return;
    }
      
/*
  MÉTODO QUE RECEBE UM INTEIRO E EXIBE OS PRIMOS DE 1 ATÉ ESSE INTEIRO
*/    
void verificarSequenciaDePrimos (long long unsigned int atual, long long unsigned int numero) {
    imprimirSeForPrimo(atual); //verifica o número atual
    if (atual < numero) //se o atual for menor que a última posição (como a função é "+1, vai no último loop vai verificar o valor de número)
        verificarSequenciaDePrimos(atual+1,numero); //chamo a própria função, atualizando o atual
}

int main() {
	long long unsigned numero;
	printf("Digite um numero inteiro positivo\n");
	scanf("%i", &numero);
	verificarSequenciaDePrimos(1,numero);
	return 0;
}

 

 

 

2#

Se entendendo que a recursividade se refere tanto a faixa, ou seja, fazer ir de 1 a Numero tanto na verificação se é primo ou não

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

/*
 DEFINIÇÃO DO PROBLEMA

 Construa um programa em C, que solicite ao usuário informar um número qualquer e o sistema
 deve calcular todos os números primos até o número informado. Deve ser utilizada uma função
 recursiva em lugar de uma estrutura de repetição para calcular os números primos." 
*/


/*
 FUNÇÃO QUE RETONA SE UM NÚMERO É PRIMO OU NÃO 
 */

bool ehPrimo (long long unsigned int numero, long long unsigned int atual) {
    if (numero < 2) //se for menor que não, não é primo
        return false;
    if (atual == numero) //se atul == numero, é que já foi verificado todos anteriores, logo é primo
        return true; //retorna que é primo (não continua a recursividade)
    else
        if ((numero % atual)==0) //se for divisível, não é primo
            return false; //retorna que não é e finaliza (não continua a recursividade)
        else
            return ehPrimo(numero,atual+1); //vai para o próximo número
 }
 
/*
  MÉTODO QUE RECEBE UM INTEIRO E EXIBE OS PRIMOS DE 1 ATÉ ESSE INTEIRO
*/    
void verificarSequenciaDePrimos (long long unsigned int atual, long long unsigned int numero) {
    if (ehPrimo(atual,2))  //verifica o número atual
        printf("%llu ",atual); //imprime o número na tela
    if (atual < numero) //se o atual for menor que a última posição (como a função é "+1, vai no último loop vai verificar o valor de número)
        verificarSequenciaDePrimos(atual+1,numero); //chamo a própria função, atualizando o atual
}

int main() {
	long long unsigned numero;
	printf("Digite um numero inteiro positivo\n");
	scanf("%i", &numero);
	verificarSequenciaDePrimos(1,numero);
	return 0;
}

 

 

3#

Se entendendo que a recursividade se refere apenas  a verificação se é primo ou não. (a faixa de número é verificado com um laço de repetição comum mesmo)

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

/*
 DEFINIÇÃO DO PROBLEMA

 Construa um programa em C, que solicite ao usuário informar um número qualquer e o sistema
 deve calcular todos os números primos até o número informado. Deve ser utilizada uma função
 recursiva em lugar de uma estrutura de repetição para calcular os números primos." 
*/


/*
 FUNÇÃO QUE RETONA SE UM NÚMERO É PRIMO OU NÃO 
 */

bool ehPrimo (long long unsigned int numero, long long unsigned int atual) {
    if (numero < 2) //se for menor que não, não é primo
        return false;
    if (atual == numero) //se atul == numero, é que já foi verificado todos anteriores, logo é primo
        return true; //retorna que é primo (não continua a recursividade)
    else
        if ((numero % atual)==0) //se for divisível, não é primo
            return false; //retorna que não é e finaliza (não continua a recursividade)
        else
            return ehPrimo(numero,atual+1); //vai para o próximo número
 }
 

int main() {
	long long unsigned numero;
	printf("Digite um numero inteiro positivo\n");
	scanf("%i", &numero);
	
	for (int i = 1;i <= numero; i++)
        if (ehPrimo(i,2))
            printf("%llu ",i); //imprime o número na tela
	
	return 0;
}

 

 

4#

Se entendendo que a paridade é feita verificando se o número tem exatamente 2 divisores (incluindo o 1), e definindo que será recursivo apenas a verificação de primos (a faixa de número é verificado com um laço de repetição comum mesmo). obs.: essa é a forma que eu tendendo que deveria ser, mas é só uma opinião

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

/*
 DEFINIÇÃO DO PROBLEMA

 Construa um programa em C, que solicite ao usuário informar um número qualquer e o sistema
 deve calcular todos os números primos até o número informado. Deve ser utilizada uma função
 recursiva em lugar de uma estrutura de repetição para calcular os números primos." 
*/

/*
 FUNÇÃO QUE RETONA A QUANTIDADE DE DIVISORES NATURAIS QUE UM NÚMERO NATURAL TEM
*/
int numeroDivisores (long long unsigned int numero, long long unsigned int atual) {
    if (atual == numero) //encontrou mais um divisor
        return 1; //retorna 1 (e não continua a recursividade)
    if ((numero % atual)==0)
        return 1+numeroDivisores(numero,atual+1);
    else
        return 0+numeroDivisores(numero,atual+1);
}

/*
 FUNÇÃO QUE RETONA SE UM NÚMERO É PRIMO OU NÃO 
 */
bool ehPrimo (long long unsigned int numero) {
    if (numeroDivisores(numero,1)==2) //verifica se o número tem exatametne 2 divisores
        return 1; //retorna verdadeiro (é primo)
    else
        return 0; //retorna false (não é primo)
}

int main() {
	long long unsigned numero;
	printf("Digite um numero inteiro positivo\n");
	scanf("%i", &numero);
	
	for (int i = 1;i <= numero; i++)
        if (ehPrimo(i))
            printf("%llu ",i); //imprime o número na tela
	return 0;
}

Ou seja, você desenvolveria o método numeroDivisores() utilizando um laço de repetição comum (como for), ai, nós tentaríamos explicar como converter de for para recursividade. Seria isso ai acima!

 

obs.: alguns conceitos podem está errados ai no meio (ou tudo, vá saber, ainda mais que estou cansado e estou improvisando), mas foi dessas formas que compreendi. Qualquer comentário ou dúvidas é só postar.

 

No aguardo.

 

 

 

@AnsiC, sobre:

5#

1 hora atrás, AnsiC disse:

@Simon Viegas tudo errado!

OK. Acontece. Obrigado pelo feedback.

 

 

Sobre:

6#

12 minutos atrás, AnsiC disse:

Definição: Todo número primo tem como único divisor exato e primo ele mesmo!

Essa agrada gregos e troianos... ^_^

 

De minha autoria!

OK.  Continuamos cada um com sua definição. (já que eu não consegui argumentar, e nem você me convencer. Fica pra próxima)

 

Att.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×