-
Posts
90 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Fabricantes
Livros
Cursos
Análises
Fórum
posts postados por jcgs98
-
-
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
-
#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); } }
- 1
-
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); }
- 1
-
@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:Nesse compilador online retorna 9
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 e isso é folclórico
Você e 3 pessoas vão rir muito. O resto vai saber o que houve...
- 1
-
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. 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 empresasMais ainda, em gcc 9.3, Ubuntu, com gets()
Ao menos retornou 8
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
Em gcc em Linux retorna em geral 9:
no windows
No SUSE Linux
Ou no Ubuntu
Mas no Windows com o compilador da Microsoft retorna 7
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 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...
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()
#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 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ê?
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!
-
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...
-
23 minutos atrás, arfneto disse:
Eita!
Custa você admitir que não sabe?
Segue:
String1...:
azulString2...:
aazz uullExistem 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 stringString2...:
uma strinGExistem 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.
- 1
-
String1...:
abcdefghijaString2...:
aExistem 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 aString2...:
aExistem 3 caracteres comuns entre as duas strings
--------------------------------
Process exited after 3.472 seconds with return value 0
Pressione qualquer tecla para continuar. . .
String1...:
bbbString2...:
abExistem 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:String1...:
abcdefghijaString2...:
aExistem 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 aString2...:
aExistem 3 caracteres comuns entre as duas strings
--------------------------------
Process exited after 3.472 seconds with return value 0
Pressione qualquer tecla para continuar. . .
String1...:
bbbString2...:
abExistem 3 caracteres comuns entre as duas strings
--------------------------------
Process exited after 6.962 seconds with return value 0
Pressione qualquer tecla para continuar. . .
String1...:
bbbString2...:
babExistem 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:String1...:
abcdefghijaString2...:
aExistem 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 aString2...:
aExistem 3 caracteres comuns entre as duas strings
--------------------------------
Process exited after 3.472 seconds with return value 0
Pressione qualquer tecla para continuar. . .
String1...:
bbbString2...:
abExistem 3 caracteres comuns entre as duas strings
--------------------------------
Process exited after 6.962 seconds with return value 0
Pressione qualquer tecla para continuar. . .
String1...:
bbbString2...:
babExistem 6 caracteres comuns entre as duas strings
--------------------------------
Process exited after 2.625 seconds with return value 0
Pressione qualquer tecla para continuar. . .String1...:
MATRIXString2...:
MATRISXExistem 6 caracteres comuns entre as duas strings
--------------------------------
Process exited after 9.389 seconds with return value 0
Pressione qualquer tecla para continuar. . . -
@arfneto Se não funciona no seu compilador... paciência. você querendo ou não está certa. Abraços.
-
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); } }
-
Em 16/11/2020 às 23:06, arfneto disse:
ah! Pena que o programa não veio falar por ele
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); } }
-
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 vezesE 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.
-
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".
-
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"); } }
-
#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!
-
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:
-
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!
-
@arfneto Não vale porque tem laço "for". Vou tentar por aqui, se eu conseguir eu posto. Abraços.
-
@arfneto existe sim, são só jogo de palavras usados para compreensão do que se quer.
-
-
@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.
- 1
-
@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"
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
-
@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 emint 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:
#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
-
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.
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
Transformar inteiro em binario usando recursividade
em C/C#/C++
Postado