Ir ao conteúdo
  • Cadastre-se

C Como encontrar o k-ésimo menor valor de um vetor


Posts recomendados

Boa noite, alguém pode me ajudar como eu poderia fazer essa questão?

O ponto é apenas eu encontrar o késimo menor valor do vetor, acredito que o resto das coisas eu já fiz. qualquer dica é bem-vinda.

6. Crie um algoritmo chamado selectionFind baseado no Selection Sort para que, em vez de ordenar uma sequência de números inteiros, ele nos retorne o k-ésimo menor elemento dessa sequência. Por exemplo: Suponha que os elementos S = 7, 1, 3, 10, 17, 2, 21, 9 estejam armazenados nessa ordem em um vetor e que desejamos obter o quinto maior elemento dessa sequência. Então, uma chamada como selectFind(S,0,7,5), deverá retornar o número 9, onde S é o nome do vetor, 0 e 7 são, respectivamente, o menor e o maior índice do vetor e 5 indica que desejamos o quinto menor elemento. Obs.: Você não deve ordenar a sequência e depois tomar o k-ésimo elemento. K é um valor informado pelo usuário.

Anexo o que eu já fiz.

6.txt

Link para o post
Compartilhar em outros sites

SelectionSort() já faz isso. 

 

Basta você usar o critério para ordem decrescente e parar na n-esima vez, já que a cada ciclo seleciona o menor. Basta retornar o valor ao invés de continuar classificando à toa.

  • Curtir 1
Link para o post
Compartilhar em outros sites
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TAM 8
int selectSort(int *vetor, int k) {
    int me, aux, i, troca;
    for(aux=0; aux < TAM-1; aux++) {
        me = aux;
        for (i=aux+1; i < TAM; i++) {
            if (vetor[i] < vetor[me]) {
                me = i;
            }
        }
        if (me != aux)    {
            troca = vetor[aux];
            vetor[aux] = vetor[me];
            vetor[me] = troca;
        }
        if (aux==k) {
            printf("\n%d\n", vetor[aux]);
        }
    }
    return (0);
}
int main() {
    int pegaK, aux, vetor[TAM] = {7, 1, 3, 10, 17, 2, 21, 9};
    //srand (time(NULL));
    printf("\nK:\n");
    scanf("%d", &pegaK);
    /*for (aux=0; aux < TAM; aux++) {
        vetor[aux] = (rand() % 89) + 10;
        printf("[%d] ", vetor[aux]);
    }*/
    printf("\n\n");
    for (aux=0; aux < TAM; aux++) {
        printf("[%d] ", vetor[aux]);
    }
    printf("\n\n");
    selectSort(vetor, pegaK);

    return (0);
}

 

  • Curtir 1
Link para o post
Compartilhar em outros sites

Está certo de que está funcionando isso?

 

