Ir ao conteúdo
  • Cadastre-se

jcgs98

Membro Pleno
  • Posts

    90
  • Cadastrado em

  • Última visita

posts postados por jcgs98

  1. void remRepListaOrd(TLista *L2,TLista *U2)
    {
        TLista L=*L2, U=*U2;
        
        if ((!L)||(!L->prox)) return;
        
        remover (&L->prox, &U,L->valor);
        
        remRepListaOrd(&L->prox,&U);
    }

     

    agora, Comunista.RJ disse:
    
    void remRepListaOrd(TLista *L2,TLista *U2)
    {
        TLista L=*L2, U=*U2;
        
        if ((!L)||(!L->prox)) return;
        
        remover (&L->prox, &U,L->valor);
        
        remRepListaOrd(&L->prox,&U);
    }

     

    uso a função de remover a partir do próximo da lista.

    @devair1010 Não deve ter rodado por causa dessa forma de "escrever":

     

    (*U)?novo->ant=*U,(*U)->prox=novo,*U=novo:*L = novo;

     

    Tenta mudar.

     

    Por exemplo,

     

    (*U)?novo->ant=*U,(*U)->prox=novo,*U=novo:*L = novo;

     

    é igual a:

     

    if (*U) { novo->ant=*U; (*U)->prox=novo; *U=novo; }

    else

    *L = novo;

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct No
    {
       int valor;
       struct No *prox, *ant;
    } TNo;
    
    typedef TNo* TLista;
    
    int inserir (TLista *L, TLista *U, int num);
    int remover (TLista *L, TLista *U,int numero);
    int alterar (TLista L, int velho, int novo);
    TLista pesquisar (TLista L, int num);
    void exibir (TLista L);
    void exibirAoContrario (TLista U);
    void clonar (TLista *L, TLista L2);
    int inserirNaPosicao (TLista *L, TLista *U, int posicao, int numero);
    int menu (TLista L, TLista L2);
    int tamanho (TLista L);
    void insereFim(TLista *L, TLista *U, int numero);
    void botarCrescente(TLista *L);
    void inverterLista (TLista *L,TLista *U);
    float media(TLista L2);
    int pesquisaMaior(TLista L2);
    int pesquisaMenor(TLista L2);
    float somaDosElementos(TLista L2);
    void remRepListaOrd(TLista *L, TLista *U);
    
    
    int main ()
    {
    	TLista L=NULL, L2=NULL, U=NULL, pos;
    	
    	int num1, num2, op;
    	
    	do
    	{
    		system ("cls");
          	op = menu (L, L2);
          
          	switch (op)
          	{
    //INSERIR
    			case 1: printf ("Entre com o número: ");
                        scanf ("%d", &num1);					
    					(inserir (&L, &U, num1))?printf ("Inserção realizada!\n"):printf ("ERRO: Inserção não realizada!\n");
                     	break;
    //REMOVER
             	case 2: printf ("Entre com o número a ser removido: ");
    					scanf ("%d", &num1);                 	
    					printf ((!remover (&L, &U, num1))?"ERRO: Remoção não realizada!\n":"Remoção realizada %i vezes!\n", remover (&L, &U, num1));
                     	break;
    //ALTERAR
             	case 3: printf ("Entre com o número a ser alterado: ");
                     	scanf ("%d", &num1);                 
                     	printf ("Entre com o novo número: ");
                     	scanf ("%d", &num2);                 
                     	printf ((alterar (L, num1, num2))?"Alteração realizada!\n":"ERRO: Alteração não realizada!\n");
                     	break;
    //PESQUISAR
             	case 4: printf ("Entre com o número a ser pesquisado: ");
                     	scanf ("%d", &num1);					               
                     	printf ((pesquisar (L, num1))?"O número foi encontrado na lista!\n":"ERRO: O número não se encontra na lista!\n");
                     	break;
    //EXIBE NORMAL
             	case 5: (!L)?printf("Lista vazia!\n"):printf("Lista: "),exibir (L),printf("\n");
    					break;			
    //EXIBE INVERTIDO
             	case 6: (!U)?printf("Lista vazia!\n"):printf("Lista: "),exibirAoContrario (U),printf("\n");
    					break;
    //CLONAR			
    			case 7: clonar (&L2,L);					
    					break;										
    //INSERE NA POSIÇÃO
             	case 8: printf ("Entre com o número a ser inserido: ");
                     	scanf ("%d", &num1);                 	
    					printf ("Entre com o posicao onde número >>%i<< vai ser inserido: ", num1);
                     	scanf ("%d", &num2);                 	
    					printf ((inserirNaPosicao (&L, &U, num2, num1))?"Insercao realizada!\n":"ERRO: Inserção não realizada!\n");
                     	break;
    //INSERE NO FIM                 	
                case 9:	printf ("Entre com o número a ser inserido: ");
                     	scanf ("%d", &num1);
    					insereFim(&L, &U, num1);
    					break;
    //ORDENA CRESCENTE					
    			case 10:printf((!L)?"Lista vazia!\n":0),botarCrescente(&L);
    					break;					
    //remover repeticao					
    			case 11:remRepListaOrd(&L,&U);
    					break;					
    //INVERTER
    			case 12:inverterLista (&L,&U);
    			        break;
    //fim
                case 0:	printf ("Fim do programa!\n");
                     	break;
    //erro
             	default:printf ("Opção inválida!\nTente novamente!\n");
          }
          system ("pause");
       }
       while (op != 0);
    }
    
    int menu (TLista L, TLista L2)
    {
    	int opcao;
    	system	("cls");
    	printf	("\nTamanho da Lista: %i\n\n",tamanho (L));
    	printf	("Lista: ");exibir (L);
    	printf	("|\n");
    	printf	("Clone: ");exibir (L2);
    	printf	("|\n\n");
    	printf	("Menor elemento da lista......: %i. \n", pesquisaMenor(L));
    	printf	("Maior elemento da lista......: %i. \n", pesquisaMaior(L));	
    	printf	("Media dos elementos da lista.: %.2f. \n\n", media(L));   
       	printf	("Menu de opções:\n\n");
       	printf	("( 1)\tInserir\n( 2)\tRemover\n( 3)\tAlterar\n");
       	printf	("( 4)\tPesquisar\n( 5)\tExibir na Ordem Natural\n");
       	printf	("( 6)\tExibir na Ordem Inversa\n( 7)\tClonar\n");   	
       	printf	("( 8)\tInserir na Posicao\n( 9)\tInsere no Fim\n(10)\tOrdenar Lista\n");   	
       	printf	("(11)\tRemove Repeticoes da lista;
       	printf	("(12)\tInverter Lista\n(13)\tComparar Listas(*FAZER)\n( 0)\tSair\n\n");
       	printf	("Entre Com a Opcao: ");
       	scanf	("%d", &opcao);   
       	return opcao;
    }
    
    int inserir (TLista *L, TLista *U, int num)
    {
    	TLista aux = (TLista) malloc (sizeof(TNo));
       
       	if (!aux)
       	{
        	return 0;
       	}
       	else
       	{
       		aux->valor = num;
    
          	aux->prox = *L;
    
          	aux->ant = NULL;
    
    	  	if (*L)
          	{
             	(*L)->ant = aux;
          	}
    
          	else
          	{
          		*U = aux;
    	  	}
          
          	*L = aux;
          
          	return 1;
       	}
    }
    
    int remover (TLista *L, TLista *U,int numero)
    {
    	TLista aux1, aux2, aux3;
    	
    	int cont;
    	
    	while ((*L) && ((*L)->valor == numero))
    	{
    		aux2 = (*L)->ant;
    	
    		aux1 = (*L)->prox;
    	
    		free (*L);
    	
    		cont++;
    	
    		*L = aux1;
    		
    		(*L)?(*L)->ant = aux2:0;
    	}
    	
    	if (!*L)
    	{
    		*U=NULL;
    	}
    	else
    	{
    		aux2 = *L;
    
    		aux1 = (*L)->prox;
    		
    		while (aux1)
    		{
    			if (aux1->valor == numero)
    			{
    				aux3 = aux2;
    				
    				(*U==aux1)?*U=aux3:0;
    								
    				(aux1->prox)?aux1->prox->ant=aux2:0;
    				
    				aux2->prox = aux1->prox;
    				
    				free (aux1);
    				
    				cont++;
    				
    				aux1 = aux2->prox;
    			}
    			else
    			{
    				aux2 = aux1;
    				
    				aux1 = aux1->prox;
    			}			
    		}
    	}
    
    	return cont;
    }
    
    
    int alterar (TLista L, int velho, int novo)
    {
    	TLista aux = L;
    	
    	int c = 0;
       
       	while (aux)
       	{
        	if (aux->valor == velho)
          	{
            	aux->valor = novo;
    			
    			c++;
          	}
          	aux = aux->prox;
       	}
    
        return c;
    }
    
    TLista pesquisar (TLista L, int num)
    {
    	if (L==NULL) return NULL;
    	
    	if (L->valor==num) return L;
    	
    	pesquisar (L->prox, num);
    }
    
    void exibir (TLista L2)
    {
    	TLista L=L2;
    	
    	if(L)
    	{
    		printf ("%d ", L->valor);
    		
    		exibir (L->prox);		
    	}
    }
    
    void exibirAoContrario (TLista U2)
    {
    	TLista U=U2;
    	
    	if(U)
    	{
    		printf ("%d ", U->valor);
    		
    		exibirAoContrario (U->ant);
    	}
    }
    
    void clonar (TLista *L, TLista L2)
    {	
    	TLista L3=L2;
    	
    	TLista U;	
    	
    	while(L3)
    	{
    		insereFim(&*L, &U, L3->valor);	
    		
    		L3=L3->prox;
    	}
    }
    
    int inserirNaPosicao (TLista *L, TLista *U, int posicao, int num)
    {	
    	
    	int t=tamanho (*L), con=0;
    	
    	TLista aux2=*L, aux, novo;
    		
    	if(!posicao||posicao>t+1)
    	{
    		return 0;
    	}
    	
    	if(posicao==1)
    	{
    		inserir (&*L, &*U, num);
    		
    		return 1;
    	}
    	
    	if(posicao==t+1)
    	{
    		insereFim(&*L, &*U, num);
    		
    		return 1;
    	}
    	
    	posicao=posicao-1;
    	
    	novo=(TLista) malloc (sizeof(TNo));
    	
    	novo->valor=num;
    		
        while (con<posicao-1)
        {
        	aux2=aux2->prox;
        	
            con++;
        }
    
    	aux=aux2->prox;
    	
    	novo->ant=aux2;
    	
    	aux2->prox=novo;
    	
    	aux->ant=novo;
    	
    	novo->prox=aux;
    
    	return 1;
    }
    
    void insereFim(TLista *L, TLista *U, int numero)
    {
    	TLista novo=(TLista) malloc(sizeof(TNo));	
    	
    	novo->prox=NULL;
    	
    	novo->valor=numero;
    	
    	(*U)?novo->ant=*U,(*U)->prox=novo,*U=novo:*L = novo;
      	
    	*U = novo;
    }
    
    void botarCrescente(TLista *L)
    {
    	TLista genesis = *L, ordenada;
    
    	int gV,oV;
       	
    	while(genesis)
    	{
           	ordenada=genesis->prox;
    			
    		while(ordenada)
    		{
               	if(genesis->valor > ordenada->valor)
    			{
                   	gV=genesis->valor;
                   	oV=ordenada->valor;
                   	ordenada->valor=gV;
                   	genesis->valor=oV;
    			}
    			ordenada = ordenada->prox;
    		}
    		genesis=genesis->prox;
    	}
    }
    
    int tamanho (TLista L1)
    {
    	TLista L=L1;
    	
    	if (!L) return 0;	
    	
    	return (1+tamanho (L->prox));
    }
    
    void inverterLista (TLista *L,TLista *U)
    {
    	TLista aux=*L;
    	
    	*L=NULL;
    	
    	*U=NULL;
    	
    	while(aux)
    	{
    		inserir (&*L, &*U, aux->valor);
    		
    		aux=aux->prox;
    	}	
    }
    
    int pesquisaMaior(TLista L2)
    {
      	TLista L=L2;
      	
    	if (!L) return 0;
      	
    	int maior = pesquisaMaior(L->prox);
    
    	if (L->valor > maior) return L->valor;
    	
    	return maior;
    }
    
    int pesquisaMenor(TLista L2)
    {
    	TLista L=L2;
    	
    	if (!L) return 0;
    	
    	int menor=L->valor;
    
    	while(L)
    	{	
    		if(L->valor < menor)
    		{
    			menor = L->valor;
    		}
    		L = L->prox;
    	}
    	return menor;
    }
    
    float media(TLista L2)
    {	
    	if (L2) return (somaDosElementos(L2)/tamanho(L2));
    	
    	return 0;
    }
    
    float somaDosElementos(TLista L2)
    {
    	TLista L=L2;
    	
    	if (!L) return 0;
    	
    	return L->valor + somaDosElementos(L->prox);	
    }
    
    void remRepListaOrd(TLista *L2,TLista *U2)
    {
        TLista L=*L2, U=*U2;
        
        if ((!L)||(!L->prox)) return;
        
        remover (&L->prox, &U,L->valor);
        
        remRepListaOrd(&L->prox,&U);
    }

    FIZ A 11

  2. #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct No{int valor;struct No *prox, *ant;}TNo;typedef TNo* TLista;
    
    int inserir (TLista *L, TLista *U, int num);
    int remover (TLista *L, TLista *U,int numero);
    int alterar (TLista L, int velho, int novo);
    TLista pesquisar (TLista L, int num);
    void exibir (TLista L);
    void exibirAoContrario (TLista U);
    void clonar (TLista *L, TLista L2);
    int inserirNaPosicao (TLista *L, TLista *U, int posicao, int numero);
    int menu (TLista L, TLista L2);
    int tamanho (TLista L);
    void insereFim(TLista *L, TLista *U, int numero);
    void botarCrescente(TLista *L);
    void inverterLista (TLista *L,TLista *U);
    float media(TLista L2);
    int pesquisaMaior(TLista L2);
    int pesquisaMenor(TLista L2);
    float somaDosElementos(TLista L2);
    void remRepListaOrd(TLista L);
    
    int main ()
    {
    TLista L=NULL, L2=NULL, U=NULL, pos;
    int num1, num2, op;
    do	{
    		system ("cls");
          	op = menu (L, L2);
      
    		switch (op)	{
    //INSERIR
    case 1: printf ("Entre com o número: ");
    		scanf ("%d", &num1);
    		(inserir (&L, &U, num1))?printf ("Inserção realizada!\n"):printf ("ERRO: Inserção não realizada!\n");
    		break;
    //REMOVER
    case 2: printf ("Entre com o número a ser removido: ");
    		scanf ("%d", &num1);
    		printf ((!remover (&L, &U, num1))?"ERRO: Remoção não realizada!\n":"Remoção realizada %i vezes!\n", remover (&L, &U, num1));
    		break;
    //ALTERAR
    case 3: printf ("Entre com o número a ser alterado: ");
    		scanf ("%d", &num1);
            printf ("Entre com o novo número: ");
            scanf ("%d", &num2);
            printf ((alterar (L, num1, num2))?"Alteração realizada!\n":"ERRO: Alteração não realizada!\n");
            break;
    //PESQUISAR
    case 4: printf ("Entre com o número a ser pesquisado: ");
    		scanf ("%d", &num1);      
    		printf ((pesquisar (L, num1))?"O número foi encontrado na lista!\n":"ERRO: O número não se encontra na lista!\n");
    		break;
    //EXIBE NORMAL
    case 5: (!L)?printf("Lista vazia!\n"):printf("Lista: "),exibir (L),printf("\n");
    		break;			
    //EXIBE INVERTIDO
    case 6: (!U)?printf("Lista vazia!\n"):printf("Lista: "),exibirAoContrario (U),printf("\n");
    		break;
    //CLONAR			
    case 7:	clonar (&L2,L);					
    		break;										
    //INSERE NA POSIÇÃO
    case 8:	printf ("Entre com o número a ser inserido: ");
            scanf ("%d", &num1);                 	
    		printf ("Entre com o posicao onde número >>%i<< vai ser inserido: ", num1);
            scanf ("%d", &num2);                 	
    		printf ((inserirNaPosicao (&L, &U, num2, num1))?"Insercao realizada!\n":"ERRO: Inserção não realizada!\n");
            break;
    //INSERE NO FIM                 	
    case 9:	printf ("Entre com o número a ser inserido: ");
            scanf ("%d", &num1);
    		insereFim(&L, &U, num1);
    		break;
    //ORDENA CRESCENTE					
    case 10:printf((!L)?"Lista vazia!\n":0),botarCrescente(&L);
    		break;					
    //remover repeticao					
    case 11:remRepListaOrd(L);
    		break;					
    //INVERTER
    case 12:inverterLista (&L,&U);
    		break;
    //fim
    case 0:	printf ("Fim do programa!\n");
    		break;
    //erro
    		default:printf ("Opção inválida!\nTente novamente!\n");
    	}
    		system ("pause");
    	}
    		while (op != 0);
    }
    
    int menu (TLista L, TLista L2)
    {
    	int opcao;
    	system	("cls");
    	printf	("\nTamanho da Lista: %i\n\n",tamanho (L));
    	printf	("Lista: ");exibir (L);
    	printf	("|\n");
    	printf	("Clone: ");exibir (L2);
    	printf	("|\n\n");
    	printf	("Menor elemento da lista......: %i. \n", pesquisaMenor(L));
    	printf	("Maior elemento da lista......: %i. \n", pesquisaMaior(L));
    	printf	("Media dos elementos da lista.: %.2f. \n\n", media(L));
       	printf	("Menu de opções:\n\n");
       	printf	("(1)\tInserir\n(2)\tRemover\n(3)\tAlterar\n");
       	printf	("(4)\tPesquisar\n(5)\tExibir na Ordem Natural\n");
       	printf	("(6)\tExibir na Ordem Inversa\n(7)\tClonar\n");
       	printf	("(8)\tInserir na Posicao\n");
       	printf	("(9)\tInsere no Fim\n(10)\tOrdenar Lista\n"); 	
       	printf	("(11)\tRemove Repeticoes da lista\n(*INCOMPLETA - so remove depois de ordenar)");
       	printf	("(12)\tInverter Lista\n");
       	printf	("(13)\tComparar Listas\n(*FAZER)");
    	printf	("(0)\tSair\n\n");
       	printf	("Entre Com a Opcao: ");
       	scanf	("%d", &opcao);
       	return opcao;
    }
    
    int inserir (TLista *L, TLista *U, int num)
    {
    	TLista aux = (TLista) malloc (sizeof(TNo));   
       	if (!aux)	{return 0;}
       	else
       	{
    		aux->valor = num;
    		aux->prox = *L;
    		aux->ant = NULL;
    
    		if (*L)
    		{
    			(*L)->ant = aux;
          	}
    
          	else
          	{
          		*U = aux;
    	  	}
          
          	*L = aux;
          
    		return 1;
    	}
    }
    
    int remover (TLista *L, TLista *U,int numero)
    {
    	TLista aux1, aux2, aux3;	
    	int cont;	
    	while ((*L) && ((*L)->valor == numero))
    	{
    		aux2 = (*L)->ant;	
    		aux1 = (*L)->prox;	
    		free (*L);	
    		cont++;	
    		*L = aux1;		
    		(*L)?(*L)->ant = aux2:0;
    	}
    	
    	if (!*L)
    	{
    		*U=NULL;
    	}
    	else
    	{
    		aux2 = *L;
    		aux1 = (*L)->prox;		
    		while (aux1)
    		{
    			if (aux1->valor == numero)
    			{
    				aux3 = aux2;				
    				(*U==aux1)?*U=aux3:0;								
    				(aux1->prox)?aux1->prox->ant=aux2:0;				
    				aux2->prox = aux1->prox;				
    				free (aux1);				
    				cont++;				
    				aux1 = aux2->prox;
    			}
    			else
    			{
    				aux2 = aux1;				
    				aux1 = aux1->prox;
    			}
    		}
    	}
    	return cont;
    }
    
    int alterar (TLista L, int velho, int novo)
    {
    	TLista aux = L;	
    	int c = 0;   
       	while (aux)
       	{
        	if (aux->valor == velho)
          	{
            	aux->valor = novo;			
    			c++;
          	}
          	aux = aux->prox;
       	}
        return c;
    }
    
    TLista pesquisar (TLista L, int num)
    {
    	if (L==NULL) return NULL;	
    	if (L->valor==num) return L;	
    	pesquisar (L->prox, num);
    }
    
    void exibir (TLista L2)
    {
    	TLista L=L2;	
    	if(L)
    	{
    		printf ("%d ", L->valor);		
    		exibir (L->prox);
    	}
    }
    
    void exibirAoContrario (TLista U2)
    {
    	TLista U=U2;	
    	if(U)
    	{
    		printf ("%d ", U->valor);
    		exibirAoContrario (U->ant);
    	}
    }
    
    void clonar (TLista *L, TLista L2)
    {	
    	TLista L3=L2;
    	TLista U;	
    	while(L3)
    	{
    		insereFim(&*L, &U, L3->valor);	
    		L3=L3->prox;
    	}
    }
    
    int inserirNaPosicao (TLista *L, TLista *U, int posicao, int num)
    {	
    	int t=tamanho (*L), con=0;
    	TLista aux2=*L, aux, novo;
    	
      	if(!posicao||posicao>t+1)
    	{
    		return 0;
    	}
    	
      	if(posicao==1)
    	{
    		inserir (&*L, &*U, num);
    		return 1;
    	}
    
    	if(posicao==t+1)
    	{
    		insereFim(&*L, &*U, num);
    		return 1;
    	}
    	
    	posicao=posicao-1;	
    	novo=(TLista) malloc (sizeof(TNo));	
    	novo->valor=num;
      
        while (con<posicao-1)
        {
        	aux2=aux2->prox;
            con++;
        }
    
    	aux=aux2->prox;	
    	novo->ant=aux2;	
    	aux2->prox=novo;	
    	aux->ant=novo;	
    	novo->prox=aux;
      
    	return 1;
    }
    
    void insereFim(TLista *L, TLista *U, int numero)
    {
    	TLista novo=(TLista) malloc(sizeof(TNo));
    	novo->prox=NULL;	
    	novo->valor=numero;
    	
    	(*U)?novo->ant=*U,(*U)->prox=novo,*U=novo:*L = novo;
      	
    	*U = novo;
    }
    
    void botarCrescente(TLista *L)
    {
    	TLista genesis = *L, ordenada;
    	int gV,oV;
       	
    	while(genesis)
    	{
           	ordenada=genesis->prox;
    			
    		while(ordenada)
    		{
               	if(genesis->valor > ordenada->valor)
    			{
                   	gV=genesis->valor;
                   	oV=ordenada->valor;
                   	ordenada->valor=gV;
                   	genesis->valor=oV;
    			}
    			ordenada = ordenada->prox;
    		}
    		genesis=genesis->prox;
    	}
    }
    
    int tamanho (TLista L1)
    {
    	TLista L=L1;
      
    	if (!L) return 0;	
    	
    	return (1+tamanho (L->prox));
    }
    
    void inverterLista (TLista *L,TLista *U)
    {
    	TLista aux=*L;
    	TLista auxU=*U;
    	*L=NULL;
    	*U=NULL;
    	
    	while(aux)
    	{
    		inserir (&*L, &*U, aux->valor);
    		aux=aux->prox;
    	}	
    }
    
    int pesquisaMaior(TLista L2)
    {
      	TLista L=L2;
      
    	if (!L) return 0;
      	
    	int maior = pesquisaMaior(L->prox);
    
    	if (L->valor > maior) return L->valor;
    	
    	return maior;
    }
    
    int pesquisaMenor(TLista L2)
    {
    	TLista L=L2;
    	
    	if (!L) return 0;
    	
    	int menor=L->valor;
    
    	while(L)
    	{	
    		if(L->valor < menor)
    		{
    			menor = L->valor;
    		}
    		L = L->prox;
    	}
    	return menor;
    }
    
    float media(TLista L2)
    {	
    	if (L2)
    	{
    		return (somaDosElementos(L2)/tamanho(L2));
    	}
    	else
    	return 0;
    }
    
    float somaDosElementos(TLista L2)
    {
    	TLista L=L2;
    	if (!L)
    	{
        	return 0;
    	}
    	else
    	{
    		return L->valor + somaDosElementos(L->prox);
    	}
    }
    
    void remRepListaOrd(TLista L2)
    {
        TLista aux;
        TLista L=L2;
      
    	if((!L)||(!L->prox)) return;
    	    
    	if (L->valor == L->prox->valor)
    	{
    		L->prox->prox->ant=aux;
    		aux = L->prox->prox;
    		free (L->prox);
    		aux->ant=L;
    		L->prox = aux;
    		remRepListaOrd(L);
    	}
    	else
    	{
    		if(!L->prox) return;
    		remRepListaOrd(L->prox);
    	}
    }

     

    • Amei 1
  3. Como posso melhorar meu código?
    Tudo funciona, mas tem como deixá-lo mais enxuto ou "profissional"?

    Obrigado!

    #include <stdio.h>
    #include <stdlib.h>
    
    #define TRUE 1
    #define FALSE 0
    
    typedef struct No {
    	int valor;
    	struct No *prox;
    } TNo;
    
    typedef TNo* TLista;
    
    
    int inserir (TLista *L, int numero);
    int remover (TLista *L, int numero);
    int alterar (TLista L, int velho, int novo);
    TLista buscar (TLista L, int numero);
    void exibir (TLista L);
    
    void mantem (TLista L,TLista *L3);
    float somaDosElementos(TLista L);
    int comparaListas (TLista L1, TLista L2);/*FAZER*/
    void exibirInvertido (TLista L2);
    void botarCrescente(TLista *L);
    int inserirNoFim (TLista *L, int numero);
    void clonar (TLista *L, TLista L2);
    void inverterLista (TLista *L);
    int inserirNaPosicao (TLista *L, int numero, int posicao);
    int tamanhoDaLista (TLista L);
    int pesquisaMaior(TLista L2);
    int pesquisaMenor(TLista L2);
    int menu (TLista L, TLista L2, TLista L3);
    float media(TLista L);
    
    void remRepListaOrd(TLista L);
    
    int main (void)
    {
    	TLista L = NULL, L2 = NULL, L3 = NULL;
    	int opcao, num1, num2, alt, pos;	
    	
    	do
    	{
    		opcao = menu (L,L2,L3);
    		
    		switch (opcao)
    		{
    //inserção
    			case 1: printf ("Entre com o número a ser inserido: ");
    			scanf ("%d", &num1);
    			printf (inserir (&L, num1)?"Elemento inserido!\n":"ERRO: Elemento não inserido!\n");
    					break;
    				
    //remoção
    			case 2: printf ("Entre com o número a ser removido: ");
    			scanf ("%d", &num1);
    			printf (remover (&L, num1)?"Elemento removido!\n":"ERRO: Elemento não removido!\n");
    					break;
    				
    //alterar
    			case 3: printf ("Entre com o número a ser alterado: ");
    			scanf ("%d", &num1);
    			
    			printf ("Entre com o novo elemento: ");
    			scanf ("%d", &num2);
    			
    			alt = alterar (L, num1, num2);
    			if (alt != 0)
    			{
    				printf ("%d ocorrencias de %d alteradas!\n", alt, num1);
    					}
    					else
    					{
    						printf ("ERRO: Elemento não alterado!\n");
    					}
    					break;
    				
    //pesquisar
    			case 4: printf ("Entre com o número a ser buscado: ");
    			scanf ("%d", &num1);
    			
    			printf (buscar (L, num1)?"Elemento encontrado!\n":"Elemento não encontrado!\n");
    					
    					break;
    				
    //exibir
    			case 5: if (!L)
    			 		{
    						printf("Lista vazia!\n");
    					}
    					else
    					{
    						printf("Lista: ");
    						exibir (L);
    			 			printf("\n");
    					}
     	break;
     	
    //exibir invertido
    			case 6: if (!L)
    			 		{
    						printf("Lista vazia!\n");
    					}
    					else
    					{
    						printf("Lista: ");
    						exibirInvertido (L);
    			 			printf("\n");
    					}
     	break;
    
    //CLONAR			
    			case 7: clonar (&L2,L);
    					break;
    			
    //INVERTER		
    			case 8:	inverterLista (&L);
    			break;
    			
    //insere no fim
    			case 9:	printf ("Entre com o número a ser inserido: ");
    			scanf ("%d", &num1);
    			printf (inserirNoFim (&L, num1)?"Elemento inserido!\n":"ERRO: Elemento não inserido!\n");
    					break;
    				
    //ordenar
    			case 10:L3=NULL;mantem (L,&L3);
    					botarCrescente (&L);
    					break;
    			
    //INSERIR NA POSIÇÃO
    			case 11:printf ("Entre com o número a ser inserido: ");
    			scanf ("%d", &num1);
    			printf ("Entre com a posicao: ");
    			scanf ("%d", &pos);
    			printf (inserirNaPosicao (&L, num1, pos)?"Elemento inserido!\n":"ERRO: Elemento não inserido!\n");
    					break;					
    //comparar
    			case 12:printf (comparaListas (L, L2)?"Elemento encontrado!\n":"Elemento não encontrado!\n");
    					break;
    					
    			case 13:remRepListaOrd(L);
    					break;
    				
    //saída
    			case 0: printf ("Fim do programa!\n");
    			break;
    			
    //opção inválida
    			default: printf ("Opção inválida! Tente novamente.\n");
    		}		
    		system ("pause");
    	}
    
    	while (opcao != 0);
    
    	return 0;
    }
    
    int inserir (TLista *L, int numero)
    {
    	TLista aux = (TLista) malloc (sizeof(TNo));	
    	if (!aux)
    	{
    		return FALSE;
    	}
    	else
    	{
    		aux->valor = numero;
    		aux->prox = *L;
    		*L = aux;
    		return TRUE;
    	}
    }
    
    int remover (TLista *L, int numero)
    {
    	TLista aux1, aux2;
    	int cont = 0;
    
    	while ((*L) && ((*L)->valor == numero))
    	{
    		aux1 = (*L)->prox;
    		free (*L);
    		cont++;
    		*L = aux1;
    	}
    
    	if (*L)
    	{
    		aux2 = *L;
    		aux1 = (*L)->prox;
    
    		while (aux1)
    		{
    			if (aux1->valor == numero)
    			{
    				aux2->prox = aux1->prox;
    				free (aux1);
    				cont++;
    				aux1 = aux2->prox;				
    			}
    			else
    			{
    				aux2 = aux1;
    				aux1 = aux1->prox;
    			}
    		}
    	}	
    	return cont;
    }
    
    int alterar (TLista L, int velho, int novo)
    {
    	TLista i=L;
    	int cont=0;
    	
    	while (i != NULL)
    	{
    		if (i->valor == velho)
    		{
    			i->valor = novo;
    			cont++;
    		}
    		i = i->prox;
    	}
    	return cont;
    }
    
    TLista buscar (TLista L, int numero)
    /*if (!L){return NULL;}if (L->valor == numero){return L;}return buscar (L->prox,numero);*/
    {
    	(!L)?NULL:(L->valor == numero)?L:buscar (L->prox,numero);	
    }
    
    void exibir (TLista L2)
    {
    	TLista L=L2;	
    	if(L)
    	{
    		printf ("%d ", L->valor);		
    		exibir (L->prox);		
    	}
    }
    
    int menu (TLista L, TLista L2, TLista L3)
    {
    	
    	int opcao;
       	system	("cls");
    	printf	("\nTamanho da Lista: %i\n\n",tamanhoDaLista (L));
    	printf	("Lista Antes de Ordenar...: ");exibir (L3);
    	printf	("|\n\n");
    	printf	("Lista Atual..................: ");exibir (L);
    	printf	("|\n");	
    	printf	("Menor elemento da lista......: %i. \n", pesquisaMenor(L));
    	printf	("Maior elemento da lista......: %i. \n", pesquisaMaior(L));
    	float x; (!L)?x=0:x=media(L);
    	printf	("Media dos elementos da lista.: %.2f. \n\n", x);	
    	printf	("Clone da Lista Atual.....: ");exibir (L2);
    	printf	("|\n\n");	
    	printf	("Menu de opções:\n\n");
       	printf	("(1)\tInserir\n(2)\tRemover\n(3)\tAlterar\n");
       	printf	("(4)\tPesquisar\n(5)\tExibir na Ordem Natural\n");
       	printf	("(6)\tExibir na Ordem Inversa\n(7)\tClonar\n");
       	printf	("(8)\tInverter Lista\n");
       	printf	("(9)\tInsere no Fim\n(10)\tOrdenar Lista\n");
       	printf	("(11)\tInserir na Posicao\n");
       	printf	("(12)\tComparar Listas(FAZER)\n");
       	printf	("(13)\tRemove Repeticao de Lista Ja Ordenada\n");
       	printf	("(0)\tSair\n\n");
       	printf	("Entre Com a Opcao: ");
       	scanf	("%d", &opcao);
    
       	return opcao;
    }
    
    void botarCrescente(TLista *L)
    {
    	TLista genesis = *L, ordenada;
    
    	int gV,oV;
       	
    	while(genesis)
    	{
       	ordenada=genesis->prox;
    		   			
    		while(ordenada)
    		{
       	if(genesis->valor > ordenada->valor)
    			{
       	gV=genesis->valor;
       	oV=ordenada->valor;
       	ordenada->valor=gV;
       	genesis->valor=oV;
    			}
    			ordenada = ordenada->prox;
    		}
    		genesis=genesis->prox;
    	}
    }
    
    int inserirNoFim (TLista *L, int numero)
    {   
    	TLista aux=(TLista)malloc(sizeof(TNo));
    	TLista novo=(TLista)malloc(sizeof(TNo));
    	TLista aux2=(TLista)malloc(sizeof(TNo));	
    	
    	novo->valor=numero;
    	aux2=*L;
    	
    	if((!*L))
    	{
    		aux->valor=numero;		
    		aux->prox=*L;		
    		*L=aux;		
    		return TRUE;
    	}
    	else
    	{
    		while(aux2->prox)
    {
    aux2=aux2->prox;
    }
    		aux=aux2->prox;
    		aux2->prox=novo;
    		novo->prox=aux;
    				
    		return TRUE;
    	}
    	
    }
    
    void clonar (TLista *L, TLista L2)
    {
    	TLista aux=(TLista)malloc(sizeof(TNo));
    		
    	*L=NULL;
    			
    	aux=L2;
    	
    	while(aux)
    	{
    		inserirNoFim (&*L, aux->valor);
    		aux=aux->prox;
    	}	
    }
    
    void inverterLista (TLista *L)
    {
    	TLista aux=(TLista)malloc(sizeof(TNo));	
    	aux=*L;	
    	*L=NULL;
    	
    	while(aux)
    	{
    		inserir (&*L, aux->valor);
    		aux=aux->prox;
    	}	
    }
    
    int inserirNaPosicao (TLista *L, int num, int posicao)
    {
    	int con=0;
    	
    	TLista auxL=*L, aux;
    	
    	TLista novo=(TLista) malloc (sizeof(TNo));
    	
    	novo->valor=num;	
    		
    	if(!posicao||posicao>tamanhoDaLista(*L)+1)
    	{
    		return FALSE;
    	}
    	
    	if(posicao==1)
    	{
    		inserir (&*L, num);
    		return TRUE;
    	}
    	
    	if(posicao==tamanhoDaLista(*L)+1)
    	{
    		inserirNoFim(&*L, num);
    		return 1;
    	}
    	
    	posicao=posicao-1;
    		
    while (con<posicao-1)
    {
    	auxL=auxL->prox;
    con++;
    }
    
    	aux=auxL->prox;
    	
    	auxL->prox=novo;
    	
    	novo->prox=aux;
    
    	return TRUE;
    }
    
    int tamanhoDaLista (TLista L2)
    /*int tam=0;TLista aux=L;while(aux){aux=aux->prox;tam++;}return tam;}*/
    {
    	TLista L=L2;
    	
    	if (!L)
    	{
    		return 0;
    	}
    	else
    	{
    		return (1 + tamanhoDaLista(L->prox));
    	}
    }
    
    int pesquisaMaior(TLista L2)
    /*if (!L2) return 0;TLista L=L2;int maior = L->valor;while(L){if(L->valor > maior){maior = L->valor;}L=L->prox;}return maior;*/
    {
      	TLista L=L2;
      	
    	if (!L) return 0;
      	
    	int maior = pesquisaMaior(L->prox);
    
    	if (L->valor > maior) return L->valor;
    	
    	return maior;
    }
    
    int pesquisaMenor(TLista L2)
    {
    	TLista L=L2;
    	
    	if (!L) return 0;
    	
    	int menor=L->valor;
    
    	while(L)
    	{	
    		if(L->valor < menor)
    		{
    			menor = L->valor;
    		}
    		L = L->prox;
    	}
    	return menor;
    }
    
    float media(TLista L2)
    {	
    	return (somaDosElementos(L2)/tamanhoDaLista(L2));
    }
    
    void exibirInvertido (TLista L2)
    {
    	TLista L=L2;	
    	if(L)
    	{
    		exibirInvertido (L->prox);		
    		printf ("%d ", L->valor);
    	}
    }
    
    int comparaListas (TLista L1, TLista L2)/*GOSTARIA DE FAZER RECURSIVAMENTE*/
    {
    	TLista l1=L1;
    	while (l1)
    	{
    		if (!buscar(L2,l1->valor))
    		{
    			return 0;
    		}
    		l1=l1->prox;
    	}
    	
    	return 1;
    }
    
    float somaDosElementos(TLista L2)
    {
    	TLista L=L2;
    	if (!L)
    	{
    	return 0;
    	}
    	else
    	{
    		return L->valor + somaDosElementos(L->prox);
    	}
    }
    
    void remRepListaOrd(TLista L)
    {
    TLista aux;
    
    	if((!L)||(!L->prox)) return;
    	
    	(L->valor == L->prox->valor)?aux = L->prox->prox,free (L->prox),L->prox = aux,remRepListaOrd(L):remRepListaOrd(L->prox);
    }
    
    void mantem (TLista L1,TLista *L3)
    {
    	TLista L=L1;	
    	if (!L)
    	{
    		return;
    	}
    	else
    	{
    		inserirNoFim (&*L3, L->valor);
    	}
    	mantem (L->prox,&*L3);
    }

     

    • Obrigado 1
  4. @arfneto Tá errado não, tá certo.

    "não há como saber qual das operações vai ser executada primeiro" ???????????????????????????

    Em 25/11/2020 às 20:29, arfneto disse:

    Acha que esse segundo return vai ser executado alguma vez?

    Leu a parte que escrevi que é desnecessário? Enfim...

    Em 25/11/2020 às 20:29, arfneto disse:

    Quanto ao primeiro return, o único que vai rodar na prática:

    Sério???? Se você não me avisa! Caramba...

    Em 25/11/2020 às 20:29, arfneto disse:

    tem dois #include obsoletos e fora do padrão e que sequer estão em uso.

    Sério??? Nossa! 

    Em 25/11/2020 às 20:29, arfneto disse:

    O problema é que você usa str1 duas vezes como parâmetro de chamada para uma função. Na mesma linha., uma soma.

    Acho que você deveria estudar mais aritmética de ponteiros.... talvez entenda o que foi feito.

    Em 25/11/2020 às 20:29, arfneto disse:

    Compilador online? Puts...

    Em 25/11/2020 às 20:29, arfneto disse:

    Por outro lado, compare com a saída do programa que te mostrei, e que tem a solução recursiva completa sem se apoiar naquela "deixa" do enunciado e funciona em qualquer plataforma...

    É só admitir que não sabe...

    Em 25/11/2020 às 20:29, arfneto disse:

    tem dois return em seguida :D :D e isso é folclórico

    Você e 3 pessoas vão rir muito. O resto vai saber o que houve...

    • Haha 1
  5. 4 horas atrás, arfneto disse:

     

    Uma discussão assim longa já não vai mais ajudar ninguém, porque imagino que as pessoas não tenham paciência de acompanhar esses argumentos, e cansei desse tópico. Eu tinha me esquecido do tanto que eu tentei te explicar muito do que está errado, e desisto. Vou resumir aqui de novo, uma última vez, e recomendo que seja ainda mais humilde e tente entender.

     

    Veja como termina sua função comparaString() por exemplo:
     

    
    int comparaString(char* str1, char* str2)
    {
    	if (!str1[0])
    	{
    		return 0;
    	}
    
    	return(comparaString2(str1[0], str2) + comparaString(++str1, str2));
    	return (comparaString(++str1, str2));
    }

     

    Acha que esse segundo return vai ser executado alguma vez? Não, não vai. :D Sabe o que é unreachable code? É isso aí acima. Se você tem um patrão ou um professor, melhor não mostrar isso. No forum já mostrou.

     

    Quanto ao primeiro return, o único que vai rodar na prática:

     

    
    	return(comparaString2(str1[0], str2) + comparaString(++str1, str2));

     

    Entenda que isso está ERRADO. Não é minha opinião. Isso é UB, undefined behavior, comportamento indefinido.

     

    Pelo modo como programa acho que não tem experiência ainda para entender isso e então vou tentar te explicar:

     

    O problema é que você usa str1 duas vezes como parâmetro de chamada para uma função. Na mesma linha., uma soma.

    E em uma das vezes você altera o valor. A linguagem C  não garante a ordem de execução dessa soma e pode ser que incremente antes ou depois da primeira chamada. Se incrementar antes vai passar o parâmetro alterado já na primeira chamada.

     

    Isso quer dizer que dependendo da ordem de execução seu programa retorna 7, 8 ou 9. Retorna 8 apenas se mantiver a chamada a gets() apesar dos avisos do gcc e do passar dos anos. No Windows não vai aceitar gets() no compilador da Microsoft. E continua sendo UB.

    Veja a mensagem do gcc 9.3 por exemplo, com -Wall que é o padrão em muitas escolas e empresas

     

    image.png.1b45294a40e214130d0dcd2fea4e27f8.png

     

    Mais ainda, em gcc 9.3, Ubuntu, com gets()
     

    image.png.2fdb13dfd369ee2b1ed5e964efccb944.png

     

    Ao menos retornou 8 :D

     

    Mas a essência do problema é o undefined behavior, o uso de uma variável alterada no meio de uma expressão cuja ordem de avaliação não é garantida. E no meio de uma chamada a duas funções recursivas. Isso num ambiente profissional poderia te custar caro.

     

    No forum não importa. Entendo que esse talvez não seja um erro ao alcance de um iniciante perceber e por isso estou escrevendo de novo a respeito. E de todo modo você não deve ter sequer lido os avisos sobre gets() na tela, exceto os que eu te dei, e parece que eu não tenho assim muito crédito, então fica aqui o aviso para ficar atento a isso no futuro.

     

    Nesse compilador online retorna 9
     

    image.png.dac89e992bf18297ec7a1ede0be7dbbd.png

     

    Em gcc em Linux retorna em geral 9:
     

    image.png.d5498bc151cadf0c444e6790c046c9b3.png

     

    no windows
     

    image.png.a7a205862ab84d92e895934fae577872.png

     

    No SUSE Linux


    image.png.6a1de50d8c4fd62e0a99946902dac59d.png

     

    Ou no Ubuntu

     

    Mas no Windows com o compilador da Microsoft retorna 7
     

    image.png.cf863d921da2305c55c5a2e6329738ea.png

     

    Isso é esperado, como eu disse: pode acontecer qualquer coisa.

     

    Seu programa no geral não está assim bom.

    • fflush() não existe para fluxos de entrada em geral.
    • gets() é marcada como obsoleta há mais de vinte anos e alguns compiladores simplesmente não tem isso
    • tem dois #include obsoletos e fora do padrão e que sequer estão em uso.
    • tem dois return em seguida :D :D e isso é folclórico
    • tem uma expressão cujo comportamento é indefinido pelo padrão.

    Por outro lado, compare com a saída do programa que te mostrei, e que tem a solução recursiva completa sem se apoiar naquela "deixa" do enunciado e funciona em qualquer plataforma...

     

    image.png.4c2480a11d6f8bddda2edee37a6f192f.png

     

    Assim é. O código está no tópico.

     

    Abaixo o código usado em todas as plataformas, o que você postou, com os 2 #include removidos e a chamada a gets() trocada por fgets()
     

      Ocultar conteúdo
    
    
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int comparaString2(char str1, char* str2);
    
    int comparaString(char* str1, char* str2);
    
    int main(void)
    {
    	int cont = 0;
    	char str1[100], str2[100];
    	fflush(stdin);
    	printf("\nString1...:\n");
    	fgets(str1, 100, stdin);
    	fflush(stdin);
    	printf("\nString2...:\n");
    	fgets(str2, 100, stdin);
    	cont = comparaString(str1, str2);
    	printf("\nExistem %i caracteres comuns entre as duas strings\n", cont);
    	return 0;
    }
    
    int comparaString(char* str1, char* str2)
    {
    	if (!str1[0])
    	{
    		return 0;
    	}
    	return(comparaString2(str1[0], str2) + comparaString(++str1, str2));
    	return (comparaString(++str1, str2));
    }
    
    int comparaString2(char str1, char* str2)
    {
    	if (!str2[0])
    	{
    		return 0;
    	}
    	if (str2[0] == str1)
    	{
    		return (1 + comparaString2(str1, ++str2));
    	}
    	else
    		return comparaString2(str1, ++str2);
    }

     

     

    O segundo return que botei na comparaString é desnecessário...

     

  6. @arfneto

    6 minutos atrás, arfneto disse:

     

    Você sabe o que é ambiguidade? Um tópico que fala em inserir na ordem o número 4 na quarta posição e a série é 1 2 3 5 6 7 8 não é ambíguo pra você?

     

    image.png.bf05186b70527acc6fe58caf64d6fde1.png

     

    Sério?

     

    Você não quer ajuda? Leia o que as pessoas de boa vontade escrevem para te ajudar 

     

    Entendeu o código que eu postei?

     

    Se quer apenas inserir na posição N, o que é inútil, basta contar os avanços a partir da raiz. E contornar o caso da lista não ter ao menos N-1 elementos.

     

     

    "Você sabe o que é ambiguidade? Um tópico que fala em inserir na ordem o número 4 na quarta posição e a série é 1 2 3 5 6 7 8 não é ambíguo pra você?"
    Não... qualquer pessoa teria lido a expressão "por exemplo" e saberia que se tratava apenas de um exemplo!

    Ajudar é bem diferente disso aí.

    Retiro o convite. Obrigado!

  7. 3 horas atrás, arfneto disse:

    Sua pergunta é ambígua: você diz que quer inserir na quarta posição, mas sugere que quer também inserir na ordem numérica.
     

     

    Se quer inserir na quarta posição é uma coisa, se quer inserir na ordem é outra.

     

    Inserir na posição N 

    É trivial, apenas tem o caso especial de a lista não ter ao menos (N-1) elementos. Se posiciona no início, conta os avanços, cria o nó e ajusta os ponteiros. É um exercíçio comum para iniciantes, mas pouco útil. Foi discutido aqui dias atrás.

     

    Inserir em ordem

    É trivial, mas é mais útil. Em geral o que se faz é usar uma função de comparação para manter a inserção genérica e poder classificar por CPF, por nome, por idade, o que tiver dentro do nó ou puder ser determinado a partir dele.

     

    É a técnica usada por exemplo no qsort() em 😄
     

    
    void qsort(
    	void *base, size_t nitems, 
    	size_t size, 
    	int (*compar)(const void *, const void*)
    );

     

    Eis um protótipo de uma solução em uso aqui:


    Lista*      _inserir_na_ordem(void*, Lista*, int(*)(void*, void*));
     

    E uma implementação com muitos comentários. No fundo não tem 20 linhas. Pode entender a lógica melhor

     

    
    /*
     aqui a ideia e simples: tenho um elemento 'item'
     para inserir. Mas quero inserir na ordem.
     So que nao sei qual o conteudo entao nao sei qual a ordem.
    
     Se eu tiver que saber o conteudo entao a lista nao sera mais
     generica e o trabalho nao vai poder ser usado depois sem
     alterar o codigo, compilar e tal
    
     Logico que nao queremos abrir mao disso porque nao queremos
     mexer mais nesse codigo. Uma lista e uma lista afinal
    
     A solucao e a simples, usada em todas as bibliotecas e
     sistemas desde os '60. So vai mudando o nome. Hook, CallBack
     sei la
    
     A funcao f() escrita pelo cara que conhece os items compara dois
     itens e devolve -1, 0 ou 1 conforme o primeiro seja menor
     igual ou maior que o segundo Pronto
    
    Se a funcao veio em branco insere no final e pronto
    
    Queremos manter uma propriedade chamada estabilidade, que ocorre
    quando os elementos iguais sao inseridos um depois do outro
    
    */
    Lista*      _inserir_na_ordem(void* item, Lista* l, int(*f)(void*, void*))
    {
        if (l == NULL) return l; // sem lista
        if (item == NULL) return l; // sem item
        // se nao veio a funcao insere no fim e pronto
        if (f == NULL)
            return _inserir_no_final(item, l);
        // se nao tinha nada insere no final. Ou no inicio
        if (l->quantos == 0)
            return _inserir_no_final(item, l);
        // entao tem mais gente. o caso comum
        // segue a lista e acha a posicao
        Node* p = l->inicio;
        // agora comparamos os itens
        // p->item e item para inserir, claro, na ordem
        do
        {
            int res = f(item, p->item); // -1,0,1
            // se voltou > 0 a posicao e mais pra frente
            // continua na lista
            if (res > 0)
            {
                p = p->proxima;
                continue;
            };  // if()
            // se voltou 0 insere o item depois de p
            if (res == 0)
                // aqui tem uma pegadinha se for inserir depois do ultimo
                if (p == l->fim)
                    l->fim = _inserir_node_depois(item, p);
                else
                    p = _inserir_node_depois(item, p);
            else
            {
                // aqui tem uma pegadinha se for inserir antes do primeiro
                if (p == l->inicio)
                    l->inicio = _inserir_node_antes(item, p);
                else
                    p = _inserir_node_antes(item, p);
            };  // if()
            // agora atualiza a quantidade e retorna
            l->quantos = l->quantos + 1;
            return l;
        } while (p != NULL);
        // se nao retornou ainda e porque esse novo item e o maior
        // de todos entao insere no final
        return _inserir_no_final(item, l);
    };  // inserir_na_ordem()

     

     

    "Sua pergunta é ambígua: você diz que quer inserir na quarta posição, mas sugere que quer também inserir na ordem numérica.
     

     

    Se quer inserir na quarta posição é uma coisa, se quer inserir na ordem é outra."

     

    1. Aí, tu forçou a barra...momento algum escrevi "BOTAR EM ORDEM"

    2. No início eu escrevi "Por exemplo, "...chegou a ver?

    3. aiai...

  8. 23 minutos atrás, arfneto disse:

    image.png.184fcc9311415f994ca4b2c54efd0761.png

     

     

    teste como eu te expliquei

    Eita!

    Custa você admitir que não sabe?
    Segue:
     


    String1...:
    azul

    String2...:
    aazz uull

    Existem 8 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 17.12 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     

    4

     

    0

     

    0


    String1...:
    uma string

    String2...:
    uma strinG

    Existem 9 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 14.53 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     

    Se você conseguir admitir que estou certo, pode me ajudar a não contar as repetições?

     

    aaaa x aa retornar "1".

     

    Pensei em pesquisar e retornar 1 ou 0 se achar.

     

    Daí um "IF".

     

    Se quiser continuar teimando, tudo bem.

    • Haha 1
  9. @arfneto

    String1...:
    abcdefghija

    String2...:
    a

    Existem 2 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 9.396 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     


    String1...:
    a a a

    String2...:
    a

    Existem 3 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 3.472 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     


    String1...:
    bbb

    String2...:
    ab

    Existem 3 caracteres comuns entre as duas strings

     

     

    --------------------------------
    Process exited after 6.962 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

    agora, Comunista.RJ disse:

    @arfneto

    String1...:
    abcdefghija

    String2...:
    a

    Existem 2 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 9.396 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     


    String1...:
    a a a

    String2...:
    a

    Existem 3 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 3.472 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     


    String1...:
    bbb

    String2...:
    ab

    Existem 3 caracteres comuns entre as duas strings

     

     

    --------------------------------
    Process exited after 6.962 seconds with return value 0
    Pressione qualquer tecla para continuar. . .


    String1...:
    bbb

    String2...:
    bab

    Existem 6 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 2.625 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     

    2 minutos atrás, Comunista.RJ disse:

    @arfneto

    String1...:
    abcdefghija

    String2...:
    a

    Existem 2 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 9.396 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     


    String1...:
    a a a

    String2...:
    a

    Existem 3 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 3.472 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     


    String1...:
    bbb

    String2...:
    ab

    Existem 3 caracteres comuns entre as duas strings

     

     

    --------------------------------
    Process exited after 6.962 seconds with return value 0
    Pressione qualquer tecla para continuar. . .


    String1...:
    bbb

    String2...:
    bab

    Existem 6 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 2.625 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

     

    String1...:
    MATRIX

    String2...:
    MATRISX

    Existem 6 caracteres comuns entre as duas strings

    --------------------------------
    Process exited after 9.389 seconds with return value 0
    Pressione qualquer tecla para continuar. . .

  10. Dado o código, como incluir número em determinada posição na LDE criada?

     

    Por exemplo, lista criada: 1 2 3 5 6 7 8. Quero incluir o 4 na quarta posição, tornando a lista assim: 1 2 3 4 5 6 7 8.

     

    Segue o código:

    #include <stdio.h>
    #include <stdlib.h>
    #include <locale.h>
    
    typedef struct No
    {
       int valor;
       struct No *prox, *ant;
    } TNo;
    
    typedef TNo* TLista;
    
    int inserir (TLista *Lista, TLista *U, int num)
    {
    	TLista aux = (TLista) malloc (sizeof(TNo));
    
       		aux->valor = num;
     
      		aux->prox = *Lista;
          	
      		aux->ant = NULL;
    
    	  	(*Lista)?(*Lista)->ant = aux:*U = aux;
    
          	*Lista = aux;
    }
    
    void exibir (TLista Lista)
    {
    	if(Lista)
    	{
    		printf ("%d ", Lista->valor);
    		exibir (Lista->prox);
    	}
    }

     

  11. Em 16/11/2020 às 23:06, arfneto disse:

     

    ah! Pena que o programa não veio falar por ele :D 

    Tem razão pequeno gafanhoto! Viu? nem sempre discordo de você.
    Segue a função que inclui os itens na lista e da onde surge o "U".

     

    typedef struct No
    {
       int valor;
       struct No *prox, *ant;
    } TNo;
    
    typedef TNo* TLista;
    
    void inserir (TLista *L, TLista *U, int num)
    {
        TLista aux = (TLista) malloc (sizeof(TNo));
       
           {
               aux->valor = num;
              aux->prox = *L;
              aux->ant = NULL;
          
              (*L)?(*L)->ant = aux:*U = aux;
          
              *L = aux;
        }
    }
    
    void exibir (TLista L)
    {
    	if(L)
    	{
    		printf ("%d ", L->valor);
    		exibir (L->prox);		
    	}
    }
    
    void exibirAoContrario (TLista U)
    {
    	if(U)
    	{
    		printf ("%d ", U->valor);
    		exibirAoContrario (U->ant);
    	}
    }

     

  12. Em 14/11/2020 às 12:40, arfneto disse:


    Testou mesmo essa solução anes de marcar como tal?🤔
     

     

    Pois é. Você respondeu:

     

     

    Para responder a si mesmo não se usa um forum. E não foi você que perguntou nesse caso: eu perguntei qual o sentido da afirmação
     

     

    Você não precisa responder nem para mim nem para o forum, claro. Mas postar uma resposta que encontrou para si mesmo é curioso ;) 

     

    A pergunta era "que tem a ver um for em uma função recursiva com o fato de ela ser recursiva ou não? Que significa a expressão "não vale" por exemplo?

     

    E a sua solução

     

    Muito bem. Parabéns. E já foi marcada como solução! É certo que foi marcada pelo próprio autor, você mesmo, mas está claro lá que é a solução. ✔️

     

    E a solução resolve?
     

    Curiosamente eu te mostrei um programa e uma função para testar isso e expliquei até porque usar. E você preferiu claro seguir seu caminho resoluto e que levou à solução final ótima e elegante.

     

    No entanto rodando o mesmo programa que te mostrei e você poderia ter copiado se vê na tela:
     

    
    
    
    A versao que "nao vale" segundo voce
    
            ==> 5 testes:
    
    01/05  "azul" vs "aazz uull" retornou 8
    02/05  "azul" vs "azul" retornou 4
    03/05  "azul" vs "" retornou 0
    04/05  "" vs "azul" retornou 0
    05/05  "uma string" vs "uma strinG" retornou 9
    
    
    A versao "Solucao" e "resposta" segundo voce
    
            ==> 5 testes:
    
    01/05  "azul" vs "aazz uull" retornou 6
    02/05  "azul" vs "azul" retornou 3
    03/05  "azul" vs "" retornou 0
    04/05  "" vs "azul" retornou 0
    05/05  "uma string" vs "uma strinG" retornou 8

     

    E os resultados não batem.

     

    Você pode responder qual está correto apenas lendo acima ou rodando esse programa aqui abaixo:
     

    
    #include <ctype.h>
    #include <memory.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int     comparaString(const char*, const char*);
    int     comparaString2(const char*, const char*);
    int     comparaStringA(const char*, const char*);
    
    void testaF(unsigned, const char* [][2],
        int(*)(const char*, const char*), const char*);
    
    int main()
    {
        const char* teste[][2] =
        {
            { "azul", "aazz uull" },
            { "azul", "azul" },
            { "azul", "" },
            { "", "azul" },
            { "uma string", "uma strinG" }
        };
    
        int n = sizeof(teste) / (2 * sizeof(char*));
    
        testaF(n, teste,
            comparaStringA,
            "A versao que \"nao vale\" segundo voce");
    
    
        testaF(n, teste,
            comparaString,
            "A versao \"Solucao\" e \"resposta\" segundo voce");
    
        return 0;
    };
    
    
    void        testaF(
        unsigned n, const char* teste[][2],
        int(*f)(char*, char*), const char* msg)
    {
        if (msg != NULL)
            printf("\n\n%s\n\n\t==> %d testes:\n\n", msg, n);
        else
            printf("\n\n==> %d testes:\n\n", n);
    
        for (unsigned i = 0; i < n; i++)
        {
            printf("\
    %02d/%02d  \"%s\" vs \"%s\" retornou %d\n",
    1 + i, n, teste[i][0], teste[i][1],
    f((char*)teste[i][0], (char*)teste[i][1]));
        }; // for()
    };

     

    Ou teste a "solução" digitando no teclado os valores um por um, do modo bem moderno. 

     

    Mas pode usar a função que eu postei no tópico #2 e o programa de teste que eu coloquei lá junto para te ajudar. Ela serve apara testar qualquer número de funções.

     

    Ainda sobre a solução


    O erro que cometeu é o clássico one-off e é o trivial para pegar quando

    • se testa mecanicamente
    • quando tem um patrão ou orientador rigoroso.
    • quanto se tem menos auto-confiança e acha que é melhor testar mais

    Acredito que possa fazer funcionar ainda, mas é uma ideia mínima apoiada em uma "muleta" deixa na alínea (ii). O alvo do seu  desafio é:

     

    Desafio

     

     

    Em português: 
     

    Desenvolver uma função recursiva que determine o número de caracteres em comum entre duas string s1 e s2
     

    E tem a "colher de chá" 

    Em português: 

    ii. Se a mesma letra aparecer N vezes em uma certa string não será considerado um erro se sua solução acumular essa letra N vezes

     

    E a restrição:
     


    Em português: 
     

    Se sua solução for dividida em mais de uma função (de modo que a função principal, que resolve o problema proposto - chama outras funções auxiliares), todas as funções devem ser recursivas

     

    Uma vez que funcione você terá feito o mínimo do mínimo.

     

     

    Se ninguém resolveu antes de mim, por que não posso marcar a minha solução como solução. Se você tivesse resolvido eu marcaria a sua. Simples.

    agora, Comunista.RJ disse:

    Se ninguém resolveu antes de mim, por que não posso marcar a minha solução como solução. Se você tivesse resolvido eu marcaria a sua. Simples.

    Pela enésima vez, a sua tem for. Não serve. Obrigado mesmo assim e até a próxima.

  13. 7 minutos atrás, arfneto disse:

    Sugiro não postar código em espaço duplo. Só fica comprido e mais difícil de ler

     

    
    void exibirAoContrario (TLista U)
    {
    	TLista aux;  
       	//verificando se a lista está vazia
       	if (!U)
       	{
          	printf ("Lista vazia!\n");
       	}
       	else
       	{
          	printf ("Lista: ");      	
          	aux = U;      
          	while (aux)
          	{
             	printf ("%d ", aux->valor);
             	aux = aux->ant;
          	}           
          	printf ("\n");
       	}
    }


    Imagino que tenha um programa todo onde testou isso. Poste o programa. E teste

     

    • Evite chamar variáveis de "aux"...
    • Se a lista está vazia simplesmente retorne. Não há sentido em deslocar todo o código da função para a direita por um caso particular que deve acontecer em uma fração modesta das execuções. Só dificultaa leitura e manutenção do código.

    E entenda que se aux está posicionada para o inicio da lista adivinha o que vai ter em aux->ant? NADA. Zero, NULL. Não vai listar nadinha exceto o primeiro valor...

     

     

    O tópico aqui era gerar uma lista inversa e e não simplesmente listar ao contrário

    Imagino que tenha um programa todo onde testou isso (lógico). Poste o programa(não precisa). E teste (aff)

    Evite chamar variáveis de "aux"...(vou continuar chamando; irrelevante).

     

    Se a lista está vazia simplesmente retorne. Não há sentido em deslocar todo o código da função para a direita por um caso particular que deve acontecer em uma fração modesta das execuções. Só dificultaa leitura e manutenção do código. (você não entendeu a função)

     

    E entenda que se aux está posicionada para o inicio da lista adivinha o que vai ter em aux->ant? NADA. Zero, NULL. Não vai listar nadinha exceto o primeiro valor...(extamante, assim o laço termina; não entendeu o código outra vez).

     

    O tópico aqui era gerar uma lista inversa e e não simplesmente listar ao contrário (isso sim é relevante; no programa, a lista "U" é a inversa da lista original "L".

     

     

  14. #include <string.h>
    #include <strings.h>
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    
    int comparaString2(char str1,char* str2);
    
    int comparaString (char* str1,char* str2);
    
    int main(void)
     {
      int cont=0;
      
      char str1[100],str2[100];
      
      fflush(stdin);
      printf("\nString1...:\n");
      gets(str1);
    
      fflush(stdin);
      printf("\nString2...:\n");
      gets(str2);
    
      cont=comparaString (str1,str2);
    
      printf("\nExistem %i caracteres comuns entre as duas strings\n",cont);
    
      return 0;
     }
    
    int comparaString (char* str1,char* str2)
     {
      if (!str1[0])
      {
       return 0;
      }
    
      return(comparaString2(str1[0],str2)+comparaString(++str1,str2));
    
      return (comparaString (++str1,str2));
    
     }
    
    int comparaString2(char str1,char* str2)
     {
      if (!str2[0])
      {
       return 0;
      }
    
      if (str2[0]==str1)
      {
       return (1+comparaString2(str1,++str2));
      }
    
      else
    
      return comparaString2(str1,++str2);
     }

    Solução!

  15. Em 12/11/2020 às 01:35, Comunista.RJ disse:
    
    
    #include <string.h>
    #include <strings.h>
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    
    int comparaString (char str1[100],char str2[100]);
    
    int main(void)
    	{
    		int cont=0;
    		
    		char str1[100],str2[100];
    		
    		system("cls");
    		fflush(stdin);
    		printf("\nString1...:\n");
    		gets(str1);
    		system("cls");
    		fflush(stdin);
    		printf("\nString2...:\n");
    		gets(str2);
    		
    		cont=comparaString (str1,str2);
    		
    		printf("\nExistem %i caracteres comuns entre as duas strings\n",cont);
    		
    		return 0;
    	}
    	
    int comparaString (char str1[100],char str2[100])
    {
    		int i,j,cont=0;
    		
    		for(i=0;str1[i]!=NULL;i++)
    		{
    			for(j=0;str2[j]!=NULL;j++)
    			{
    				if(str1[i]==str2[j])
    				{
    					cont++;
    				}
    			}
    		}
    		
    		return cont;
    }

    Como fazer de forma totalmente recursiva?

    Eu mesmo consegui me responder, segue:
     

     

  16. 1 minuto atrás, arfneto disse:

    ? Deve estar brincando

     

    Recursividade é só isso: Uma função ou algoritmo que de algum modo chama a si mesmo. Só isso. Não há desafio ou forum que mude isso.

     

    Em geral a recursão acontece no início ou no final do processo. Nesse caso no final.

     

    A própria recursão é um for(), e vai entender isso lendo o código. E como um for seria mais eficiente. como já expliquei e você pode medir para provar. Também mostrei como medir isso nessa semana em outro post

     

    É o seu desafio, afinal. Espero que tenha entendido ao menos o mecanismo e as coisas que te expliquei. Atualize seu IDE. 89 passou há muito.

     

    Deve servir para outros ao menos

     

    Abraço

     

    2 minutos atrás, arfneto disse:

    ? Deve estar brincando

     

    Recursividade é só isso: Uma função ou algoritmo que de algum modo chama a si mesmo. Só isso. Não há desafio ou forum que mude isso.

     

    Em geral a recursão acontece no início ou no final do processo. Nesse caso no final.

     

    A própria recursão é um for(), e vai entender isso lendo o código. E como um for seria mais eficiente. como já expliquei e você pode medir para provar. Também mostrei como medir isso nessa semana em outro post

     

    É o seu desafio, afinal. Espero que tenha entendido ao menos o mecanismo e as coisas que te expliquei. Atualize seu IDE. 89 passou há muito.

     

    Deve servir para outros ao menos

     

    Abraço

    @arfneto Não vale porque tem laço "for". Vou tentar por aqui, se eu conseguir eu posto. Abraços.

     

     

    Você que não entendeu muito bem, mas deixa pra lá. Vou tentar sozinho ou esperar alguém que me ajude. Quando eu conseguir eu mostro aqui. Até a próxima!

  17. @arfneto Acho que você não entendeu, mas deixa prá lá.

     

    É só salvar como .cpp que funciona.

     

    Não estou preocupado com essas coisas agora.

     

    Sei todas as "regras de etiqueta" dos códigos.

     

    Perda de tempo... estou queimando os neurônios aqui ainda com a função recursiva! KKKK

    5 minutos atrás, Comunista.RJ disse:

    @arfneto Acho que você não entendeu, mas deixa prá lá.

     

    É só salvar como .cpp que funciona.

     

    Não estou preocupado com essas coisas agora.

     

    Sei todas as "regras de etiqueta" dos códigos.

     

    Perda de tempo... estou queimando os neurônios aqui ainda com a função recursiva! KKKK

    Por exemplo, eu uso operador ternário nos meus códigos, você não. Estou escrevendo para tentar entender a recursividade.

    E por fim, obrigado por se disponibilizar a ajudar.

    • Curtir 1
  18. @arfneto Eu sei. No DEVC++, se você gravar o arquivo como .c, ele não aceita declarar dentro do for.

     

    "50    2    D:\desafio.c    [Error] 'for' loop initial declarations are only allowed in C99 or C11 mode"

    @arfneto

    int comparaString (char* str1,char* str2)
    {
            int i,j,cont=0,CONT=0;
            
            for(i=0;str1[i]!=NULL;i++)
            {
                for(j=0;str2[j]!=NULL;j++)
                {
                    if(str1[i]==str2[j])
                    {
                        cont++;break;
                    }
                }
            }
            
            for(i=0;str2[i]!=NULL;i++)
            {
                for(j=0;str1[j]!=NULL;j++)
                {
                    if(str2[i]==str1[j])
                    {
                        CONT++;break;
                    }
                }
            }
            
            if (CONT>cont)
            {
                return cont;
            }
            else
            
            {
                return CONT;
            }
    }

     

    Não conta caracter repetido

  19. @arfneto não importa. cada "a" é considerado um "a" diferente.

    Esse foi o desafio:
    Develop a recursive function that determines the number of common characters between two strings s1 and s2. Grades: i. The solution must be in the C programming language; ii. If the same character appears n times in a given string, it will not be considered an error if your solution counts this character n times; iii. If your solution is broken down into more than one function (so that the main one - which solves the proposed problem - calls other helpers), all functions must be recursive;

    @arfneto "não use char[100]. É limitante a toa. Se possível use "const char*"."

    Sim, depois eu deixo o código elegante.

    18 minutos atrás, Comunista.RJ disse:

    @arfneto não importa. cada "a" é considerado um "a" diferente.

    Esse foi o desafio:
    Develop a recursive function that determines the number of common characters between two strings s1 and s2. Grades: i. The solution must be in the C programming language; ii. If the same character appears n times in a given string, it will not be considered an error if your solution counts this character n times; iii. If your solution is broken down into more than one function (so that the main one - which solves the proposed problem - calls other helpers), all functions must be recursive;

    @arfneto "não use char[100]. É limitante a toa. Se possível use "const char*"."

    Sim, depois eu deixo o código elegante.

    @arfneto "um "problema": não declare variáveis de controle fora do loop, em especial ums com nomes comuns tipo i e j como aqui. Isso sempre cai na sua cabeça. A comunidade lutou por anos até o comitê ISO que controla C mudar a linguagem para aceitar essas declarações no próprio for. Só que foi no final dos anos 80. É norma em toda empresa que tenha um código de aderência para programação, em toda escola séria: nada de globais, total foco na redução de escopo de variáveis. Nada de variáveis de controle soltas pelo programa. Tanto é assim que desde '17 por exemplo em C++ se pode declarar variáveis dentro de if() e switch() também, e variáveis podem ser declaradas dentro de qualquer bloco {}."

     

    arquivos ".c" não aceitam declarar a variável dentro do for

    7 horas atrás, arfneto disse:
    
    int comparaString (char str1[100],char str2[100])
    {
    		int i,j,cont=0;
    		
    		for(i=0;str1[i]!=NULL;i++)
    		{
    			for(j=0;str2[j]!=NULL;j++)
    			{
    				if(str1[i]==str2[j])
    				{
    					cont++;
    				}
    			}
    		}	
    		return cont;
    }

     

    Ainda sobre a função como escreveu:

    • imagino que pretendesse retornar false quando as strings fossem diferentes, zero no popular.  E 1 quando forem iguais, mas está contando e retornando apenas o número de letras iguais. Ou pretendia apenas retornar o número de vezes que alguma letra de str1 aparece em str2 ou algo assim? Acho que te qualquer maneira não está certo porque está comparando todas as letras de str2 com cada letra de str1 e isso pode não ter um significado objetivo, já que as strings podem ter letras repetidas... Escreva explicando o que pretende se não é comparar as strings apenas.
       
      De qualquer forma o que vou te mostrar se aplica do mesmo modo.

       
    • um "problema": não declare variáveis de controle fora do loop, em especial ums com nomes comuns tipo i e j como aqui. Isso sempre cai na sua cabeça. A comunidade lutou por anos até o comitê ISO que controla C mudar a linguagem para aceitar essas declarações no próprio for. Só que foi no final dos anos 80. É norma em toda empresa que tenha um código de aderência para programação, em toda escola séria: nada de globais, total foco na redução de escopo de variáveis. Nada de variáveis de controle soltas pelo programa. Tanto é assim que desde '17 por exemplo em C++ se pode declarar variáveis dentro de if() e switch() também, e variáveis podem ser declaradas dentro de qualquer bloco {}.
       

    • evite char[]. Não é relevante e só limita as coisas. Deixe char* ou melhor const char* assim fica claro que não vai mudar a entrada e que a função pode ser chamada com literais ou ponteiros 
       

    • outra "norma" comum a todos os guias de boas práticas: não declare mais que uma variável por linha. Inicialize todas as variáveis.

    Claro que software é um trabalho criativo e cada um tem suas idéias. Mas hoje em dia mal se consegue escolher a linguagem. E quando trabalha para uma empresa grande ou mesmo pequena tem que se ater às regras locais. Isso pode e em geral significa coisas como

    • tamanho máximo de uma função em número de linhas
    • regras precisas sobre onde colocar colchetes, chaves, parênteses e vírgulas
    • regras para documentação e comentários
    • regras para sufixos ou prefixos de variáveis membro, nomes de funções e classes
    • limites para o número de colunas usadas, em geral 60
    • regras para alinhamento de comandos e declarações

    E mais coisas do tipo. Um p0rr3. Mas a ideia é que qualquer um possa continuar o seu trabalho lá, e você possa continuar o trabalho de qualquer um. Em muitas escolas é assim também: alguém manda.

     

    De volta o ao programa:
     

    
    int comparaString2 (char* str1, char* str2 )
    {
        while( *str1 != 0 )
        {
            if ( *str2 == 0 ) return 0;
            if( *str1 != *str2 ) return 0;
            str1+=1; str2+=1;
        };
        return ( *str2 == 0);
    };  


    Algo assim já funcionaria. Veja que não precisa de nenhuma variável. E assim é mais eficiente. Na dúvida meça.

     

    E a recursão afinal?


    Esse é um exemplo comum de recursão para iniciantes, mas não é esperto: iterar em um vetor, como o caso da função que escreveu e dessa aí acima que eu mostrei, É muito mais eficiente que usar recursão. Como dez ou vinte vezes mais rápido. Centenas de vezes se as strings são grandes. E não usa memória extra nem nada.


    Estamos entrando em uma época em que tudo vai pra tal nuvem e a CPU é cobrada por segundo no Azure, GCloud, Amazon... :) 

     

    De volta ao problema:


    Pensando do modo recursivo você só pensa em uma letra: se elas são iguais você anda uma posição nas strings e continua. Assim que achar uma diferença para o ciclo e retorna.


    Pode ser algo simples assim em 😄

     

    
    int comparaString3 ( char* str1, char* str2 )
    {
        if ( *str1 != 0 )
        {
            if ( *str2 == 0 )       return 0;
            if ( *str1 == *str2 )   return comparaString3( ++str1, ++str2 );
            return 0;
        }
        else
            return ( *str2 == 0 );
    };

     

    Pode usar essa para comparar os resultados entre as funções, por exemplo entre as 3 versões aqui:
     

    
    void testaF(
        unsigned n, const char* teste[][2],
        int(*f)(char*,char*), const char* msg)
    {
       	if( msg != NULL )
            printf("\n\n%s\n\n\t==> %d testes:\n\n",msg,n);
        else
       	    printf ( "\n\n==> %d testes:\n\n", n );
    
     	for (int i=0;i<n;i++)
        {
             printf("\
    %02d/%02d  \"%s\" vs \"%s\" retornou %d\n",
            1+i,n, teste[i][0], teste[i][1], 
            f( (char*) teste[i][0], (char*) teste[i][1] ) );
          }; // for()

     

    Para usar é trivial, usando uma tabela teste de strings para acelerar os testes comuns:

     

    
        int n = sizeof(teste)/(2 * sizeof(char*));
        testaF( n, teste,
            comparaString2, 
            "Usando funcao iterativa");
    
        testaF( n, teste,
            comparaString, 
            "Usando funcao original");
    
        testaF( n, teste,
            comparaString3, 
            "Usando funcao recursiva");

     

    Para essa tabela
     

    
      	const char* teste[][2] =
          {
              { "azul", "azul" },
              { "zul", "azul" },
              { "azul", "zul" },
              { "", "azul" },
              { "", "" },
              { "uma string", "uma string" },
              { "uma string", "uma strinG" },
              { "coisa", "" }
           };

     

    Mostraria
     

    
    
    Usando funcao iterativa
    
            ==> 8 testes:
    
    01/08  "azul" vs "azul" retornou 1
    02/08  "zul" vs "azul" retornou 0
    03/08  "azul" vs "zul" retornou 0
    04/08  "" vs "azul" retornou 0
    05/08  "" vs "" retornou 1
    06/08  "uma string" vs "uma string" retornou 1
    07/08  "uma string" vs "uma strinG" retornou 0
    08/08  "coisa" vs "" retornou 0
    
    
    Usando funcao original
    
            ==> 8 testes:
    
    01/08  "azul" vs "azul" retornou 4
    02/08  "zul" vs "azul" retornou 3
    03/08  "azul" vs "zul" retornou 4
    04/08  "" vs "azul" retornou 0
    05/08  "" vs "" retornou 0
    06/08  "uma string" vs "uma string" retornou 10
    07/08  "uma string" vs "uma strinG" retornou 10
    08/08  "coisa" vs "" retornou 5
    
    
    Usando funcao recursiva
    
            ==> 8 testes:
    
    01/08  "azul" vs "azul" retornou 1
    02/08  "zul" vs "azul" retornou 0
    03/08  "azul" vs "zul" retornou 0
    04/08  "" vs "azul" retornou 0
    05/08  "" vs "" retornou 1
    06/08  "uma string" vs "uma string" retornou 1
    07/08  "uma string" vs "uma strinG" retornou 0
    08/08  "coisa" vs "" retornou 0

     

    A vantagem desa técnica --- comum --- é que você pode editar a tabela e ir acrescentando ou excluindo strings de teste e automaticamente testar o programa com TODAS as string e TODAS as funções, sem mudar nada.

     

    Note que a função original ainda está sem a correção que eu sugeri. comparaString() é a função que escreveu.

    comparaString2() é a função que eu mostrei. comparaString3() é a versão recursiva.

    Se não era isso que pretendia testar escreva de novo para eu entender o que quer comparar e o resultado que espera. E me desculpe ;) 

     

    Eis o programa de teste:

      Ocultar conteúdo
    
    
    #include <stdio.h>
    #include <string.h>
    
    int comparaString (char[100],char [100]);
    int comparaString2 (char*, char* );
    int comparaString3 (char*, char* );
    
    void testaF(unsigned, const char*[][2],
        int(*)(char*,char*), const char* );
    
    int main()
    {
      	const char* teste[][2] =
          {
              { "azul", "azul" },
              { "zul", "azul" },
              { "azul", "zul" },
              { "", "azul" },
              { "", "" },
              { "uma string", "uma string" },
              { "uma string", "uma strinG" },
              { "coisa", "" }
           };
    
        int n = sizeof(teste)/(2 * sizeof(char*));
    
        testaF( n, teste,
            comparaString2, 
            "Usando funcao iterativa");
    
        testaF( n, teste,
            comparaString, 
            "Usando funcao original");
    
         testaF( n, teste,
            comparaString3, 
            "Usando funcao recursiva");
    
      	return 0;
    };
    
    int comparaString (char str1[100],char str2[100])
    {
    		int i,j,cont=0;
    		
    		for(i=0;str1[i]!=0;i++)
    		{
    			for(j=0;str2[j]!=0;j++)
    			{
    				if(str1[i]==str2[j])
    				{
    					cont++;
    				}
    			}
    		}
    	
    		return cont;
    }
    
    int comparaString2 (char* str1, char* str2 )
    {
        while( *str1 != 0 )
        {
            if ( *str2 == 0 ) return 0;
            if( *str1 != *str2 ) return 0;
            str1+=1; str2+=1;
        };
        return ( *str2 == 0);
    };  
    
    int comparaString3 ( char* str1, char* str2 )
    {
        if ( *str1 != 0 )
        {
            if ( *str2 == 0 )       return 0;
            if ( *str1 == *str2 )   return comparaString3( ++str1, ++str2 );
            return 0;
        }
        else
            return ( *str2 == 0 );
    };  
    
    void testaF(
        unsigned n, const char* teste[][2],
        int(*f)(char*,char*), const char* msg)
    {
       	if( msg != NULL )
            printf("\n\n%s\n\n\t==> %d testes:\n\n",msg,n);
        else
       	    printf ( "\n\n==> %d testes:\n\n", n );
    
     	for (int i=0;i<n;i++)
        {
             printf("\
    %02d/%02d  \"%s\" vs \"%s\" retornou %d\n",
            1+i,n, teste[i][0], teste[i][1], 
            f( (char*) teste[i][0], (char*) teste[i][1] ) );
          }; // for()
    
    };

     

     

     

     

    Só a minha iterativa que funcionou

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!