-
Posts
46 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Fabricantes
Livros
Cursos
Análises
Fórum
posts postados por NhemonF
-
-
1 hora atrás, arfneto disse:
// se posiciona no inicio No* destino = outra->inicio; while (f[ordem](destino, origem->prod) > 0) { antes = destino; // nao tem ponteiros para tras destino = destino->prox; // avanca }; // while()
Só não entendi de onde veio o "antes"... Da onde ele veio?
Vou escrever o que você escreveu, se importar. E o que eu imaginei. Mas por enquanto em ordem crescente:
Lista *ordenar(const Lista *L, int ordem) { // IMPLEMENTE ESTA FUNÇÃO //Estou pensando em como fazer if (listaEstaVazia(L)) { return; } else { Lista *Crescente = criaLista(); No *destino = Crescente->inicio; No *origem = L->inicio; int (*f[4]) (No*, Produto*); while (f[ordem] (destino, origem->prod) > 0) { No *antes = destino; insereNoInicio(Crescente, destino->prod->num_serie, destino->prod->preco, destino->prod->nome); destino = destino->prox; } } } int f_crescente(No* no_na_lista, Produto* novo) { if (novo == NULL) return 1; // nao esperado if (no_na_lista == NULL) { return -1; // acabou }; return no_na_lista->prod->num_serie < novo->num_serie; // aqui }
-
11 horas atrás, arfneto disse:
E então se é isso que tem que fazer é mais simples, já que vai criar outra lista afinal e não indexar a mesma por outro critério. No entanto é mais uma b0b@g3m do enunciado, porque o critério então tinha que fazer parte da lista, de modo que todas as inserções seguissem o mesmo critério no futuro.
11 horas atrás, arfneto disse:Sem isso novas inserções serão sempre no início, algo praticamente inútil e destruindo a classificação. Insisto que era mais prático e simples manter os ponteiros TODOS dentro da mesma lista, mas um enunciado é um enunciado.
Bom... quer dizer então que devo, basicamente, escrever uma Bubble Sort para ordenar de forma decrescente ou crescente?
Porque, pelo que entendi em outros fóruns e outros artigos que busquei ver, a função irá percorrer todo a lista simples encadeada, e verificar se o num_serie é menor que o outro.
-
@arfneto Acho que pra ficar melhor, vou colar o código com as alterações.
/*************************** * LAB 04 - 02/12/2020 * SEU NOME - SEU PRONTUÁRIO ***************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> // struct que define um produto typedef struct _produto { int num_serie; // numero de série do produto char nome[64]; double preco; } Produto; // struct que define um nó curcular duplamente encadeado typedef struct _no { Produto *prod; struct _no *prox; } No; // struct que define uma Lista Ligada Simples typedef struct _lista { No *inicio; No *fim; int tamanho; // numero de nós da lista } Lista; typedef struct { No *inicio; No *fim; No* i_crescente; No* f_crescente; No* i_decrescente; No* f_decrescente; int tamanho; } Lista1; typedef struct { No *inicio; No *fim; No* H[3]; // head 0 cronologico No* T[3]; // tail 1 cresc 2 decresc int tamanho; } Lista2; /*********** HEADERS ***********/ Produto *criaProduto(int num_serie, double preco, char nome[64]); void destroiProduto(Produto **prod_ref); No *criaNo(int num_serie, double preco, char nome[64]); Lista *criaLista(); void destroiLista(Lista **L_ref); int listaEstaVazia(const Lista *L); void imprime(const Lista *L); void imprime_ultimo(const Lista *L); // A SEREM IMPLEMENTADAS POR VOCÊ void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]); void removeProduto(Lista *L, int num_serie); void removePrimeiraMetade(Lista *L); Lista *inverter(const Lista *L); Lista *ordenar(const Lista *L, int ordem); /*******************************/ int main() { Lista *L = criaLista(); char comando[64]; int ordem; int num_serie; char nome[64]; double preco; scanf("%s", comando); while (strcmp(comando, "para") != 0) { if (strcmp(comando, "insere_inicio") == 0) { scanf("%d", &num_serie); scanf("%lf", &preco); scanf(" %[^\t\n]s", nome); insereNoInicio(L, num_serie, preco, nome); } else if (strcmp(comando, "remove_produto") == 0) { scanf("%d", &num_serie); removeProduto(L, num_serie); } else if (strcmp(comando, "remove_primeira_metade") == 0) { removePrimeiraMetade(L); } else if (strcmp(comando, "inverte") == 0) { Lista *L_aux = inverter(L); destroiLista(&L); L = L_aux; } else if (strcmp(comando, "ordena") == 0) { scanf("%d", &ordem); Lista *L_aux = ordenar(L, ordem); destroiLista(&L); L = L_aux; } else if (strcmp(comando, "imprime") == 0) { imprime(L); } scanf("%s", comando); } return 0; } //////////////////////////////////// /*************** BODIES *****************/ // (a) Insere um nó no início da Lista com um novo produto, que possui os valores passados por parâmetro. void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]) { // IMPLEMENTE ESTA FUNÇÃO No *p = criaNo(num_serie, preco, nome); //Cria um nó de um produto para inserir os dados p->prox = L->inicio; //Aponta a partir do início da lista encadeada L->inicio = p; //Coloca os dados do produto pro início L->tamanho++; //Aumenta o tamanho da lista para cada produto adicionado no encadeamento. if (L->fim == NULL) { L->fim = p; } } // (b) Remove o nó da lista cujo produto possua o número de série num_serie. // Assuma que o número de série é único na lista. // Se a lista estiver vazia ou não existir nenhum produto com o número de série, nada acontece. void removeProduto(Lista *L, int num_serie) { // IMPLEMENTE ESTA FUNÇÃO //caso a lista esteja vazia if (listaEstaVazia(L)) { return; } //variável que indica se o número de serie foi encontrado ou não // 0 para não // 1 para sim int encontrou = 0; //verifica se o número encontrado está no início if(L->inicio->prod->num_serie == num_serie) { L->inicio = L->inicio->prox; encontrou = 1; L->tamanho--; } //verifica se o número encontrado está em qualquer posição else { No *no = L->inicio; No *anterior = NULL; //percorre todo o nó da lista para encontrar o valor inserido while(no != NULL && encontrou == 0) { if(no->prod->num_serie == num_serie) { anterior->prox = no->prox; encontrou = 1; L->tamanho--; } anterior = no; no = no->prox; } } } // (c) Remove a primeira metade da Lista. Caso a lista possua um número ímpar de elementos, // considere que a primeira metade possui mais elementos // (Ex: se a lista possuir 5 elementos, a primeira metade possui os 3 primeiros elementos). // Se a lista tiver vazia, nada acontece. void removePrimeiraMetade(Lista *L) { // IMPLEMENTE ESTA FUNÇÃO //Estou pensando no código } // (d) Retorna a Lista invertida. Se a lista está vazia, retorne uma lista vazia. Lista *inverter(const Lista *L) { // IMPLEMENTE ESTA FUNÇÃO if (L == NULL) return NULL; No* p = L->inicio; Lista* Outra = criaLista(); if (Outra == NULL) return NULL; while (p != NULL) { insereNoInicio(Outra, p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; }; // while() return Outra; return NULL; } // (e) Retorna a lista ordenada pelo número de série de seus produtos, de acordo com uma ordem passada pelo programa: // ordem=0 significa ordem crescente; // ordem=1 significa ordem decrescente. Lista *ordenar(const Lista *L, int ordem) { // IMPLEMENTE ESTA FUNÇÃO if (listaEstaVazia(L)) { return NULL; } else { if (ordem == 0){ Lista *Crescente = criaLista(); No *p = L->inicio; int menor = p->prod->num_serie; while(p != NULL){ if (menor < p->prod->num_serie){ } p = p->prox; } return Crescente; } else { Lista *Decrescente = criaLista(); No *p = L->inicio; int maior = p->prod->num_serie; while (p != NULL){ if (maior > p->prod->num_serie){ } p = p->prox; } return Decrescente; } } } int f_crescente( Produto* um, Produto* outro) { return um->num_serie < outro->num_serie; } int f_decrescente( Produto* um, Produto* outro) { return um->num_serie > outro->num_serie; } /************ FUNÇÕES JÁ IMPLEMENTADAS *************/ Produto *criaProduto(int num_serie, double preco, char nome[64]) { Produto *prod = (Produto *)calloc(1, sizeof(Produto)); prod->num_serie = num_serie; prod->preco = preco; strcpy(prod->nome, nome); return prod; } void destroiProduto(Produto **prod_ref) { Produto *prod = *prod_ref; if (prod != NULL) { free(prod); *prod_ref = NULL; } } No *criaNo(int num_serie, double preco, char nome[64]) { No *no = (No*) calloc(1, sizeof(No)); no->prod = criaProduto(num_serie, preco, nome); no->prox = NULL; return no; } Lista *criaLista() { return ((Lista*) calloc(1, sizeof(Lista))); } void destroiLista(Lista **L) { Lista *L_aux = *L; // remove todos os nós da lista No *p = L_aux->inicio; while (p != NULL) { No *no = p; p = p->prox; destroiProduto(&no->prod); free(no); } free(L_aux); *L = NULL; } int listaEstaVazia(const Lista *L) { return (L->inicio == NULL); } void imprime(const Lista *L) { printf("Tamanho da lista: %d\n", L->tamanho); printf("L -> "); if (!listaEstaVazia(L)) { No *p = L->inicio; while (p != NULL) { printf("(%d, %.2lf, %s) -> ", p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; } } printf("NULL\n\n"); }
- 1
-
3 minutos atrás, arfneto disse:
Você leu mesmo o que eu expliquei? Mesmo sem usar o mais genérico, faça o simples. Não precisa ordenar nada. É a sua lista. Está criando agora. O seu programa. Modifique insere() e prepare os 3 ponteiros.
Eu li, mas não entendi muito bem o que você disse.
46 minutos atrás, arfneto disse:int f_crescente( Produto* um, Produto* outro) { return um->num_serie < outro->num_serie; } int f_decrescente( Produto* um, Produto* outro) { return um->num_serie > outro->num_serie; }
Eu devo criar estas funções dentro ou fora da função que havia feito?
-
Então, sobre isso, alterei o código da função.
Então ficou mais ou menos assim?
Lista *ordenar(const Lista *L, int ordem) { // IMPLEMENTE ESTA FUNÇÃO if (listaEstaVazia(L)) { return NULL; } else { if (ordem == 0){ Lista *Crescente = criaLista(); No *p = L->inicio; int menor = p->prod->num_serie; while(p != NULL){ if (menor < p->prod->num_serie){ insereNoInicio(Crescente, p->prod->num_serie, p->prod->preco, p->prod->nome); } p = p->prox; } return Crescente; } else { Lista *Decrescente = criaLista(); No *p = L->inicio; int maior = p->prod->num_serie; while (p != NULL){ if (maior > p->prod->num_serie){ insereNoInicio(Decrescente, p->prod->num_serie, p->prod->preco, p->prod->nome); } p = p->prox; } return Decrescente; } } }
Só que desta vez, ele apaga os menores números de série. E sobram apenas os maiores números.
-
Boa tarde (ou boa noite), pessoal!!
Estou ainda com uma dúvida referente ao exercício da faculdade que estou a fazer. O exercício consiste em um objetivo: queria ordenar de maneira crescente e decrescente uma lista ordenada pelo serial de um produto. Por exemplo:
1. Output da lista exemplo
L -> (324, 899.99, playstation 5) -> (892, 399.99, mouse gamer) -> (435, 199.99, headset gamer) -> NULL
2. Output da lista em ordem crescente
L -> (324, 899.99, playstation 5) -> (435, 199.99, headset gamer) -> (892, 399.99, mouse gamer) -> NULL
3. Output da lista em ordem decrescente
L -> (892, 399.99, mouse gamer) -> (435, 199.99, headset gamer) -> (324, 899.99, playstation 5) -> NULL
Só que não tenho certeza se fiz da forma certa esta função que fiz. Poderiam me dar uma ajuda neste código?
Alguns itens que estou utilizando na composição do código:
A. Função que ordena a lista, sendo crescente ou decrescente:
// (e) Retorna a lista ordenada pelo número de série de seus produtos, de acordo com uma ordem passada pelo programa: // ordem=0 significa ordem crescente; // ordem=1 significa ordem decrescente. Lista *ordenar(const Lista *L, int ordem) { // IMPLEMENTE ESTA FUNÇÃO //Estou pensando em como fazer if (ordem == 0){ Lista *Crescente = criaLista(); No *p; No *menor = p->prod->num_serie; if (listaEstaVazia(L)){return -1;} if (listaEstaVazia(Crescente)){return -1;} while(p != NULL){ insereNoInicio(Crescente, p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; } return Crescente; } else { Lista *Decrescente = criaLista(); No *p; No *maior = p->prod->num_serie; if (listaEstaVazia(L)){return -1;} if (listaEstaVazia(Decrescente)) {return -1;} while (p != NULL){ insereNoInicio(Decrescente, p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; } return Decrescente; } }
B. Structs 'no', 'lista' e 'produto':
// struct que define um produto typedef struct _produto { int num_serie; // numero de série do produto char nome[64]; double preco; } Produto; // struct que define um nó curcular duplamente encadeado typedef struct _no { Produto *prod; struct _no *prox; } No; // struct que define uma Lista Ligada Simples typedef struct _lista { No *inicio; No *fim; int tamanho; // numero de nós da lista } Lista;
C. Função inserida na main para execução:
else if (strcmp(comando, "ordena") == 0) { scanf("%d", &ordem); Lista *L_aux = ordenar(L, ordem); destroiLista(&L); L = L_aux; }
-
@arfneto Ok!!
Agradeço demais!!
- 1
-
@arfneto Aproveitando esta deixa, poderia me ajudar um pouco mais no programa?
Eu sei que estou tomando muito do seu tempo, mas estou com dúvidas a respeito deste programa
Bom, agora pra ordenar de forma crescente e decrescente, de acordo com o número de série do produto, devo criar um ponteiro chamado "crescente", que seria o ponteiro de Lista e igualar a L. Certo?
E depois criar o nó *p, que vai apontar para o produto, e que por sua vez vai apontar para o número de série?
Como no código abaixo:
Lista *ordenar(const Lista *L, int ordem) { // IMPLEMENTE ESTA FUNÇÃO //Estou pensando em como fazer if (ordem == 0){ Lista *Crescente = L; No *p = p->prod->num_serie; while (p != NULL){ insereNoInicio(Crescente, p->prod->num_serie, p->prod->preco, p->prod->nome); p->prod->num_serie = p->prox; } } }
-
@arfneto Queria agradecer pela ajuda e pelo tempo que você teve para me ajudar neste exercício. Desculpe pela minha lerdeza em pensar (que faz jus à foto do perfil)
- 1
-
@arfneto Ah!! Desculpe. Vou ler aqui
8 minutos atrás, arfneto disse:Leia o que acrescentei agora e talvez entenda melhor o que está errado...
Agora entendi!!
Pelo que vi no seu código e o que eu escrevi bem no início do post, vi que equivoquei bastante em tentar inverter a ordem, como se fosse uma lista duplamente encadeada.
Tentei fazer esta possibilidade de uma lista simplesmente encadeada se tornar duplamente encadeada pelo método que fiz
Agora esclareceu bastante!!!
-
**mensagem apagada**
-
@arfneto Vou postar o código aqui mesmo.
/*************************** * LAB 04 - 02/12/2020 * SEU NOME - SEU PRONTUÁRIO ***************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> // struct que define um produto typedef struct _produto { int num_serie; // numero de série do produto char nome[64]; double preco; } Produto; // struct que define um nó curcular duplamente encadeado typedef struct _no { Produto *prod; struct _no *prox; } No; // struct que define uma Lista Ligada Simples typedef struct _lista { No *inicio; No *fim; int tamanho; // numero de nós da lista } Lista; /*********** HEADERS ***********/ Produto *criaProduto(int num_serie, double preco, char nome[64]); void destroiProduto(Produto **prod_ref); No *criaNo(int num_serie, double preco, char nome[64]); Lista *criaLista(); void destroiLista(Lista **L_ref); int listaEstaVazia(const Lista *L); void imprime(const Lista *L); void imprime_ultimo(const Lista *L); // A SEREM IMPLEMENTADAS POR VOCÊ void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]); void removeProduto(Lista *L, int num_serie); void removePrimeiraMetade(Lista *L); Lista *inverter(const Lista *L); Lista *ordenar(const Lista *L, int ordem); /*******************************/ int main() { Lista *L = criaLista(); char comando[64]; int ordem; int num_serie; char nome[64]; double preco; scanf("%s", comando); while (strcmp(comando, "para") != 0) { if (strcmp(comando, "insere_inicio") == 0) { scanf("%d", &num_serie); scanf("%lf", &preco); scanf(" %[^\t\n]s", nome); insereNoInicio(L, num_serie, preco, nome); } else if (strcmp(comando, "remove_produto") == 0) { scanf("%d", &num_serie); removeProduto(L, num_serie); } else if (strcmp(comando, "remove_primeira_metade") == 0) { removePrimeiraMetade(L); } else if (strcmp(comando, "inverte") == 0) { Lista *L_aux = inverter(L); destroiLista(&L); L = L_aux; } else if (strcmp(comando, "ordena") == 0) { scanf("%d", &ordem); Lista *L_aux = ordenar(L, ordem); destroiLista(&L); L = L_aux; } else if (strcmp(comando, "imprime") == 0) { imprime(L); } scanf("%s", comando); } return 0; } //////////////////////////////////// /*************** BODIES *****************/ // (a) Insere um nó no início da Lista com um novo produto, que possui os valores passados por parâmetro. void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]) { // IMPLEMENTE ESTA FUNÇÃO No *p = criaNo(num_serie, preco, nome); //Cria um nó de um produto para inserir os dados p->prox = L->inicio; //Aponta a partir do início da lista encadeada L->inicio = p; //Coloca os dados do produto pro início L->tamanho++; //Aumenta o tamanho da lista para cada produto adicionado no encadeamento. } // (b) Remove o nó da lista cujo produto possua o número de série num_serie. // Assuma que o número de série é único na lista. // Se a lista estiver vazia ou não existir nenhum produto com o número de série, nada acontece. void removeProduto(Lista *L, int num_serie) { // IMPLEMENTE ESTA FUNÇÃO //caso a lista esteja vazia if (listaEstaVazia(L)) { return; } //variável que indica se o número de serie foi encontrado ou não // 0 para não // 1 para sim int encontrou = 0; //verifica se o número encontrado está no início if(L->inicio->prod->num_serie == num_serie) { L->inicio = L->inicio->prox; encontrou = 1; L->tamanho--; } //verifica se o número encontrado está em qualquer posição else { No *no = L->inicio; No *anterior = NULL; //percorre todo o nó da lista para encontrar o valor inserido while(no != NULL && encontrou == 0) { if(no->prod->num_serie == num_serie) { anterior->prox = no->prox; encontrou == 1; L->tamanho--; } anterior = no; no = no->prox; } } } // (c) Remove a primeira metade da Lista. Caso a lista possua um número ímpar de elementos, // considere que a primeira metade possui mais elementos // (Ex: se a lista possuir 5 elementos, a primeira metade possui os 3 primeiros elementos). // Se a lista tiver vazia, nada acontece. void removePrimeiraMetade(Lista *L) { // IMPLEMENTE ESTA FUNÇÃO //Estou pensando no código } // (d) Retorna a Lista invertida. Se a lista está vazia, retorne uma lista vazia. Lista *inverter(const Lista *L) { // IMPLEMENTE ESTA FUNÇÃO Lista *Outra; if ( L == NULL ) return -1; if ( Outra == NULL ) return -1; if (!listaEstaVazia(L)) { No *p = L->inicio; No *ant = NULL; while (p != NULL) { insereNoInicio(Outra, p->prod->num_serie, p->prod->preco, p->prod->nome); ant->prox = p->prox; p->prox = p; } } } // (e) Retorna a lista ordenada pelo número de série de seus produtos, de acordo com uma ordem passada pelo programa: // ordem=0 significa ordem crescente; // ordem=1 significa ordem decrescente. Lista *ordenar(const Lista *L, int ordem) { // IMPLEMENTE ESTA FUNÇÃO //Estou pensando em como fazer if (ordem == 0){ if (listaEstaVazia(L)){ return; } else { } } else { if (listaEstaVazia(L)){ return; } else { } } } /************ FUNÇÕES JÁ IMPLEMENTADAS *************/ Produto *criaProduto(int num_serie, double preco, char nome[64]) { Produto *prod = (Produto *)calloc(1, sizeof(Produto)); prod->num_serie = num_serie; prod->preco = preco; strcpy(prod->nome, nome); return prod; } void destroiProduto(Produto **prod_ref) { Produto *prod = *prod_ref; if (prod != NULL) { free(prod); *prod_ref = NULL; } } No *criaNo(int num_serie, double preco, char nome[64]) { No *no = (No*) calloc(1, sizeof(No)); no->prod = criaProduto(num_serie, preco, nome); no->prox = NULL; return no; } Lista *criaLista() { return ((Lista*) calloc(1, sizeof(Lista))); } void destroiLista(Lista **L) { Lista *L_aux = *L; // remove todos os nós da lista No *p = L_aux->inicio; while (p != NULL) { No *no = p; p = p->prox; destroiProduto(&no->prod); free(no); } free(L_aux); *L = NULL; } int listaEstaVazia(const Lista *L) { return (L->inicio == NULL); } void imprime(const Lista *L) { printf("Tamanho da lista: %d\n", L->tamanho); printf("L -> "); if (!listaEstaVazia(L)) { No *p = L->inicio; while (p != NULL) { printf("(%d, %.2lf, %s) -> ", p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; } } printf("NULL\n\n"); }
-
16 minutos atrás, arfneto disse:
Eu ainda não entendi direito... "Eu acho que assim daria um erro ao compilar" Como assim? Apenas compile e veja se dá erro.
Então, o código deu erro. Não saiu a lista invertida.
-
53 minutos atrás, arfneto disse:
Mas pode apenas não usar
Não está assim muito bom. main() por outro lado está bem ruim, com todos os erros que parecem obrigatórios.
- teste o retorno de scanf(). Já leu o manual? Qual o propósito de seguir se pode não ter lido nada?
- qual a razão de ler sem um único prompt?
- qual a razão de ler do teclado? Mesmo que o enunciado exija é MUITO mais simples e seguro testar com constantes ou ler de um arquivo.
- ler valores sem um único prompt? Não seria gentil dizer o que e como espera ler?
- não seria razoável mostrar o que leu ao menos enquanto está testando?
- quando declara algo está declarando o nome. Não use o asterisco junto à variável. Não reflete o que est;a fazendo.
-
Esse tipo de função
void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]);
É de certa ingenuidade. Escreva
void insereNoInicio(_produto*,Lista *L);
Que é muito mais esperto. E mesmo que precise escrever com o protótipo fornecido escreva
void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]) { _produto um; um.num_serie = num_serie; um.preco = preco; strcpy(um.nome, nome); insere( &um, L); return; }
E mostre ao seu professor que você pensou melhor que ele.Entenda que uma lista tem nós. As chamadas das funções de lista não podem usar dados que estão nos nós. É ingenuidade.
E os nós tem dados e uma chave. E a chave pode ou não fazer parte dos dados. Assim é
Se você em essa função aí e esta funcionando, e você tem essa
void imprime(const Lista *L) { printf("Tamanho da lista: %d\n", L->tamanho); printf("L -> "); if (!listaEstaVazia(L)) { No *p = L->inicio; while (p != NULL) { printf("(%d, %.2lf, %s) -> ", p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; } } printf("NULL\n\n"); }
O que acha que vai acontecer se você escrever
int imprime_e_faz_aquilo(const Lista *L, const Lista* Outra ) { if ( L == NULL ) return -1; if ( Outra == NULL ) return -1; printf("Tamanho da lista: %d\n", L->tamanho); printf("L -> "); if (!listaEstaVazia(L)) { No *p = L->inicio; while (p != NULL) { printf("(%d, %.2lf, %s) -> ", p->prod->num_serie, p->prod->preco, p->prod->nome); insereNoInicio(Outra, p->prod->num_serie, p->prod->preco, p->prod->nome); // ====< p = p->prox; } } printf("NULL\n\n"); }
Pois é.
Não entendeu mesmo o que eu disse?
E essa função?
int faz_aquilo(const Lista *L, const Lista* Outra ) { if ( L == NULL ) return -1; if ( Outra == NULL ) return -1; if (!listaEstaVazia(L)) { No *p = L->inicio; while (p != NULL) { insereNoInicio(Outra, p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; } } }
Faria o que?
Eu ainda não entendi direito... Eu acho que assim daria um erro ao compilar.
Na verdade, acho que tenho uma pequena ideia. Mas não sei se para você estaria certo:
Criar um nó do qual aponta para o fim da lista.
Eu iria criar um nó que aponta para o fim da lista?
Basicamente assim?
int faz_aquilo(const Lista *L, const Lista* Outra ) { if ( L == NULL ) return -1; if ( Outra == NULL ) return -1; if (!listaEstaVazia(L)) { No *p = L->fim; No *ant = NULL; while (p != NULL) { insereNoInicio(Outra, p->prod->num_serie, p->prod->preco, p->prod->nome); ant->prox = p->prox; } } }
-
@arfneto Ok. Vou postar o código.
OBS: Tem algumas linhas do código que não posso alterá-las.
/*************************** * LAB 04 - 02/12/2020 * SEU NOME - SEU PRONTUÁRIO ***************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> // struct que define um produto typedef struct _produto { int num_serie; // numero de série do produto char nome[64]; double preco; } Produto; // struct que define um nó curcular duplamente encadeado typedef struct _no { Produto *prod; struct _no *prox; } No; // struct que define uma Lista Ligada Simples typedef struct _lista { No *inicio; No *fim; int tamanho; // numero de nós da lista } Lista; /*********** HEADERS ***********/ Produto *criaProduto(int num_serie, double preco, char nome[64]); void destroiProduto(Produto **prod_ref); No *criaNo(int num_serie, double preco, char nome[64]); Lista *criaLista(); void destroiLista(Lista **L_ref); int listaEstaVazia(const Lista *L); void imprime(const Lista *L); void imprime_ultimo(const Lista *L); // A SEREM IMPLEMENTADAS POR VOCÊ void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]); void removeProduto(Lista *L, int num_serie); void removePrimeiraMetade(Lista *L); Lista *inverter(const Lista *L); Lista *ordenar(const Lista *L, int ordem); /*******************************/ int main() { Lista *L = criaLista(); char comando[64]; int ordem; int num_serie; char nome[64]; double preco; scanf("%s", comando); while (strcmp(comando, "para") != 0) { if (strcmp(comando, "insere_inicio") == 0) { scanf("%d", &num_serie); scanf("%lf", &preco); scanf(" %[^\t\n]s", nome); insereNoInicio(L, num_serie, preco, nome); } else if (strcmp(comando, "remove_produto") == 0) { scanf("%d", &num_serie); removeProduto(L, num_serie); } else if (strcmp(comando, "remove_primeira_metade") == 0) { removePrimeiraMetade(L); } else if (strcmp(comando, "inverte") == 0) { Lista *L_aux = inverter(L); destroiLista(&L); L = L_aux; } else if (strcmp(comando, "ordena") == 0) { scanf("%d", &ordem); Lista *L_aux = ordenar(L, ordem); destroiLista(&L); L = L_aux; } else if (strcmp(comando, "imprime") == 0) { imprime(L); } scanf("%s", comando); } return 0; } //////////////////////////////////// /*************** BODIES *****************/ // (a) Insere um nó no início da Lista com um novo produto, que possui os valores passados por parâmetro. void insereNoInicio(Lista *L, int num_serie, double preco, char nome[64]) { // IMPLEMENTE ESTA FUNÇÃO No *p = criaNo(num_serie, preco, nome); //Cria um nó de um produto para inserir os dados p->prox = L->inicio; //Aponta a partir do início da lista encadeada L->inicio = p; //Coloca os dados do produto pro início L->tamanho++; //Aumenta o tamanho da lista para cada produto adicionado no encadeamento. } // (b) Remove o nó da lista cujo produto possua o número de série num_serie. // Assuma que o número de série é único na lista. // Se a lista estiver vazia ou não existir nenhum produto com o número de série, nada acontece. void removeProduto(Lista *L, int num_serie) { // IMPLEMENTE ESTA FUNÇÃO //caso a lista esteja vazia if (listaEstaVazia(L)) { return; } //variável que indica se o número de serie foi encontrado ou não // 0 para não // 1 para sim int encontrou = 0; //verifica se o número encontrado está no início if(L->inicio->prod->num_serie == num_serie) { L->inicio = L->inicio->prox; encontrou = 1; L->tamanho--; } //verifica se o número encontrado está em qualquer posição else { No *no = L->inicio; No *anterior = NULL; //percorre todo o nó da lista para encontrar o valor inserido while(no != NULL && encontrou == 0) { if(no->prod->num_serie == num_serie) { anterior->prox = no->prox; encontrou == 1; L->tamanho--; } anterior = no; no = no->prox; } } } // (c) Remove a primeira metade da Lista. Caso a lista possua um número ímpar de elementos, // considere que a primeira metade possui mais elementos // (Ex: se a lista possuir 5 elementos, a primeira metade possui os 3 primeiros elementos). // Se a lista tiver vazia, nada acontece. void removePrimeiraMetade(Lista *L) { // IMPLEMENTE ESTA FUNÇÃO //verifica se a lista está vazia } // (d) Retorna a Lista invertida. Se a lista está vazia, retorne uma lista vazia. Lista *inverter(const Lista *L) { // IMPLEMENTE ESTA FUNÇÃO printf("Tamanho da lista: %d\n", L->tamanho); printf("L -> "); if (!listaEstaVazia(L)) { No *p = L->fim; No *ant = NULL; while (p != NULL) { printf("(%d, %.2lf, %s) -> ", p->prod->num_serie, p->prod->preco, p->prod->nome); ant->prox = p->prox; } } printf("NULL\n\n"); } // (e) Retorna a lista ordenada pelo número de série de seus produtos, de acordo com uma ordem passada pelo programa: // ordem=0 significa ordem crescente; // ordem=1 significa ordem decrescente. Lista *ordenar(const Lista *L, int ordem) { // IMPLEMENTE ESTA FUNÇÃO if (ordem == 0){ if (listaEstaVazia(L)){ return; } else { } } else { if (listaEstaVazia(L)){ return; } else { } } } /************ FUNÇÕES JÁ IMPLEMENTADAS *************/ Produto *criaProduto(int num_serie, double preco, char nome[64]) { Produto *prod = (Produto *)calloc(1, sizeof(Produto)); prod->num_serie = num_serie; prod->preco = preco; strcpy(prod->nome, nome); return prod; } void destroiProduto(Produto **prod_ref) { Produto *prod = *prod_ref; if (prod != NULL) { free(prod); *prod_ref = NULL; } } No *criaNo(int num_serie, double preco, char nome[64]) { No *no = (No*) calloc(1, sizeof(No)); no->prod = criaProduto(num_serie, preco, nome); no->prox = NULL; return no; } Lista *criaLista() { return ((Lista*) calloc(1, sizeof(Lista))); } void destroiLista(Lista **L) { Lista *L_aux = *L; // remove todos os nós da lista No *p = L_aux->inicio; while (p != NULL) { No *no = p; p = p->prox; destroiProduto(&no->prod); free(no); } free(L_aux); *L = NULL; } int listaEstaVazia(const Lista *L) { return (L->inicio == NULL); } void imprime(const Lista *L) { printf("Tamanho da lista: %d\n", L->tamanho); printf("L -> "); if (!listaEstaVazia(L)) { No *p = L->inicio; while (p != NULL) { printf("(%d, %.2lf, %s) -> ", p->prod->num_serie, p->prod->preco, p->prod->nome); p = p->prox; } } printf("NULL\n\n"); }
-
@arfneto Entendi mais ou menos o que você disse.
Vou traduzir do português para C se entendi.
1) Caso a lista não esteja vazia:
if (!listaEstaVazia(L)){ //comando da função }
2) Crio um ponteiro de uma lista chamado "aux":
Lista *aux;
3) Crio um ponteiro de "No" chamado "p" que é equivalente ao nó do fim da lista:
No *p = L->fim
4) Crio um ponteiro de "No" chamado "ant", ou seja, quero que percorra para o anterior de "p":
No *ant = NULL
5) Enquanto o ponteiro "p" não for nulo, imprime a lista invertida:
while (p != NULL) { printf("(%d, %.2lf, %s) -> ", p->prod->num_serie, p->prod->preco, p->prod->nome); ant->prox = p->prox; }
É mais ou menos desta maneira?
-
@arfneto Então, tenho o programa inteiro para algum de vocês compilar. Se não se importar, posso publicar neste comentário.
E sobre as frases em negrito, eu queria inverter a lista pelo nó. Por exemplo, se eu haver uma lista simples com 5 elementos, preciso fazer com que inverta os nós da lista começando pelo último elemento. Certo?
L -> (800, 99.99, Polystation 5) -> (785, 299.99, Mouse Gamer) -> (584, 899.99, Intel Core i9 8700U) -> (123, 34.99, Mousepad Razer) -> (981, 199.99, XCaixa Series Y) -> NULL
L -> (981, 199.99, XCaixa Series Y) -> (123, 34.99, Mousepad Razer) -> (584, 899.99, Intel Core i9 8700U)-> (785, 299.99, Mouse Gamer) -> (800, 99.99, Polystation 5) -> NULL
@arfneto mas fica basicamente assim?
Lista *inverter(const Lista *L) { // IMPLEMENTE ESTA FUNÇÃO Lista *aux = L; No *p; No *ant = NULL; if (listaEstaVazia(L)){ return; } else { aux = L->fim; while(aux != NULL){ aux = L->fim; p = p->ant; L->fim = aux; } } return aux; }
-
Boa tarde pessoal
Estou com uma dúvida em um exercício de lista encadeada simples. Queria inserir o nó do início como fim, e o nó do fim como o início.
É basicamente nessa maneira:
**ANTES**
L -> (800, 99.99, Polystation 5) -> (981, 199.99, XCaixa Series Y) -> NULL
**DEPOIS**
L -> (981, 199.99, XCaixa Series Y) -> (800, 99.99, Polystation 5) -> NULL
Mas estou com um certo problema com o código, que quando executo o comando, ele não inverte.
A) Função que inverte o nó da lista
// (d) Retorna a Lista invertida. Se a lista está vazia, retorne uma lista vazia. Lista *inverter(const Lista *L) { // IMPLEMENTE ESTA FUNÇÃO Lista* q; /* variável auxiliar para nova lista */ No *p; int aux; for (p = L; p != NULL; p = p->prox) if (p-> == NULL) { aux = p->prox; p->prox = NULL; return p; } }
B) Structs de `_produto`, `_no` e `_lista`
// struct que define um produto typedef struct _produto { int num_serie; // numero de série do produto char nome[64]; double preco; } Produto;
// struct que define um nó curcular duplamente encadeado typedef struct _no { Produto *prod; struct _no *prox; } No;
// struct que define uma Lista Ligada Simples typedef struct _lista { No *inicio; No *fim; int tamanho; // numero de nós da lista } Lista;
C) Código acionado na `main()`:else if (strcmp(comando, "inverte") == 0) { Lista *L_aux = inverter(L); destroiLista(&L); L = L_aux; }
-
1 minuto atrás, arfneto disse:
Só isso. Ao invés de mostrar na tela compare. Insisto em que está superestimando o problema
Ok
Sim. Talvez esteja superestimando ele.
Mas estou começando a entender aos poucos. Achei este exercício da faculdade bastante difícil. Por isso, queria uma ajuda com este exercício.
Muito obrigado pela ajuda!!
-
Acho que agora, estou entendendo.
35 minutos atrás, arfneto disse:Sub-Matriz entre (2,2) e (4,4) 13 14 15 18 19 20 23 24 25
Agora pra fazer a somatória, encontrar o menor valor e o maior valor da sub-matriz, é só também procurar nos índices da submatriz e declará-los como "maior" e "menor"?
tipo assim:
-
agora, arfneto disse:
Não entendi. Se você quer "pegar" os elementos apenas use os indices deles. Se quer copiar claro que vai precisar de um destino. "pegar" seria o que?
Isso!! "Pegar" era exatamente o que você havia dito.
Agora, então, pra substituir, devo colocar o valor, e substituir em um intervalo (x,y) da matriz "teste" pelo número que eu quero?Por exemplo, neste código aqui:
scanf("%d %d %d %d $d", x1, y1, x2, y2, valor); for (int i=x1; i<x2; i++){ for (int j=y1; j<y2; j++){ teste[i][j] = valor; printf("%d", teste[i][j]); } printf("\n"); }
-
11 minutos atrás, arfneto disse:
antes de tudo escreva o programa para mostrar a matriz e entenda como endereçar os elementos nessa sub-matriz. Esqueça esse lance de construir a matriz na memória. Faça uma coisa por vez.
Pense no simples. Esta provavelmente superestimando o problema
int teste[5][5] = { { 2,4,6,8,10 }, { 2,4,6,8,10 }, { 2,4,6,8,10 }, { 2,4,6,8,10 }, { 2,4,6,8,10 } };
Isso por exemplo cria e preenche uma matriz e você pode escrever o resto com isso. Escreva a partir dos dados. Só isso
beleza.
E se eu quiser pegar os elementos em um intervalo (x,y), devo criar uma matriz (ex: int teste2[lin][col])?
-
@arfneto Bom, primeiramente, desculpe por não dizer a minha dúvida.
Estava com muitas dificuldades: por exemplo, no 2º item, queria atribuir um valor inteiro em cada elemento da sub-matriz (x1,y1,x2,y2). E também no 3º item (criar a função 'print_matrix_metrics'), que é para somar todos os elementos de uma submatriz (x1,y1,x2,y2) e, depois, imprimir o somatório, o menor e o maoir elemento da sub-matriz.
14 minutos atrás, arfneto disse:mas qual a sua dúvida afinal?
- porque tentou escrever o programa todo antes de resolver um desses itens, já que são todos iguais
- porque usar calloc() se vai atribuir valores à matriz toda?
-
porque usar alocação dinâmica da matriz se o enunciado só mostra uma simples matriz 5x5 e nem fala em ler a matriz, apenas em operar com ela?
matriz = (int**) calloc (numLinha, sizeof(int)); for (int i=0; i<numLinha; i++){ matriz = (int**) calloc (numColuna, sizeof(int)); }
- que pretende nas linhas acima? Como quer construir a area para a matriz? C não tem vetores de mais de uma dimensão, então pode usar o simples e usar linha a linha. Assim como fez não vai funcionar...
- copiar um loop para mostrar a matriz para todas as funções pode fazer você se sentir melhor ao ler o programa com as funções todas, mas é ilusão. Faça o simples e use uma matriz com valores inicias e escreva as funções uma a uma. De verdade. E deixe uma função para claro mostrar a matriz, funcionando antes de tudo.
Bom, tentei fazer este item, seguindo da forma que em ED1 pede.
Sobre colocar o calloc, ao invés do malloc, não sabia qual dos dois tipos de alocação colocar.
Sobre o 3º item que você colocou em cima, posso fazer dessa maneira?
matriz = malloc (numLinha * numColuna, sizeof(int));
Mas como é uma matriz, para isso, devo criar um novo elemento chamado "subMatriz" para inserir os elementos dentro da matriz?
Mas o problema é esse: como posso incrementar e atribuir os dados dentro do elemento "matriz" inicialmente declarado? -
Pessoal, estou com bastante dificuldade de resolver este exercício de ED1 (Janelas de Matrizes).
Ele pede para fazer os seguintes itens:
1.Incrementar um valor inteiro em cada elemento (x,y) da sub-matriz (x1,y1,x2,y2). Crie uma função chamada increment_matrix;
Ex:
2.Atribuir um valor inteiro em cada elemento (x,y) da sub-mâtriz (x1,y1,x2,y2). Crie uma função chamada set_value_into_matrix.
Ex:
3.Imprimir os vâlores do somâto rio, mínimo e máximo dos elementos sub-matriz (x1,y1,x2,y2). Crie uma função chamada "print_matrix_metrics".
Ex:
Preciso de muita ajuda de vcs!!
Para quem quer realizar os testes do código:
#include <stdio.h> #include <stdlib.h> /* Incrementar um valor inteiro em cada elemento (x,y) da sub-matriz (x1,y1,x2,y2). Crie uma função chamada increment_matrix; */ void incrementMatrix(int matriz, int x1, int y1, int x2, int y2, int valor){ for (int i=x1; i<=x2; i++){ for (int j=y1; j<=y2; j++){ printf(" %d ", valor); } printf("\n"); } printf("\n"); } /* Atribuir um valor inteiro em cada elemento (x,y) da sub-matriz (x1,y1,x2,y2). Crie uma funçao chamada set_value_into_matrix. */ void setValueIntoMatrix(int matriz, int x1, int y1, int x2, int y2, int valor){ int novoValor = 0; for (int i=x1; i<=x2; i++){ for (int j=y1; j<=y2; j++){ novoValor = novoValor + valor; printf(" %d ", novoValor); } printf("\n"); } printf("\n"); } /* Imprimir os vâlores do somatorio, mínimo e maximo dos elementos sub-mâtriz (x1,y1,x2,y2). Crie uma funçao chamada print_matrix_metrics */ void printMatrixMetrics(int **matriz, int x1, int y1, int x2, int y2){ int somatorio = 0; int maximo = 0, minimo = 0; for (int i=x1; i<=x2; i++){ for (int j=y1; j<=y2; j++){ if (minimo < matriz[i][j]){ minimo = matriz[i][j]; } if (maximo > matriz[i][j]){ maximo = matriz[i][j]; } somatorio = somatorio + matriz[i][j]; } } printf("%d %d %d", somatorio, minimo, maximo); } int main(){ int numLinha, numColuna, numOperacoes; scanf("%d %d %d", &numLinha, &numColuna, &numOperacoes); int **matriz; matriz = (int**) calloc (numLinha, sizeof(int)); for (int i=0; i<numLinha; i++){ matriz = (int**) calloc (numColuna, sizeof(int)); } for (int i=0; i<numOperacoes; i++){ int tipoOperacao; int x1, y1, x2, y2; int valor; scanf("%d %d %d %d %d", &tipoOperacao, &x1, &y1, &x2, &y2); if (tipoOperacao == 1){ scanf("%d", &valor); incrementMatrix(matriz, x1, y1, x2, y2, valor); } else if (tipoOperacao == 2){ scanf("%d", &valor); setValueIntoMatrix(matriz, x1, y1, x2, y2, valor); } else { printMatrixMetrics(**matriz, x1, y1, x2, y2); } } free(matriz); return 0; }
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
Como posso ordenar uma lista encadeada simples pelo serial do produto?
em C/C#/C++
Postado
Então nesta linha aqui:
Devo escrever nest maneira?
===================================================================
Não havia entendido esta parte, porque ao ler o codigo que você escreveu, eu fiquei me perguntando sobre isso.
===================================================================
Como assim escrever em torno dos dados?
===================================================================
Aqui, não aconteceu nada ://
Estou tentando, agora, fazer de outra forma:
Pensei agr em colocar um [switch...case] para isso. Mas, ao mesmo tempo, estou colocando as funções que você escreveu
E, claro, as modificações feitas no código. Só que vou precisar de um tempo para pensar em como aplicá-lo.