E não está muito bom ainda :(

 

  • main() deve ser a primeira função do programa
     
  • declare main() como
        int main(void)
    ou
        int main(int argc, char** argv)

     

  • srand(time) não é esperto nesse caso. É melhor usar um valor conhecido enquanto testa, e NUNCA a hora
     
  • for() SEMPRE declare a variável de controle do loop DENTRO do for. Desde os anos '80 C foi alterada para permitir isso
     
  • scanf(): SEMPRE teste o retorno de scanf(). Qual o propósito de continuar com o programa se não ler K?
     
  • Use a linha de comando. É mais esperto. É chato rodar o programa e depois ter que entrar com o valor de K. Imagine se o compilador abrisse um prompt e a cada programa perguntasse "Entre com o programa a compilar:"...
     
  • Ao ler valores deixe o prompt na mesma linha
     
  • Não use variáveis globais.  Muito menos uma chamada aux. Poucos de seus programas vão ter 20 linhas e isso é um pesadelo de manutenção
     
  • #define: use os #define antes dos #include porque algum dos #include pode depender do #define...
     
  • selectSort() nao deve mostrar nada e sim reotrnar o valor
Link para o post
Compartilhar em outros sites

O que você quer dizer com este ponto? não compreendi.

  •  scanf(): SEMPRE teste o retorno de scanf(). Qual o propósito de continuar com o programa se não ler K?

Mexi no código, agora está mais limpo. Não consegui colocar o main() como primeira função, é como se o selectSort não existisse ao ser chamado.

Aliás, por que eu não deveria usar variáveis globais? (ainda sou leiga nisso, já usei algumas vezes sem erros.).

#include <stdio.h>
#define m 8
int selectSort(int *vetor, int k) { int me, t;
    for(int j = 0; j < m-1; j++) { me = j;
        for (int i = j+1; i < m; i++) {
            if (vetor[i] < vetor[me]) { me = i; }
        }
        if (me != j) {
            t = vetor[j];
            vetor[j] = vetor[me];
            vetor[me] = t;
        }
        if (j == k) { return vetor[j]; }
    }
}
int main(void) {
	int K, vetor[m];
	for (int i = 0; i < m; ++i) {
		printf("[%d] ", i); scanf("%d", &vetor[i]);
	}
    printf("K: "); scanf("%d", &K);
    for (int i = 0; i < m; i++) {
        printf("[%d] ", vetor[i]);
    }
    printf("\n");
    printf("%do menor valor: %d", K, selectSort(vetor, K));
    return (0);
}

 

Link para o post
Compartilhar em outros sites
2 minutos atrás, natesp disse:

por que eu não deveria usar variáveis globais? (ainda sou leiga nisso, já usei algumas vezes sem erros

 

:) pois é. Acontece que uma variável global fica viva, válida, durante todo o programa. No seu caso nem são exatamente globais, mas variáveis declaradas em main() vão estar vivas durante todo o programa.

 

Isso é proibido ou ao menos desencorajado em toda parte, empresas e escolas. A razão é simples: controle, manutenção. Sua variável com o nome ingênuo de aux por exemplo só existe para o loop que imprime o vetor, mas está válida por toda a função, e com esse nominho. Por exemplo é usada de novo dentro do loop que está comentado. Se algumas linhas abaixo  você usa essa variável pode zoar o programa todo e levar horas para descobrir o erro.

 

Por isso o que se procura na prática é DIMINUIR ao máximo a visibilidade e o tempo de vida --- scope --- das variáveis, porque o que não existe não pode dar erro. Pelo mesmo motivo você DEVE declarar as variáveis de controle de um for por exemplo DENTRO do for,  escrevendo
 

    for (int aux=0; aux < TAM; aux++)
        printf("[%d] ", vetor[aux]);


ao invés de
 

    for (aux=0; aux < TAM; aux++) {

        printf("[%d] ", vetor[aux]);

    }

 

como fez. Note que se o loop tem um único comando as chaves são opcionais e muitas vezes só atrapalham a leitura.

 

Esse é um ponto importante quando seu programa passa a ter mais de umas poucas linhas.
 

scanf()

 

15 minutos atrás, natesp disse:

O que você quer dizer com este ponto? não compreendi.

  •  scanf(): SEMPRE teste o retorno de scanf(). Qual o propósito de continuar com o programa se não ler K?

 

???? Não entendeu? 

 

O propósito de seu programa é mostrar o k-esimo menor valor de um certo vetor de int. Se não conseguir ler K qual o sentido de rodar o programa? O que vai fazer? 

 

Se na hora de digitar o tal K o cara ia digitar 8 e bateu a mão no U que fica logo abaixo, que acha que vai acontecer?

 

Veja:

 

#include <stdio.h>
int main(void)
{
    int valor;
    printf("Valor: ");
    int res = scanf("%d", &valor);
    printf( "scanf() retornou %d, valor = %d\n",
        res,
        valor
    );
    return 0;
}

 

Rodando esse sofisticado programa de 10 linhas:

 

ch$  gcc -o ts ts.c
ch$  ./ts
Valor: 122
scanf() retornou 1, valor = 122
ch$  ./ts
Valor: u
scanf() retornou 0, valor = -639192736
ch$  

 

Acho que agora entendeu...

 

Você tem um livro?

 

Sobre main()

 

20 minutos atrás, natesp disse:

Não consegui colocar o main() como primeira função, é como se o selectSort não existisse ao ser chamado.

 

Você deve usar o que se chama protótipo. no início do programa informe ao compilador que d1@b0 é selectSort() usando
 

    int selectSortint (int,int*,int);

 

assim ao ver a chamada o compilador saberá o que fazer.

 

Em geral as funções são deixadas em arquivos separados, porque vários programas cada um com seu main(0 e seu propósito, podem usar tais funções. É para isso que elas são escritas afinal....

 

 

Sobre selectSort()

 

24 minutos atrás, natesp disse:

Mexi no código, agora está mais limpo

 

É verdade, mas está errado ainda. Por exemplo
 

int selectSort(int *vetor, int k) { int me, t;
    for(int j = 0; j < m-1; j++) { me = j;
        for (int i = j+1; i < m; i++) {
            if (vetor[i] < vetor[me]) { me = i; }
        }
        if (me != j) {
            t = vetor[j];
            vetor[j] = vetor[me];
            vetor[me] = t;
        }
        if (j == k) { return vetor[j]; }
    }
}

 

O teste não deve ser para k mas sim para (k-1). Pense bem: se o cara quiser o menor valor vai passar K = 1. 

Mas me vai ser ZERO. 

 

Acha que levou vantagem em usar me ao invés de menor e economizar 3 letras? Não levou. Use nomes mais significativos. É melhor para você e para quem venha a ler seu programa.

 

Selection Sort()

 

Esse algoritmo é o que qualquer criança usaria para colocar coisas os brinquedos em ordem, do maior para o menor. OK, é um algoritmo, mas é o óbvio. A criança pega os 5 brinquedos. Escolhe o maior deles e põe na frente. Aí olha os outros 4 e faz a mesma coisa. E depois com os outros 3. E depois escolhe o maior dos 2 últimos e põe na frente do último. E os brinquedos ficam lá em ordem.

 

É isso que está programando. Só que quer o K-esimo item maior, então vai retornar depois de escolher K vezes. Só isso.

 

MAS...

 

se o cara digitou K = N, para mostrar o 5 menor item de 5, vai dar na mesma porque vai selecionar o quinto menor brinquedo que vai ser o menor de todos.

 

E aí está outro erro de sua função... Não funciona para K = N - 1

 

       if (me != j) {
            t = vetor[j];
            vetor[j] = vetor[me];
            vetor[me] = t;
        }
        if (j == k) { return vetor[j]; }

 

 

Não sou eu que vou corrigir seu programa, mas fosse eu e você perderia uns pontos também por fazer essa inversão ANTES de testar com k (o teste está errado, já expliquei): pra que vai inverter os valores se vai retornar logo em seguida? Não é esperto. Só está perdendo tempo.

 

Compare 
 

        if ( i == (K-1) )
        {
            if ( menor == i )
                return v[i];
            else
                return v[menor];
        };  // if()

 

 

 

 

  • Curtir 1
Link para o post
Compartilhar em outros sites
#include <stdio.h>
#define m 8
int selectSort (int*, int);
int main(void) {
	int K, vetor[m] = {7, 1, 3, 10, 17, 2, 21, 9};
	/*for (int i = 0; i < m; ++i) {
		printf("[%d] ", i); scanf("%d", &vetor[i]);
	}*/
	for (int i = 0; i < m; i++) {
        printf("[%d] ", vetor[i]);
    }
    printf("K: ");
    int r = scanf("%d", &K);
    printf("scanf() retornou %d, valor = %d\n", r, K);
    for (int i = 0; i < m; i++) {
        printf("[%d] ", vetor[i]);
    }
    printf("\n");
    printf("%do menor valor: %d", K, selectSort(vetor, K));
    return (0);
}
int selectSort(int *vetor, int k) { int menor, t, j, i, c=0;
    for(j = 0; j < m-1; j++) { menor = j;
        for (i = j+1; i < m; i++) {
        	if (vetor[i] < vetor[menor]) {
        		menor = i;
        		if (i==(k-1)) {
        		    if (menor == i) {
        		    	return vetor[i];
        		    } else {
        		    	return vetor[menor];
        		    }
        		} 			
            }
        }
        /*if (menor != j)	{
            t = vetor[j];
            vetor[j] = vetor[menor];
            vetor[menor] = t;
        }*/
        if (j == (k-1)) { return vetor[j]; }
    }
}

Fiz o que você disse, mas ainda não consegui encontrar a solução exata para o problema, entendi o que você quis dizer, posso estar errando, mas não estou sabendo como corrigir, enfim, obrigada de qualquer maneira.

Link para o post
Compartilhar em outros sites

 

wow! está bem melhor!

  • tem os protótipos
  • main() está no início e com void na lista de argumentos
     
        printf("K: ");
        int r = scanf("%d", &K);
        printf("scanf() retornou %d, valor = %d\n", r, K);

     

  • isso eu não entendi. OK você salvou o retorno de scanf(). Nem precisava. O que você precisa fazer é TESTAR. scanf() retorna um int, claro, e você salvou em r. Mas o que precisa entender, e eu te mostrei um programa exemplo pronto E também a execução, é que scanf() pode não ler nada e aí vai retornar 0, ou -1. 
    • o que importa é que cada coisa dessas com % em scanf() é um valor a ser lido. No seu caso "%d" só vai ler um valor. scanf() vai tentar ler tudo que foi pedido e vai retornar quantos conseguiu ler. No seu caso só pode ler 1.
    • se não retornar 1 é porque não leu K e você tem que encerrar o programa. Ou tentar ler de novo. O que não pode fazer é cegamente continuar sem ter lido nada. O que vai fazer sem o valor de K? Entendeu agora? Leia o exemplo que te mostrei, e a execução.
       
  • não declare mais de uma variável por linha
     
  • use comentários,. no mínimo para os argumentos das funções e algum detalhe da lógica
     
  • NUNCA use um #define com nome assim como 'm'. Fica difícil de achar. Há uma convenção: Use algum nome TODO em maiúsculas assim saberá logo que é um @define.
     

não entendi a nova versão de selectSort(). Talvez pudesse alinhar melhor seu código. Eis o que tem lá. alinhado de um modo mais convencional:
 

#define m 8
int selectSort(int* vetor, int k)
{
    int menor, t, j, i, c = 0;
    for (j = 0; j < m - 1; j++)
    {
        menor = j;
        for (i = j + 1; i < m; i++)
        {
            if (vetor[i] < vetor[menor])
            {
                menor = i;
                if (i == (k - 1))
                {
                    if (menor == i)
                    {
                        return vetor[i];
                    }
                    else
                    {
                        return vetor[menor];
                    }
                }
            }
        }
        /*
        if (menor != j)
        {
            t = vetor[j];
            vetor[j] = vetor[menor];
            vetor[menor] = t;
        }
        */
        if (j == (k - 1)) { return vetor[j]; }
    }
}

 

  • pra que t e c se não usa?
     
  • você comentou as inversões e assim o selection sort não seleciona nada, fica tudo igual certo? Se fica igual como vai classificar?
     
  • O teste no final está errado.  Se chegar no fim do loop é porque o vetor tinha 8 números e o cara pediu o oitavo menor, popularmente conhecido como o maior valor do vetor já que estará ao final em ordem crescente. Leu o que eu escrevi sobre esse tipo de sort?
     
  • porque voltou a escrever coisas como
     
        for (j = 0; j < m - 1; j++)


PRESTE ATENÇÃO ao código abaixo: ele retorna como esperado e funciona para qualquer valor de N e K.

 

Procure ver as diferenças: 

  • não tem nenhuma variável global à função, por exemplo.
  • é mais fácil passar o valor de N para ajudar nos testes
  • o primeiro loop SELECIONA o menor entre os que sobraram. Veja o exemplo que te expliquei sobre a criança e os brinquedos...
  • menor só faz sentido dentro do loop e deve ser declarada lá.
  • se você apagar a parte da "mudança" é claro que vai ficar com um selection sort normal, então pode começar sua função de qualquer selection sort(0 que vir por aí que vai funcionar...

 

// retorna o K-esimo menor valor de v[] com N elementos
int         select_K_Sort(int K, int v[], int N)
{
    for (int i = 0; i < N-1; i++)
    {
        int menor = i;
        for (int j = i+1; j <N; j++) if (v[j] < v[menor]) menor = j;

        // essa e a mudanca no selection dort para retornar o K-esimo menor
        if ( i == (K-1) )
        {
            if ( menor == i )
                return v[i];
            else
                return v[menor];
        };  // if()
        // fim da mudanca
        
        // aqui continua o algoritmo normal
        if ( menor != i )
        {   // inverte
            int temp = v[i];
            v[i] = v[menor];
            v[menor] = temp;
        }
    };  // for()
    return v[N-1]; // era o ultimo
}

 

 

  • Curtir 1
Link para o post
Compartilhar em outros sites

obrigada, você foi de grande ajuda, de verdade, estudo tudo sozinha e ainda é meio complicado pra mim.

#include <stdio.h>
int selectSort (int, int*, int);
int main(void) {
	int N, K;
	printf("\nNo. elementos: "); scanf("%d", &N);
	int vetor[N];
	for (int i = 0; i < N; ++i) {
		printf("[%d] ", i); scanf("%d", &vetor[i]);
	}
	for (int i = 0; i < N; i++) {
        printf("[%d] ", vetor[i]);
    }
    printf("K: ");
    scanf("%d", &K);
    for (int i = 0; i < N; i++) {
        printf("[%d] ", vetor[i]);
    }
    printf("\n");
    printf("%do menor valor: %d", K, selectSort(K, vetor, N));
    return (0);
}
int selectSort(int k, int vetor[], int N)
{ 
    for(int i = 0; i < N-1; i++)
    {
    	int menor = i;
        for (int j = i+1; j < N; j++)
        	if (vetor[j] < vetor[menor]) menor = j;
        		if (i==(k-1))
        		{
        		    if (menor == i)
        		    	return vetor[i];
        		    else
        		    	return vetor[menor];
        		};
        			
        if (menor != i)
        {
            int t = vetor[i];
            vetor[i] = vetor[menor];
            vetor[menor] = t;
        }
    };
    return vetor[N-1];
}

Esse é o código final, obrigada pelas dicas e tempo dedicado para fazê-las, foram cruciais.

  • Curtir 1
Link para o post
Compartilhar em outros sites

Está muito melhor em relação às versões anteriores. Parabéns.

 

Sobre isso:

 

int main(void)
{
	int N, K;
	printf("\nNo. elementos: "); scanf("%d", &N);
	int vetor[N];


Nunca use isso. Em alguns casos é possível, mas não é boa ideia. As dimensões devem ser constantes.

 

E TESTE o retorno de scanf() !!! Qual o sentido de seguir sem ler o vetor inteiro ou sem ler algum valor? NENHUM.

 

Veja o exemplo que te dei antes... o programa e o resultado... 

 

Interatividade

 

De acordo com o enunciado apenas o valor de K tem que ser fornecido pelo usuário. Então evite ao máximo qualquer tipo de interatividade. Só vai te atrapalhar. Não ensina nada. 

 

Ninguém afinal vai querer ficar digitando números na tela para depois digitar o valor de um certo K e ver o k-ésimo menor valor.

Obrigado por continuar postando as versões do programa. Esse é o objetivo do forum. Claro, em geral os que procuram respostas buscam por uma resposta pronta ;) e alguns dos que respondem parecem responder para mostrar conhecimento ou como um desafio pessoal (mais ao estilo de um outro site famoso meio pedante -- StackOverflow). 

 

Ainda sobre esse programam entenda que o mais prático seria poder digitar direto os valores. 

 

Exemplo

 

Se o programa se chamar sortk.exe no windows por exemplo, o cara abre lá um terminal e digita
 

	sortk

 

O programa roda e pergunta o valor de K. E assume um vetor de 8 números como tinha feito em seu programa

 

Mas se o cara digita
 

	sortk 5

 

O programa entende que 5 é o valor de K e não fica perguntando, porque afinal é chato.

 

Mas se o cara digita 
 

    sortk 20 45

 

o programa entende o óbvio: vai usar um vetor de 45 números e mostrar o 20-esimo menor e não fica perguntando nada...

 

Não é mais prático? Ou será melhor abrir o IDE carregar o programa, compilar, gerar o exe, esperar a mensagem e digitar os valores um por um e depois o valor de K?

 

Como seria? Veja

 

ch$ 
ch$ gcc -o sortk  -Wall -std=c17 sortk.c

ch$ ./sortk

Prefira usar "sortK K [N]" para definir K e N
[valores gerados aleatoriamente]
8 Valores: [ 7 7 9 5 5 6 3 7 ]
[voce poderia ter usado a linha de comando] K: 8
Identifica o #8 menor elemento no vetor de 8 elementos
#8 menor = 9

ch$ ./sortk 1
[valores gerados aleatoriamente]
8 Valores: [ 7 7 9 5 5 6 3 7 ]
Identifica o #1 menor elemento no vetor de 8 elementos
#1 menor = 3

ch$ ./sortk 12 15
[valores gerados aleatoriamente]
15 Valores: [ 10 10 15 10 11 2 12 5 6 16 7 6 8 5 9 ]
Identifica o #12 menor elemento no vetor de 15 elementos
#12 menor = 11
ch$ 

 

Uma última vez, em relação a scanf()

 

ch$ ./sortk 

Prefira usar "sortK K [N]" para definir K e N
[valores gerados aleatoriamente]
8 Valores: [ 7 7 9 5 5 6 3 7 ]
[voce poderia ter usado a linha de comando] K: i
ch$ 

 

Se o cara bater a mão no i porque ia digitar 9 e o i fica logo embaixo, errou e já era. Então se espera que o programa termine. Não precisa dar uma mensagem, ler de novo, contar os erros, nada disso. É só um programa de estudo. Mas seguir reto não pode. Qual vai ser o valor de K?

 

Como preencher um vetor com N valores entre A e B e retornar o vetor para o programa?

 

No seu programa isso seria prático: os valores vem arrumadinhos, podem repetir alguns para testar o sort e tal. E pode ser simples. Veja esse:

 

// retorna um vetor com k int entre menor e maior inclusive
int*        vetorN(int k,int menor, int maior)
{
    int* v = (int*) malloc( k * sizeof(int) );
    if ( v == 0 ) return NULL;
    // nesse caso valores repetidos sao esperados
    for( int i= 0; i<k;i+=1) v[i] = 1 + menor + rand() % maior;
    return v;
}; // inventa o vetor de k int

 

Como usar um trem desses?

 

Trivial:
 

    int* vetor = vetorN( 50,1,20); // vetor com 50 valores entre 1 e 20 inclusive
    mostra_vetor( vetor, N, "[valores gerados aleatoriamente]"); // mostra na tela
    free(vetor); // quando nao for mais usar apaga

 

Como mostrar na tela nos testes
 

// mostra na tela k elementos do vetor v e opcional m e retensagem msg
void        mostra_vetor(int* v,int n,const char* msg)
{
    if ( v == 0 ) return;
    if ( msg != NULL ) printf("%s\n", msg);
    printf("%d Valores: [ ", n);
    for( int i= 0; i<n;i+=1) printf("%d ", v[i]);
    printf("]\n");
    return;
};

 

Se msg for NULL apenas lista os valores. Mas nos testes pode ser conveniente usar uma mensagem, e asim economiza uns printf(). Veja o exemplo acima

 

O exemplo completo

 

Esse exemplo aceita vetores de qualquer tamanho, aceita os valores de K e N da linha de comando e usa as funções que mostrei. Se comentar o trecho indicado (8 linhas) em selectSort() terá o selection sort normal.

 

Spoiler


#define TAM 8

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

void        mostra_vetor(int*,int,const char*); // mostra vetor
int         select_K_Sort(int K, int v[], int N); // #K no vetor de N
int*        vetorN(int,int,int); // inventa o vetor de N int

// cria e preenche um vetor de N elemntos e mostra o K-esimo menor
int main(int argc, char** argv)
{
    unsigned N = TAM; 
    unsigned K = TAM-1;
    srand (210408); // para poder reproduzir a sequencia nos testes

    if (argc == 1)  printf("\nPrefira usar \"sortK K [N]\" para definir K e N\n");
    if (argc > 1) K = atoi(argv[1]);
    if (argc > 2) N = atoi(argv[2]);
    if ( K > N ) return -2; // bobagem

    int* vetor = vetorN(N,1,N); // vetor com valores entre 1 e N
    mostra_vetor( vetor, N, "[valores gerados aleatoriamente]");

    if ( argc < 2 )
    {   // se nao veio K entao le
        printf("[voce poderia ter usado a linha de comando] K: ");
        if ( scanf("%d", &K) != 1) return -1; // nao leu nada
        if ( K > N ) return -2; // bobagem
    }
    printf("Identifica o #%d menor elemento no vetor de %d elementos\n", K, N);
    printf("#%d menor = %d\n", K, select_K_Sort(K, vetor, N) );
    free(vetor);

    return 0;
}


// mostra na tela k elementos do vetor v e opcional m e retensagem msg
void        mostra_vetor(int* v,int n,const char* msg)
{
    if ( v == 0 ) return;
    if ( msg != NULL ) printf("%s\n", msg);
    printf("%d Valores: [ ", n);
    for( int i= 0; i<n;i+=1) printf("%d ", v[i]);
    printf("]\n");
    return;
};

// retorna o K-esimo menor valor de v[] com N elementos
int         select_K_Sort(int K, int v[], int N)
{
    for (int i = 0; i < N-1; i++)
    {
        int menor = i;
        for (int j = i+1; j <N; j++) if (v[j] < v[menor]) menor = j;

        // essa e a mudanca no selection dort para retornar o K-esimo menor
        if ( i == (K-1) )
        {
            if ( menor == i )
                return v[i];
            else
                return v[menor];
        };  // if()
        // fim da mudanca
        
        // aqui continua o algoritmo normal
        if ( menor != i )
        {   // inverte
            int temp = v[i];
            v[i] = v[menor];
            v[menor] = temp;
        }
    };  // for()
    return v[N-1]; // era o ultimo
}


// retorna um vetor com k int entre menor e maior inclusive
int*        vetorN(int k,int menor, int maior)
{
    int* v = (int*) malloc( k * sizeof(int) );
    if ( v == 0 ) return NULL;
    // nesse caso valores repetidos sao esperados
    for( int i= 0; i<k;i+=1) v[i] = 1 + menor + rand() % maior;
    return v;
}; // inventa o vetor de k int

 

 

 

 

  • Obrigado 1
Link para o post
Compartilhar em outros sites

@arfneto Isso é muito interessante, não sabia que dava para usar assim, é melhor, vou tentar pôr em prática nos meus programas.

Aliás, você teria algum livro que poderia me indicar? É sempre bom aprender mais.

Link para o post
Compartilhar em outros sites

@natesp o que seria "assim" nesse caso?

 

Não sei agora de um livro de C, faz muito tempo que não leio. O livro de K&R, o clássico "A Linguagem de Programação C , é muito bom. Mas a linguagem evoluiu muito e não sei hoje como seria. A linguagem fez 50 anos afinal.

 

Use um IDE que mostre ao menos os protótipos. um compilador moderno. Algum site. Forums como esse são eu acho muito legais porque podem ter a evolução de algum problema e tem pessoas do  outro lado. Um pouco pedante, mas o StackOverflow é muito legal. E o Tutorials Point tem muitos exemplos em várias linguagens, de tudo. E o Geeks for Geeks tem o mesmo perfil. Dê uma olhada.

 

 

 

  • Curtir 1
Link para o post
Compartilhar em outros sites
4 horas atrás, natesp disse:

@arfneto quero dizer a parte de usar: "sortK K [N]" para definir K e N, ficou meio confusa, mas deu para entender. :)

 

Isso é para o cara digitar o mínimo possível e o programa se virar.

  • se o cara não digitar nada, só o nome do programa e ENTER, então assume o vetor de 8 elementos como você fez, e pede para o usuário digitar o valor de K porque sem ele não dá para continuar
    • mas se não conseguir ler K encerra, como te expliquei
    • se conseguir ler mas for maior que o total de elementos pode ser o instrutor tentando ver se você pensou nisso, então faz K = N - 1, que significa mostrar o maior elemento
       
  • se o cara digitar um valor só então é o valor de K e vai usar o vetor de 8
     
  • se o cara digitar 2 números então serão K e N na ordem

Claro que podia ser diferente. É só um exemplo. Até faria mais sentido ser N o primeiro valor e K o segundo.

 

O que importa é entender que usar a linha de comando é trivial. E ficar digitando é chato. Por isso os programas  sempre recebem esses valores: main() é
 

    int main( int argc, char** argv );

 

e isso quer dizer que todo programa recebe um vetor de ponteiros com argc valores.

 

O primeiro é sempre o nome do programa. Eu já escrevi bastante sobre isso aqui. Dá pra pesquisar no conteúdo vendo o meu perfil.

  • Curtir 1
Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 comunidades 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

×
×
  • Criar novo...

Aprenda a ler resistores e capacitores

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!