ordena.c


/**************************************************/
/* Aluno: Felipe Junqueira                        */
/* N?mero USP: 5603871                            */
/* Exerc?cio-Programa 3 -- Ordena??o              */
/* MAC122 -- BMAC -- 2008 -- Professor: Reverbel  */
/* Compilador: ... gcc 4.3.2                      */
/**************************************************/

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

int reversa, fold, time, numerico, ePadrao; /*vari?veis que trat?o as op??espassadas pela linha de comando*/


int separa (char **v, int p, int r, int (*cmp)(char [], char [])) 
{/*m?todo auxiliar do quicksort*/
	char *c, *aux;
	int i, j;
	i = p+1;
	j = r;
	c = malloc(sizeof(v[p]));
	strcpy(c, v[p]);/*?ndice*/
	 while ( i <= j)
	{ /*divide o vetor em outros 2, desordenados, um com as strings "menores" que o ?ndice e outro com as "maiores"*/                                   
		if((*cmp)(v[i], c) <= 0)
			++i;
		else if((*cmp)(c, v[j]) < 0)
			--j;
		else
		{
			aux = v[i]; v[i] = v[j]; v[j] = aux;
			++i; --j;/*troca uma string maior que est? antes do ?ndice por uma menor que est? depois*/
		}
other
} v[p] = v[j]; v[j] = c; return j; } void quicksort(char **v, int p, int r, int (*cmp)(char [], char [])) { int j; if (p < r) {/*separa o vetor em 2 desordenados, e os ordena separadamente*/
j = separa (v, p, r, (*cmp)); quicksort (v, p, j-1, (*cmp)); quicksort (v, j+1, r, (*cmp)); } return;
other
} void intercala (int p, int q, int r, char **v, int (*cmp)(char [], char [])) {/*fun??o auxiliar do mergesort*/ int i, j, k; char **w; w = malloc((r-p)*sizeof(char)*sizeof(char *));
other
i = p; j = q; k = 0; while (i < q && j < r) {/*percorre os 2 vetores e intercala as strings, com o aux?lio de w, de forma que o vetor fica ordenado percorrendo-o apenas uma vez*/ if ((*cmp)(v[i], v[j]) <=0) w[k++] = v[i++]; else w[k++] = v[j++]; } while (i < q) w[k++] = v[i++]; while (j < r) w[k++] = v[j++]; for (i = p; i < r; ++i) v[i] = w[i-p]; free (w); } void mergesort (int p, int r, char **v, int (*cmp)(char [], char [])) { if (p < r-1) {/*divide o vetor em 2, de tamanho igual (ou quase), ordena-os e depois os intercala*/ int q = (p + r)/2; mergesort (p, q, v, (*cmp)); mergesort (q, r, v, (*cmp)); intercala (p, q, r, v, (*cmp)); } }
other
void insercao (int n, char** v, int (*cmp)(char [], char [])) {/*a cada passo, simplesmente insere um elemento na posi??o certa, movendo todos os outros*/ int i, j; char *aux; for (j = 1; j < n; j++) { aux = v[j]; for (i = j-1; i >= 0 && (*cmp)(v[i], aux) > 0; --i) v[i+1] = v[i];
other
v[i+1] = aux; } } void selecao (int n, char **v, int (*cmp)(char [], char [])) {/*organiza o vetor, a cada passo colocando a menor string na menor posi??o n?o ordenada*/ int i, j, min; char *aux; for (i = 0; i < n-1; ++i) { min = i; for (j = i+1; j < n; ++j) if((*cmp)(v[j], v[min]) < 0) min = j; aux = v[i]; v[i] = v[min]; v[min] = aux; } } void peneira (int p, int m, char **v, int (*cmp)(char [], char []))
{/*m?todo auxiliar do heapsort*/ char *aux; int f = 2*p;
other
aux = v[p]; while (f <= m) { if (f < m && (*cmp)(v[f], v[f+1]) < 0) ++f; if ((*cmp)(aux, v[f]) >= 0) break; v[p] = v[f]; p = f; f = 2*p; } v[p] = aux; } void heapsort (int n, char **v, int (*cmp)(char [], char [])) { int p, m; char *aux; for (p = n/2; p >= 1; --p) peneira (p, n, v, (*cmp)); for (m = n; m >= 2; --m) {
if (v[1] && v[m]) { aux = v[1]; v[1] = v[m]; v[m] = aux; peneira (1, m-1, v, (*cmp)); } } } int compNum(char a[], char b[]) {/*diz qual ? maior, caso a op??o de ordenar pelo n?mero do come?o da linha esteja selecionada*/ if(a == NULL) { if(reversa)/*caso a ordena??o seja reversa, devolve a resposta contr?ria*/ return -1; else return 1; } if(b== NULL) { if(reversa)/*caso a ordena??o seja reversa, devolve a resposta contr?ria*/ return 1; else return -1; } if(a[0] < b[0]) { if(reversa)/*caso a ordena??o seja reversa, devolve a resposta contr?ria*/ return 1; else return -1; } if(a[0] > b[0]) { if(reversa) return -1; else return 1; } else/*o contr?rio de 0 ? 0*/ return 0; } int compAlf(char a[], char b[]) {/*compara o primeiro caractere de cada linha, apresenta resultado invertido caso esteja no mode reverso*/ int i, tam; if(fold) { tam = sizeof(a); for(i = 0; i<tam; i++) a[i] = tolower(a[i]); tam = sizeof(b); for(i=0; i<tam; i++) b[i] = tolower(b[i]); } if(strcmp(a, b) > 0) { if(reversa) return -1; else return 1; } else if(strcmp(a, b) < 0) { if(reversa) return 1; else return -1; } else return 0; } int main(int argc, char *argv[]) { FILE *arq; int i, j, k, l, linhas; long int tam; char a, *entrada, *texto, **v; int (*cmp)(char [], char []); entrada = malloc(100); linhas = 0; reversa = 0; fold = 0; time = 0; numerico = 0; ePadrao = 0; tam = 0; a = ' '; if(argc == 1) {/*caso n?o seja passado um arquivo na inha de comando, toma as providncias neess?rias para executar o programa nesse modo*/ ePadrao = 1; texto = malloc(40000000); while(scanf("%s", entrada) != -1 && (strlen(entrada) + tam + 1)<40000000) { strcat(texto, entrada); tam += strlen(entrada);linhas++; } for(i=0; i<=tam; i++); if(texto[i] == '\n') { texto[i] = '\0'; } if(texto[tam] != '\0') texto[++tam] = '\0'; } else { for(i=1; i<argc-1; i++) {/*l? os par?metros passados na linha de comando */ a = argv[i][1]; switch(a) { case 'f': fold = 1; break; case 't': time = 1; break; case 'n': numerico = 1; break; case 'r': reversa = 1; break; case 'a': a = argv[i][2]; } } strcpy(entrada, argv[i]); arq = fopen(entrada, "r"); fseek(arq, 0, SEEK_END);/*m?todo para descobrir o tamanho do texto*/ tam = ftell(arq);/*vai at? o fim, olha a posi??o e volta ao in?cio*/ texto = malloc(tam+1); rewind(arq); while(fgets(entrada, 100, arq)) {/*l? as palavras do texto e as concatena no vetor*/ strcat(texto, entrada); linhas++; } j = strlen(texto); for(i=0; i<j; i++)/*substitui os '\n' por \'0', garantindo o aspecto de frase*/ if(texto[i] == '\n') texto[i] = '\0'; } if(numerico == 1)/*decide se a ordem vai ser alfab?tica ou num?rica, selecionando a compara??o adequada*/ cmp = compNum; else cmp = compAlf; v = malloc(linhas * sizeof(char *)); j = 0; for(i=0; i<tam; i++) { for(k=0; texto[i] != '\0'; i++) {/*l? uma das palavras*/ entrada[k++] = texto[i]; } v[j] = malloc(k*sizeof(char)); for(l=0; l<k; l++) {/*aloca mem?ria suficiente e armazena ela no vetor de ponteiros*/ v[j][l] = entrada[l]; } j++; } switch(a) { case 'H': heapsort(tam, v, (*cmp)); break; case 'I': insercao(tam, v, (*cmp)); break; case 'M': mergesort(0, tam, v, (*cmp)); break; case 'S': selecao(tam, v, (*cmp)); break; default: quicksort(v, 0, tam, (*cmp)); } for(i=0; i<linhas; i++) {/*imprime o vetor ordenado e libera a mem?ria alocada*/ printf("%s\n", v[i]); free(v[i]); } free(v); return 0; }