Ir ao conteúdo
  • Cadastre-se

C++ QuickSort - Ordenação dentro de arquivo


Posts recomendados

11 horas atrás, arfneto disse:

Pois é, a da direita grava um arquivo, de 10, 10.000  ou 1 milhão de valores. 

 

Percebi isso também, comecei a manipular os números. 

Agora acredito que o próximo passo seria  fazer a busca desses números no vetor e organiza-los, correto!? 

Se for, tenho que estudar isso. 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define TAM 10000

int dividir (int vetor[], int esq, int dir){
	int aux;
	int cont = esq;
	
	for(int i = esq+1; i <= dir; i++){
		
		if(vetor[i] < vetor[esq]){
			cont++;
			aux = vetor[i];
			vetor[i] = vetor[cont];
			vetor[esq] = aux;
			
		}
		
	}
	aux = vetor[esq];
	vetor[esq] = vetor[cont];
	vetor[cont] = aux;
	
	return cont;
}

void quick(int vetor[], int esq, int dir){
	int pos;
	
	if(esq < dir){
	pos = dividir(vetor, esq, dir);
		quick(vetor, esq, pos-1);
		quick(vetor, pos+1, dir);
	}
}

int gravar(int[],int,int,const char*);

int main(void)
{
    int vetor[TAM];
    srand(211110);
    for (int i = 0; i < TAM; i += 1) vetor[i] = 1 + rand()%TAM;
    gravar(vetor, 10000, 100, "os primeiros 10000, 100 por linha");
    
    return 0;
}

	int gravar(int vetor[], int n, int c, const char* arquivo) {
		// grava n elementos do vetoror no arquivo, c el. por linha
		FILE* arq = fopen(arquivo, "w");
		if(arq == NULL) 
		return -1;
		int col = 0;
		for (int i = 0; i < n; i += 1){
			fprintf(arq, "%6i", vetor[i]);
			col +=1;
			if (col == c){
				fprintf(arq, "\n");
				col = 0;
			}
		};
		fprintf(arq,"\n");
		return 0;
	};

 

Código que tentei manipular mas não deu certo.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Em 11/11/2021 às 10:39, Weverson Meireles disse:

Agora acredito que o próximo passo seria  fazer a busca desses números no vetor e organiza-los, correto!? 

Se for, tenho que estudar isso

 

Talvez "estudar isso" seja um exagero. Buscar os números no vetor quer dizer apenas olhar um por um dos elementos e ver se é o que procura. Se o vetor for ordenado significa que pode parar quando encontrar um elemento maior.

Sobre a busca binária, postei algo ontem em 

 que pode ajudar.

 

Sobre o Quicksort você postou um programa, mas que parece que não foi você que escreveu.

 

 

11 horas atrás, Weverson Meireles disse:

Código que tentei manipular mas não deu certo.

 

Que significa? O que é "tentar manipular"?

 

Que pretende fazer com esse programa?

 

Apenas colou duas funções em parte do programa que eu te mostrei. Sequer chamou a função ou abriu o arquivo.

 

Assim chamou a função

 

11 horas atrás, Weverson Meireles disse:
gravar(vetor, 10000, 100, "os primeiros 10000, 100 por linha");

 

que começa assim

 

11 horas atrás, Weverson Meireles disse:
int gravar(int vetor[], int n, int c, const char* arquivo) {
		// grava n elementos do vetor no arquivo, c el. por linha

 

 

Acho que dá pra imaginar que a função criou um arquivo na sua máquina com o nome "os primeiros 10000, 100 por linha".

 

Você nem se deu ao trabalho de comparar as duas funções que te mostrei lado a lado.

 

 

A ideia era que você percebesse que podia usar a função mostrar() até o arquivo estar ok para os testes. E aí mudar umas 2 ou 3 linhas e ter o arquivo gravado, porque tratar arquivos em C é muito simples.

 

Eis as funções de novo

 

image.thumb.png.49ae8c5f27337d2af85a78f1a1a3b692.png

 

Se prestar alguma atenção vai ver que mostrar usa uma mensagem no último parâmetro. Os outros são o óbvio: o vetor, o tamanho e quantas colunas quer gerar em cada linha

 

    mostrar(vet, 80, 10, "os primeiros 80, 10 por linha");
    mostrar(vet, 20, 4, "os primeiros 20, 4 por linha");
    mostrar(vet, 18, 6, "os primeiros 18, 6 por linha");

 

no exemplo que te mostrei gera

 

image.png.98b07c92bd8442a1a32ee77469397dfd.png

 

E em seguida te expliquei que 

 

    const char* arquivo = "num.txt";
    int res = gravar(vet,TAM,10,arquivo); // cria

 

iria gerar num.txt no disco com TAM elementos, 10 por coluna, a partir dos elementos em vet[]

 

Pois é.

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, arfneto disse:

que pode ajudar.

 

Ajudou a perceber que tenho que fazer a busca por posição, mas não estou conseguindo encaixar no programa que me mostrou. 

1 hora atrás, arfneto disse:

Sobre o Quicksort você postou um programa, mas que parece que não foi você que escreveu.

 

Realmente não foi, peguei um exemplo, tentei entender e encaixar no programa que me mostrou 

 

1 hora atrás, arfneto disse:

Apenas colou duas funções em parte do programa que eu te mostrei. Sequer chamou a função ou abriu o arquivo.

 

Eu quis ter uma noção de como eu chamaria a função dentro do programa que me mostrou. 

Peguei uma estrutura pronta e quis encaixar no programa, mas não deu certo por não saber chamar 

 

É possível chamar a  função Quicksort dentro do programa que me enviou? e se for, como poderia fazer isso?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

42 minutos atrás, Weverson Meireles disse:

Eu quis ter uma noção de como eu chamaria a função dentro do programa que me mostrou. 

Peguei uma estrutura pronta e quis encaixar no programa, mas não deu certo por não saber chamar 

 

É possível chamar a  função Quicksort dentro do programa que me enviou? e se for, como poderia fazer isso?

 

Mas você nem tentou no código que mostrou

 

Você percebeu o que fez com a função gravar()?

 

Entendeu o que eu expliquei?

 

Criou um arquivo com o nome do título que copiou da função mostrar? Por que?

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Em 12/11/2021 às 12:53, arfneto disse:

Mas você nem tentou no código que mostrou

int n = 10000;
				 quick(vetor, 0, n);
				 
				 for ( i=0; i<n; i++){
				 printf("%d", vetor[i]);

Eu tentei inserir esse ciclo para que conseguisse ordenar os números, mas não deu certo 

 

Em 12/11/2021 às 12:53, arfneto disse:

Entendeu o que eu expliquei?

Infelizmente não 

Em 12/11/2021 às 12:53, arfneto disse:

Você percebeu o que fez com a função gravar()?

Percebi que inseri ela errada e fora da estrutura

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

30 minutos atrás, Weverson Meireles disse:

Infelizmente não 

 

E não tem uma única pergunta?

 

E mesmo assim continuou o programa seguindo a partir dos exemplos que te mostrei e que você não entendeu? 

 

31 minutos atrás, Weverson Meireles disse:

Percebi que inseri ela errada e fora da estrutura

 

Você não inseriu de forma errada. Apenas copiou a função que mostra e nela o último parâmetro é o título, e aí criou um arquivo com esse nome folclórico em sua máquina. E nem viu.

 

33 minutos atrás, Weverson Meireles disse:
 for ( i=0; i<n; i++){
				 printf("%d", vetor[i]);

 

Acho que sabe que eu te mostrei uma função mostrar() :D que faz isso para o vetor. Não seria o caso de usar?

 

34 minutos atrás, Weverson Meireles disse:
int n = 10000;
				 quick(vetor, 0, n);
				 
				 for ( i=0; i<n; i++){
				 printf("%d", vetor[i]);

Eu tentei inserir esse ciclo para que conseguisse ordenar os números, mas não deu certo 

 

 

Sei.

 

E onde está o código todo? Como vamos saber o que fez para criar o vetor?

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Em 13/11/2021 às 19:31, arfneto disse:

Acho que sabe que eu te mostrei uma função mostrar() :D que faz isso para o vetor. Não seria o caso de usar?

 

Eu tentei usa-la mas não estou conseguindo mudar a função mostrar. Parece ser uma coisa boba mas não esta funcionando pra mim. 

Primeiro tentei usar o gravar sozinho e depois a função mostrar. A parte do QuickSort eu deixei estruturado sem chama-lo. (Estrutura que peguei pronta).

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define TAM 10000

int dividir (int vetor[], int esq, int dir){
	int aux;
	int cont = esq;
	
	for(int i = esq+1; i <= dir; i++){
		
		if(vetor[i] < vetor[esq]){
			cont++;
			aux = vetor[i];
			vetor[i] = vetor[cont];
			vetor[esq] = aux;
			
		}
		
	}
	aux = vetor[esq];
	vetor[esq] = vetor[cont];
	vetor[cont] = aux;
	
	return cont;
}

void quick(int vetor[], int esq, int dir){
	int pos;
	
	if(esq < dir){
	pos = dividir(vetor, esq, dir);
		quick(vetor, esq, pos-1);
		quick(vetor, pos+1, dir);
	}
}

int gravar(int vetor[], int n, int c, const char* arquivo);

int main(void)
{
    int vet[TAM];
    srand(211110);
    for (int i = 0; i < TAM; i += 1) vet[i] = 1 + rand()%TAM;
    gravar(vet, 10000, 100, "os primeiros 10000, 100 por linha");
    
    return 0;
}

	int gravar(int vetor[], int n, int c, const char* arquivo) {
		// grava n elementos do vetor no arquivo, c el. por linha
		FILE* arq = fopen(arquivo, "w");
		if(arq == NULL) 
		return -1;
		int col = 0;
		for (int i = 0; i < n; i += 1){
			fprintf(arq, "%6i", vetor[i]);
			col +=1;
			if (col == c){
				fprintf(arq, "\n");
				col = 0;
			}
		};
		fprintf(arq,"\n");
		return 0;
	};
	
int mostrar(int vetor[], int n, int c, const char* msg){

 // mostrar n elementos do vetor em c colunas na tela
  if (msg != NULL) printf("\n%s\n", msg);
  int col = 0;
  for (int i = 0; i < n; i += 1)
 {
	printf("%6i ", vetor [i]);
	col += 1;
	if (col == c)
	{
		printf("\n");
		col = 0;
	}
 };
 printf("\n");
 return n;
};

 

12 minutos atrás, Weverson Meireles disse:
int gravar(int vetor[], int n, int c, const char* arquivo) {
		// grava n elementos do vetor no arquivo, c el. por linha
		FILE* arq = fopen(arquivo, "w");
		if(arq == NULL) 
		return -1;
		int col = 0;
		for (int i = 0; i < n; i += 1){
			fprintf(arq, "%6i", vetor[i]);
			col +=1;
			if (col == c){
				fprintf(arq, "\n");
				col = 0;
			}
		};
		fprintf(arq,"\n");
		return 0;
	};

 

E como no exercício se pede para que eu faça a leitura de um arquivo e ordena-lo, devo substituir o meu antigo programa que deveria fazer isso, por este?

Sabendo que o meu antigo, como me mostrou, possui muitos erros.

  • Amei 1
Link para o comentário
Compartilhar em outros sites

@Weverson Meireles   esse seu código não está criando o arquivo txt , por que você não colocou o tipo do arquivo ,  ao enviar o nome do arquivo para a função gravar tem três erros , 1 - nome de arquivo não pode ter espaços em branco então precisa substituir por underline, ou outro caractere qualquer , 2 - mas uma variável const não pode ter os dados modificados , só podem ser Lidos , então adicione esses caracteres lidos em outra variável simples e use ela para criar ou abrir o arquivo ,  3 -  mas ainda falta o tipo de arquivo , então use a função strcat para completar o   "nome_do_arquivo.txt"   ,   e essa função gravar ficou assim  :

int gravar(int vetor[], int n, int c, const char* arquivo) 
{                                      /// const char ponteiro
    char aux[200];                     /// receber os caracteres do nome arquivo
                                       /// grava n elementos do vetor no arquivo, c el. por linha
    for(i=0; arquivo[i] != 0; i++)     /// o nome de arquivo não pode ter espacos em branco
    {
        aux[i] = arquivo[i];           /// só pode ler nessa variavel const char arquivo
        if(arquivo[i] == ' ' )         /// se for espaco
        {
            aux[i] = '_';              /// substitui os espacos por UnderLine
        }
    }
    strcat(aux,".txt");                /// adiciona o tipo de arquivo no nome do arquivo .txt
    printf("\n\nAUX --> %s\n",aux);    /// ver se concatenou mesmo
    FILE* arq = fopen(aux, "a");       /// usa a variaveL auxiliar e tenta abrir o arquivo para gravar a 
                                       /// partir do finaL dele
    if(arq == NULL)                    /// por qq erro
        arq = fopen(aux,"w");          /// cria reseta e abre o arquivo para gravar nele a partir no iníco dele
    if( ! arq )return -1;              /// por qq outro erro sai do programa e volta para o windows com msg 
                                       /// de erro valor -1
    int col = 0;
    for ( i = 0; i < n; i += 1)
    {
        fprintf(arq, "%6d", vetor[i]); /// escreve em colunas de 6 dígitos no arquivo
        col +=1;
        if (col == c)
        {
            fprintf(arq, "\n");
            col = 0;
        }
    }
    fprintf(arq,"\n");
    return 0;
}

 

Link para o comentário
Compartilhar em outros sites

27 minutos atrás, devair1010 disse:

esse seu código não está criando o arquivo txt , por que você não colocou o tipo do arquivo ,  ao enviar o nome do arquivo para a função gravar tem três erros , 1 - nome de arquivo não pode ter espaços em branco então precisa substituir por underline, ou outro caractere qualquer , 2 - mas uma variável const não pode ter os dados modificados , só podem ser Lidos , então adicione esses caracteres lidos em outra variável simples e use ela para criar ou abrir o arquivo ,  3 -  mas ainda falta o tipo de arquivo , então use a função strcat para completar o   "nome_do_arquivo.txt"

 

Outra coisa que percebi também é que esse código não esta gerando valores distintos. Como eu poderia fazer com que gerasse? 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

 

1 hora atrás, devair1010 disse:

@Weverson Meireles    creio que possa ser  semente de Rand ,

experimente assim :

#include <time.h>
int main()
{
    srand(time(NULL)); /// aqui logo no início e só precisa uma vez em todo o código

 

Vou repetir o que eu disse no tópico 8. Sugiro testar:

 

Citação

 

Apenas NÃO use o ingênuo 
 

srand(time(NULL));

 

Como parece ser automático nas escolas e livros. Use um valor conhecido e reproduzível. Assim pode sempre testar seu programa com os mesmos números e qualquer tamanho.

O que fez com o programa que copiou?

 

 

 

1 hora atrás, Weverson Meireles disse:

 

Outra coisa que percebi também é que esse código não esta gerando valores distintos. Como eu poderia fazer com que gerasse? 

 

 

Acho que se lembra do post #22 onde tem um exemplo da saída de mostra() chamada 3 vezes para o mesmo vetor, em

 

https://www.clubedohardware.com.br/forums/topic/1572565-quicksort-ordenação-dentro-de-arquivo/#comment-8305356 e era algo assim

 

os primeiros 20, 4 por linha
     8     96     88     28
    25     77     62     97
    40     46     86     77
    82     77     49     42
     5     68     60     91


os primeiros 18, 6 por linha
     8     96     88     28     25     77
    62     97     40     46     86     77
    82     77     49     42      5     68



mostrar() 80x8 sem um titulo:
     8     96     88     28     25     77     62     97
    40     46     86     77     82     77     49     42
     5     68     60     91     95     72     68     63
     8     31     59      3     21     75     29     17
    83     64     90     34     65     65     10     66
    78     74     41     62     87     13     40     71
    16     74     67     88     40     39     57      7
    50     83      5     64     73     38     78     35
     7     18     85     65     26     25     13     24
    79     91     35     54     59     53     71     91

 

Com valores aleatórios entre 1 e TAM

 

1 hora atrás, devair1010 disse:

esse seu código não está criando o arquivo txt , por que você não colocou o tipo do arquivo

 

Não, @devair1010, não é o caso. Arquivos nem precisam de extensão. E o nome do arquivo é o último parâmetro. Acontece que o autor do tópico juntou duas funções que eu mostrei para ele e chamou sem pensar, usando o título usado em gravar() como nome do arquivo me mostrar() porque não entendeu que eu estava mostrando que era mais fácil criar mostrar() até o arquivo parecer ok e aí mudar 3 linhas e criar o arquivo, algo trivial em C. E eu mostrei até uma imagem das duas funções lado a lado...

 

image.png.8665a86ac2fde174dc9fc9697cbd1b13.png

 

:(

 

3 horas atrás, Weverson Meireles disse:

Eu tentei usa-la mas não estou conseguindo mudar a função mostrar. Parece ser uma coisa boba mas não esta funcionando pra mim. 

Primeiro tentei usar o gravar sozinho e depois a função mostrar. A parte do QuickSort eu deixei estruturado sem chama-lo. (Estrutura que peguei pronta).

 

Vou resumir o que essas funções fazem, o mesmo que está no comentário em verde no início de cada uma:

  • mostrar() mostra o vetor na tela, o vetor de tamanho n. Em c colunas por linha e com um título opcional
  • gravar() grava o vetor em disco, o vetor de tamanho n. Em c colunas por linha e o nome do arquivo é o último parâmetro

 

3 horas atrás, Weverson Meireles disse:

E como no exercício se pede para que eu faça a leitura de um arquivo e ordena-lo, devo substituir o meu antigo programa que deveria fazer isso, por este?

Sabendo que o meu antigo, como me mostrou, possui muitos erros

 

Se lembra de quando eu escrevi isso:

image.png.40e86301a1151d67969091287a4cc1ae.png 

 

Sugiro de novo que faça nessa ordem.

 

 

1 hora atrás, devair1010 disse:

1 - nome de arquivo não pode ter espaços em branco então precisa substituir por underline, ou outro caractere qualquer

 

 

Devair, o nome de arquivo pode ter espaços. Não escreva isso. Não usa Windows? Notou que todo computador tem uma pasta, por exemplo, chamada "Arquivos de Programas" no Windows em Português????

 

 

Outro EXEMPLO

 

Esta é a saída


os primeiros 80, 10 por linha
     8     96     88     28     25     77     62     97     40     46
    86     77     82     77     49     42      5     68     60     91
    95     72     68     63      8     31     59      3     21     75
    29     17     83     64     90     34     65     65     10     66
    78     74     41     62     87     13     40     71     16     74
    67     88     40     39     57      7     50     83      5     64
    73     38     78     35      7     18     85     65     26     25
    13     24     79     91     35     54     59     53     71     91


os primeiros 20, 4 por linha
     8     96     88     28
    25     77     62     97
    40     46     86     77
    82     77     49     42
     5     68     60     91


os primeiros 18, 6 por linha
     8     96     88     28     25     77
    62     97     40     46     86     77
    82     77     49     42      5     68



mostrar() 80x8 sem um titulo:
     8     96     88     28     25     77     62     97
    40     46     86     77     82     77     49     42
     5     68     60     91     95     72     68     63
     8     31     59      3     21     75     29     17
    83     64     90     34     65     65     10     66
    78     74     41     62     87     13     40     71
    16     74     67     88     40     39     57      7
    50     83      5     64     73     38     78     35
     7     18     85     65     26     25     13     24
    79     91     35     54     59     53     71     91


gravando "num.txt" com o vetor inteiro
"num.txt" gravado ok!

 

Desse programa

 

#define TAM 100

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

int gravar(int[], int, int, const char*);
int mostrar(int[], int, int, const char*);

int main(void)
{
    int vet[TAM];
    srand(211110);
    for (int i = 0; i < TAM; i += 1) vet[i] = 1 + rand() % TAM;
    mostrar(vet, 80, 10, "os primeiros 80, 10 por linha");
    mostrar(vet, 20, 4, "os primeiros 20, 4 por linha");
    mostrar(vet, 18, 6, "os primeiros 18, 6 por linha");
    printf("\n\nmostrar() 80x8 sem um titulo:\n");
    mostrar(vet, 80, 8, NULL);

    const char* arquivo = "num.txt";
    printf("\ngravando \"%s\" com o vetor inteiro\n", arquivo);
    int res = gravar(vet,TAM,10,arquivo); // cria
    if (res == 0)
        printf("\"%s\" gravado ok!\n", arquivo);
    else
        printf("Erro tentando criar \"%s\"\n", arquivo);
    return 0;
}




int gravar(int vetor[], int n, int c, const char* arquivo) { 
    // grava n elementos do vetor no arquivo, c el. por linha
    FILE* arq = fopen(arquivo, "w");
    if (arq == NULL) return -1;
    int col = 0;
    for (int i = 0; i < n; i += 1) {
        fprintf(arq, "%6i ", vetor[i]);
        col += 1;
        if (col == c) {
            fprintf(arq, "\n");
            col = 0;
        }
    };
    fprintf(arq,"\n");
    return 0;
};





int mostrar(int vetor[], int n, int c, const char* msg)
{  // mostra n elementos do vetor em c colunas na tela
    if (msg != NULL) printf("\n%s\n", msg);
    int col = 0;
    for (int i = 0; i < n; i += 1)
    {
        printf("%6i ", vetor[i]);
        col += 1;
        if (col == c)
        {
            printf("\n");
            col = 0;
        }
    };
    printf("\n");
    return n;
};

// https:// www.clubedohardware.com.br/forums/topic/
// 1572565-quicksort-ordena%C3%A7%C3%A3o-dentro-de-arquivo/

 

ABAIXO Atente para as diferentes chamadas e o que aparece na tela...

 

Claro, depois de rodar o programa vai ter o arquivo no disco com os mesmos dados.

 

Acho que nem tentou entender o que expliquei sobre passar de uma função para outra :( 

 

    mostrar(vet, 80, 10, "os primeiros 80, 10 por linha");
    mostrar(vet, 20, 4, "os primeiros 20, 4 por linha");
    mostrar(vet, 18, 6, "os primeiros 18, 6 por linha");
    printf("\n\nmostrar() 80x8 sem um titulo:\n");
    mostrar(vet, 80, 8, NULL);
// ...    
    int res = gravar(vet,TAM,10,arquivo); // cria

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

6 horas atrás, arfneto disse:

Acho que se lembra do post #22 onde tem um exemplo da saída de mostra() chamada 3 vezes para o mesmo vetor, em

 

Lembro sim, por isso percebi que estava gerando números aleatórios dentro do intervalo porém alguns números repetidos. 

 

Por isso a ideia de usar o srand:

6 horas atrás, arfneto disse:
srand(time(NULL))

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

2 minutos atrás, Weverson Meireles disse:

Lembro sim, por isso percebi que estava gerando números aleatórios dentro do intervalo porém alguns números repetidos

 

Que quer dizer com isso? Números aleatórios se repetem. Esse é o conceito de aleatoriedade. 

Se quer uma permutação ou uma combinação entenda que isso é outra coisa e não tem a ver com srand()

e mais uma vez, a terceira, vou dizer: evite a ingênua mania de usar srand(time(NULL)). Em testes você precisa de sequências facilmente reproduzíveis.

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

56 minutos atrás, arfneto disse:

Que quer dizer com isso? Números aleatórios se repetem. Esse é o conceito de aleatoriedade. 

Se quer uma permutação ou uma combinação entenda que isso é outra coisa e não tem a ver com srand()

e mais uma vez, a terceira, vou dizer: evite a ingênua mania de usar srand(time(NULL)). Em testes você precisa de sequências facilmente reproduzíveis.

 

Como eu poderia fazer com que este programa gerasse um arquivo com números desordenados e que não se repetissem? 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

34 minutos atrás, Weverson Meireles disse:

Como eu poderia fazer com que este programa gerasse um arquivo com números desordenados e que não se repetissem?

 

Então não são aleatórios como disse desde o início.

 

Eu postei aqui programas que fazem isso, em C e C++. Pode buscar no meu perfil, por exemplo em 

 

 

 

Em geral faz como o bingo da igreja ou o sorteio da loteria. 

 

Exemplo:  para um grupo de 100 bolinhas numeradas quer um grupo de 30.

 

Escolhe uma entre as 100. Sim, aí vai usar rand().

 

Tira essa do conjunto. não sorteio da loteria elas ficam expostas na canaleta. No bingo também.

 

Restam 99 bolinhas para as 29 posições que faltam. Escolhe uma das bolinhas restantes e continua.

 

Restam 98 bolinhas e 28 posições.

 

Continua fazendo a mesma coisa até extrair as 30 bolinhas. . . 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

#include <stdio.h>

int tamVetor = 10;
int vetor[] = { 9, 7, 5, 4, 1, 8, 6, 3, 2, 0 };


void quickSort(int inicio, int final) {
	int i, j, pivo, aux;
	i = inicio;
	j = final-1;
	pivo = vetor[(inicio + final) / 2];
	while(i <= j) {
		while(vetor[i] < pivo && i < final) {
			i++;
		}
		while(vetor[j] > pivo && j > inicio) {
			j--;
		}
		if(i <= j) {
			aux = vetor[i];
			vetor[i] = vetor[j];
			vetor[j] = aux;
			i++;
			j--;
		}
	}
	if(j > inicio)
		quickSort(inicio, j+1);
	if(i < final)
		quickSort(i, final);
}


int buscaSequencial(int elemento) {
	for (int i = 0; i < tamVetor; i++) {
		if (vetor[i] == elemento)
			return i;
	}
	return -1;
}
int buscaBinaria(int elemento, int limEsq, int limDir) {
	int meio = (limEsq + limDir)/2;
	if (vetor[meio] == elemento)
		return meio;
	
	if (limEsq >= limDir)
		return -1; // não encontrado
	
	else if (vetor[meio] < elemento)
		return buscaBinaria(elemento, meio+1, limDir);
	else
		return buscaBinaria(elemento, limEsq, meio-1);
}



int main(void) {

	for(int i=0; i< tamVetor; i++) {
		printf("%i\n", vetor[i]);
	}

	puts("Pos ordenacao\n\n");
  
    quickSort(0, 9);
   
	for(int i=0; i< tamVetor; i++) {
		printf("%i\n", vetor[i]);
	}
	
}

 

Com este programa eu conseguiria fazer o que a questão me pede?

Claro, modificando

 

 

Ideia de onde tirei que usa varias funções de ordenação:

 

#include <stdio.h>

int tamVetor = 10;
int vetor[] = { 9, 7, 5, 4, 1, 8, 6, 3, 2, 0 };

void insertionSort() {

    for (int i = 1; i < tamVetor; i++) {
		int item = vetor[i];
		int j = i - 1;
		
		while ((j >= 0) && (vetor[j] > item)) {
			vetor[j + 1] = vetor[j];
			j--;
		}
		
		vetor[j + 1] = item;
	}
}
void selectionSort() { 
	int aux, min;
	for (int i = 0; i < (tamVetor-1); i++) {
		min = i;
		for (int j = (i+1); j < tamVetor; j++) {
			if(vetor[j] < vetor[min]) 
				min = j;
		}
		if (i != min) {
			aux = vetor[i];
			vetor[i] = vetor[min];
			vetor[min] = aux;
		}
	}
}
void bubbleSort(int posicao){ 
    if (posicao < 1)return; 
 
    for (int i=0; i< posicao; i++) {
        if (vetor[i] > vetor[i+1]) {
        	int temp = vetor[i];
		    vetor[i] = vetor[i+1];
		    vetor[i+1] = temp; 
		}
	}
    bubbleSort(posicao-1); 
}
void quickSort(int inicio, int final) {
	int i, j, pivo, aux;
	i = inicio;
	j = final-1;
	pivo = vetor[(inicio + final) / 2];
	while(i <= j) {
		while(vetor[i] < pivo && i < final) {
			i++;
		}
		while(vetor[j] > pivo && j > inicio) {
			j--;
		}
		if(i <= j) {
			aux = vetor[i];
			vetor[i] = vetor[j];
			vetor[j] = aux;
			i++;
			j--;
		}
	}
	if(j > inicio)
		quickSort(inicio, j+1);
	if(i < final)
		quickSort(i, final);
}
void heapSort(int n) {
   int i = n / 2, pai, filho, t;
   while(true) {
      if (i > 0) {
          i--;
          t = vetor[i];
      } else {
          n--;
          if (n <= 0) return;
          t = vetor[n];
          vetor[n] = vetor[0];
      }
      pai = i;
      filho = i * 2 + 1;
      while (filho < n) {
          if ((filho + 1 < n)  &&  (vetor[filho + 1] > vetor[filho]))
              filho++;
          if (vetor[filho] > t) {
             vetor[pai] = vetor[filho];
             pai = filho;
             filho = pai * 2 + 1;
          } else {
             break;
          }
      }
      vetor[pai] = t;
   }
}

int buscaSequencial(int elemento) {
	for (int i = 0; i < tamVetor; i++) {
		if (vetor[i] == elemento)
			return i;
	}
	return -1;
}
int buscaBinaria(int elemento, int limEsq, int limDir) {
	int meio = (limEsq + limDir)/2;
	if (vetor[meio] == elemento)
		return meio;
	
	if (limEsq >= limDir)
		return -1; // não encontrado
	
	else if (vetor[meio] < elemento)
		return buscaBinaria(elemento, meio+1, limDir);
	else
		return buscaBinaria(elemento, limEsq, meio-1);
}



int main(void) {

	for(int i=0; i< tamVetor; i++) {
		printf("%i\n", vetor[i]);
	}

	puts("Pos ordenacao\n\n");
    //insertionSort();
    //selectionSort();
    //bubbleSort(tamVetor-1);
    //quickSort(0, 9);
    heapSort(10);
	for(int i=0; i< tamVetor; i++) {
		printf("%i\n", vetor[i]);
	}
	
}

 

 

Sabendo que, tenho que mostrar números de 0 a 10000 que não se repetem e fora de ordem. 

 

Sabendo que esses números não deverão estar declarados em um vetor como no programa a cima  e sim a leitura de um arquivo com esses números assim declarando no vetor.  

 

 

E pelo o que estava estudando por slides do próprio professor, devo usar este programa mesmo para gerar o arquivo que deve ser usado nesta questão:

 

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

const int TAM = 10001;
int vet[TAM];

void preencher() {
	for (int i=1; i<TAM; i++) {
		vet[i] = rand() % 10001;
	}
}

void salvar() {
	FILE *arq = fopen("10000num.txt", "w");
	for (int i=1; i<TAM; i++) {
		fprintf(arq, "%i\n", vet[i]);
	}
	fclose(arq);
}


int main(void) {
	srand(time(NULL));
	
	preencher();
	
	for (int i=1; i<TAM; i++) {
		printf("%i\n", vet[i]);
	}
	
	salvar();
	
}

 

E uma duvida gerada a partir deste programa é:

Como poderia usar a função "salvar()" para salvar em disco?

Pelo programa já esta salvo?

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Eu consegui ordenar e fazer com que não se repitam os números usando o "srand" 

fiz com números de 0 a 9. 

Agora quero saber como eu faria para pegar os números gerados em um arquivo e ordenasse nesse programa:

 

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

const int MAX = 10;
int vetor[MAX];

void preencher() {
	for (int i=1; i<MAX; i++) {
		vetor[i] = rand() % 10;
	}
}

void quickSort(int inicio, int final) {
	int i, j, pivo, aux;
	i = inicio;
	j = final-1;
	pivo = vetor[(inicio + final) / 2];
	while(i <= j) {
		while(vetor[i] < pivo && i < final) {
			i++;
		}
		while(vetor[j] > pivo && j > inicio) {
			j--;
		}
		if(i <= j) {
			aux = vetor[i];
			vetor[i] = vetor[j];
			vetor[j] = aux;
			i++;
			j--;
		}
	}
	if(j > inicio)
		quickSort(inicio, j+1);
	if(i < final)
		quickSort(i, final);
}


int buscaSequencial(int elemento) {
	for (int i = 0; i < MAX; i++) {
		if (vetor[i] == elemento)
			return i;
	}
	return -1;
}
int buscaBinaria(int elemento, int limEsq, int limDir) {
	int meio = (limEsq + limDir)/2;
	if (vetor[meio] == elemento)
		return meio;
	
	if (limEsq >= limDir)
		return -1; // não encontrado
	
	else if (vetor[meio] < elemento)
		return buscaBinaria(elemento, meio+1, limDir);
	else
		return buscaBinaria(elemento, limEsq, meio-1);
}



int main(void) {
	
int i = 0, j, igual;

srand(time(NULL));
	
	preencher();
	
	do{
		vetor[i] = rand() % 10;
		igual = 0;
		for(j = 0; j < i; j++){
			if(vetor[j] == vetor[i])
			igual = 1;
		}
		if(igual == 0)
		     i++;
	}while(i < 10);
	
	for(i = 0; i < 10; i++){
	printf("%d\n", vetor[i]);	
	}




	puts("Pos ordenacao\n\n");
  
    quickSort(0, 10);
   
	for(int i=0; i< MAX; i++) {
		printf("%i\n", vetor[i]);
	}
}

 

5 horas atrás, Weverson Meireles disse:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

const int TAM = 10001;
int vet[TAM];

void preencher() {
	for (int i=1; i<TAM; i++) {
		vet[i] = rand() % 10001;
	}
}

void salvar() {
	FILE *arq = fopen("10000num.txt", "w");
	for (int i=1; i<TAM; i++) {
		fprintf(arq, "%i\n", vet[i]);
	}
	fclose(arq);
}


int main(void) {
	srand(time(NULL));
	
	preencher();
	
	for (int i=1; i<TAM; i++) {
		printf("%i\n", vet[i]);
	}
	
	salvar();
	
}

Números gerados nesse arquivo.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

5 horas atrás, Weverson Meireles disse:

Eu consegui ordenar e fazer com que não se repitam os números usando o "srand" 

fiz com números de 0 a 9. 

 

??

 

Leu o exemplo passo a passo que eu mostrei naquele link, aquele programa com as cores? Entendeu aquilo?

Entendeu o lance do bingo? É o que tem que fazer. O que tentou fazer com rand --- e não srand --- como escreveu está errado.

 

Como te disse esse é um problema de combinatória. Nada tem a ver com números aleatórios. O sorteio é feito com as posições, não com os números

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Weverson Meireles     para pegar os números que estejam em um arquivo , você pode usar o comando fopen para abrir o arquivo  , que esteja na mesma pasta desse programa , e ler com a função fscanf , que lê um conjunto de caracteres  até encontrar um espaço em branco , ou também o  EOF ,  então para ler e armazenar no vetor pode ser assim  :

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

const int MAX = 10;
int vetor[MAX];                          /// desaconselhacel usar variaveis global 
int quickSort(int inicio, int final);
float ler_do_arquivo(char a[]);          /// prototipo das funcoes
int main(void)
{
	int i = 0, j, igual;
	char nom[30] = { "qq_coisa" };
	srand(time(NULL));
	printf("o nome do arquivo ");
	fgets(nom, sizeof(nom), stdin);
	nom[strlen(nom) - 1] = 0;
	ler_do_arquivo(nom);
	///  preencher();  o vetor será preenchido com numeros do arquivo
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", vetor[i]);
	}
	puts("Pos ordenacao\n\n");
	quickSort(0, 10);
	for (int i = 0; i < MAX; i++)
	{
		printf("%i\n", vetor[i]);
	}
}
int quickSort(int inicio, int final)
{
	int i, j, pivo, aux;
	i = inicio;
	j = final - 1;
	pivo = vetor[(inicio + final) / 2];
	while (i <= j) {
		while (vetor[i] < pivo && i < final)
		{
			i++;
		}
		while (vetor[j] > pivo && j > inicio)
		{
			j--;
		}
		if (i <= j)
		{
			aux = vetor[i];
			vetor[i] = vetor[j];
			vetor[j] = aux;
			i++;
			j--;
		}
	}
	if (j > inicio)
		quickSort(inicio, j + 1);
	if (i < final)
		quickSort(i, final);
	return 0;
}
float ler_do_arquivo(char nom[])
{
	FILE* arq;
	char num[20] = {};
	int i = -1;
	arq = fopen(nom, "r");
	if (!arq)return 4096.2048;
	while (fscanf(arq, "%s", num) != EOF)
	{
		vetor[++i] = atof(num);
		if (i > 9) break; /// limite de qtd de numeros no vetor
		printf("%d ", vetor[i]);
	}
	printf("\n\n");
	fclose(arq);
	return 2048.65535;
}

 

Link para o comentário
Compartilhar em outros sites

1 hora atrás, devair1010 disse:

para pegar os números que estejam em um arquivo , você pode usar o comando fopen para abrir o arquivo  , que esteja na mesma pasta desse programa , e ler com a função fscanf , que lê um conjunto de caracteres  até encontrar um espaço em branco , ou também o  EOF ,  então para ler e armazenar no vetor pode ser assim  :

Consegui ler mas como eu leio o arquivo, aprensento e depois apresento novamente desordenado e ordenado, fica pesado e o programa fecha, pois são 10000 números kk. Como poderia minimizar isso? por exemplo puxar pra apresentar somente uma vez o desordenado? 

Mas testei com poucos números alterando o limite e deu certo. so q apresenta o desordenado duas vezes antes do ordenado.

 

 

 

2 horas atrás, arfneto disse:

Leu o exemplo passo a passo que eu mostrei naquele link, aquele programa com as cores? Entendeu aquilo?

Entendeu o lance do bingo? É o que tem que fazer. O que tentou fazer com rand --- e não srand --- como escreveu está errado.

 

Como te disse esse é um problema de combinatória. Nada tem a ver com números aleatórios. O sorteio é feito com as posições, não com os números

Li sim sobre o programa exemplo que me mandou, mas quis tentar com o que tenho um pouco de conhecimento. Acredito que tenha dado certo com o complemento que o colega mandou a cima. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Weverson Meireles disse:

fica pesado e o programa fecha, pois são 10000 números kk

 

10.000 números são praticamente nada para computadores modernos. Nada "pesado".

 

2 horas atrás, Weverson Meireles disse:

Li sim sobre o programa exemplo que me mandou, mas quis tentar com o que tenho um pouco de conhecimento

 

Não entendo o que quer dizer. Se trata de um algoritmo e C.

 

2 horas atrás, Weverson Meireles disse:

Acredito que tenha dado certo com o complemento que o colega mandou a cima.

 

Se deu certo é algo objetivo. Não precisa acreditar. Apenas teste. O  " complemento"  seria ler o arquivo?

3 horas atrás, devair1010 disse:
float ler_do_arquivo(char nom[])

 

porque uma função que lê de um arquivo retorna float? Pode dar 0.05 certo?

 

Ler de um vetor global não é uma boa ideia. E é proibido pelas regras comuns de conduta em escolas e empresas

 

@devair1010 entenda que essa função recebe o nome do arquivo como parâmetro mas não o vetor. Isso quer dizer que pode ler vários arquivos, mas todos dentro do MESMO vetor. É bem estranho. Compare com o comum, como a função gravar() que eu mostrei e vai entender a diferença.

 

O simples é passar o nome do arquivo e o endereço do vetor. E retornar algo negativo em caso de erro e algo como o clássico zero em caso de sucesso ou simplesmente o total de números lidos, que pode ser útil em muitos casos.

 

while (fscanf(arq, "%s", num) != EOF)
	{
		vetor[++i] = atof(num);
		if (i > 9) break; /// limite de qtd de numeros no vetor
		printf("%d ", vetor[i]);
	}

 

Qual o propósito de converter para float dados de uma string e depois colocar em um vetor que é int[MAX] que é 10 no caso e testar com 9 e depois mostrar na tela como int de novo, numa única e bem comprida linha que no final va ter 10.000 números?

 

Compare coma função mostra() que eu postei e que recebe o número de colunas e o nome do vetor. É mais  útil, e é o comum por essa razão.

 

Se i vai de -1 a 9 não seria o simples usar um for? 

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@arfneto     eu não quis modificar o código   do    @Weverson Meireles   e apenas para ler do arquivo e inserir no vetor ,   e também a conversão de string para float  seria que se houver algum número decimal no arquivo vai converter ele também ,  e usando int  "%d"  , na  leitura  com fscanf está apresentando erro que não consegui descobrir o que é e nem como concerta-lo  ,  e lendo como string  não deu nenhum erro , a imagem do erro no visual studio 

788214211_debugnovstudio.jpg.a0cbb03c7ca1e2e07f19c043d0761ab1.jpg

 

usando a função para ler com int  no arquivo ainda com o vetor global , para não modificar o código do  @Weverson Meireles

float ler_do_arquivo(char nom[])
{
  FILE* arq;
  //char num[20] = {};
  int num = {};
  int i = -1;
  arq = fopen(nom, "r");
  if (!arq)return -1;
  while (fscanf(arq, "%d", num) != EOF)
  {
    vetor[++i] = num;//atof(num);
    if (i > 9) break; /// limite de qtd de numeros no vetor
    printf("%d ", vetor[i]);
  }
  printf("\n\n");
  fclose(arq);
  return 0;
}

 

  • Curtir 1
Link para o comentário
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...