A lot of your compilation mistakes is that now you use Pilha
and now uses Pilha *
. Always use Pilha *
.
See its function of creating batteries:
Pilha create() {
Pilha p;
p->topo = -1;
p->elementos[MAX];
}
The use of ->
serves to access pointers, then p
should be a pointer. Also, you should return a pointer (as said in item 1). If p
is not a pointer, it will be allocated to the stack and out of focus when the function is finished, so you have to allocate it to the heap with malloc
. You should do it then:
Pilha *create() {
Pilha *p = (Pilha *) malloc(sizeof(Pilha));
p->topo = -1;
p->elementos[MAX];
return p;
}
However, this p->elementos[MAX];
does nothing. What you wanted in your place was this:
for (int i = 0; i < MAX; i++) {
p->elementos[i] = 0;
}
Its function push
is void
, but she has a return 0;
and a return 1;
inside. Let’s make return int
.
In his job push
we have it:
char p->elementos[p->topo] = c;
That one char
in front of you is no use. Remove it.
With the above changes in the file lisp.c
, these lines:
Pilha lisp = create();
push(&lisp, Fr[i]);
pop(&lisp);
They get like this:
Pilha *lisp = create();
push(lisp, Fr[i]);
pop(lisp);
With these changes, your code should already compile. But still there are other errors:
See its function size
:
int size(Pilha p) {
int tam;
tam = p->topo; + 1;
return tam;
}
About the *
before the p
, I told you before. But look at the line tam = p->topo; + 1;
- there is an extra semicolon there! Also, you don’t need this variable if you will already return immediately. So you can simplify it all like this:
int size(Pilha *p) {
return p->topo + 1;
}
Let’s see your function isEmpty
:
int isEmpty(Pilha p){
if (p->topo == -1)
return 1;
else
return 0;
}
The result of a comparison with ==
is always 1 when it is true and 0 when it is not. Therefore, if the result of the comparison is 1, it must return 1, if it is 0, it must return 0. Therefore, it is simpler to just return the result of the comparison directly:
int isEmpty(Pilha *p) {
return p->topo == -1;
}
The same can be done in your job isFull
.
If you have a if
that always ends with a return
, the else
is unnecessary. For example:
if (condição) {
return alguma_coisa;
} else {
blablabla
}
Is equivalent to that:
if (condição) {
return alguma_coisa;
}
blablabla
With that in mind, you can simplify your function push
by eliminating the else
hers.
The case of the variable charlvl
is curious. This is an array of 10 positions, but you only use position 1. Therefore, it is better to declare this as a char
. Besides, there is a printf
where you print charlvl[1]
using %s
. You should use %c
. Also, unless the list empties before it reaches the position of the sought character, we will have to charlvl[1]
will be Fr[idx - 1]
. Therefore, it is better to change this variable to the type char
and assign Fr[idx - 1]
to her before the for
.
You keep decreasing the idx
until when it is 1, you perform the lvl = size(lisp);
. The idx
will have value 1 only when i == lvl - 1
. So it’s easier for you to put that condition on if
, do not change the variable lvl
never and get rid of else
.
You ask to check characters at a certain level. In fact, what you look at is at a certain position in the sentence. Accordingly, the corresponding message in printf
shall be amended. The variable idx
is the position of the character in the sentence.
A very important thing in programming is to give suitable names to variables. Especially if you are in college, why sometimes some teachers pick up and even take a point if the program has variables with inappropriate or non-standard names. So I suggest you rename Fr
for frase
, QtCar
for quantidade
, idx
for posicao
, lvl
for nivel
and charlvl
for procurado
.
The printf("A lista nao esta balanceada");
within the for
of main
should not be there. It already says whether or not the list is balanced at the end. However, the idea here is to stop the whole analysis. Then an auxiliary variable that indicates whether or not the analysis was aborted at this point is necessary.
You don’t need stdio.h
inside pilha.c
nor pilha.h
. And you don’t need stdlib.h
inside lisp.c
.
This is what your programme looks like:
pilha.h
:
#ifndef PILHA_H_
#define PILHA_H_
#define MAX 100
typedef struct pilha {
char elementos[MAX];
int topo;
} Pilha;
Pilha *create(); //cria pilha
char pop(Pilha *p); //desempilha
int push(Pilha *p, char c); //empilha
int isEmpty(Pilha *p); //verifica pilha vazia
int isFull(Pilha *p); //verifica pilha cheia
int size(Pilha *p); //verifica tamanho da pilha
#endif
pilha.c
:
#include "pilha.h"
#include <stdlib.h>
Pilha *create() {
Pilha *p = (Pilha *) malloc(sizeof(Pilha));
p->topo = -1;
for (int i = 0; i < MAX; i++) {
p->elementos[i] = 0;
}
return p;
}
int isFull(Pilha *p) {
return p->topo == MAX - 1;
}
char pop(Pilha *p) {
char c = p->elementos[p->topo];
p->topo--;
return c;
}
int push(Pilha *p, char c) {
if (isFull(p)) {
return 0;
}
p->topo++;
p->elementos[p->topo] = c;
return 1;
}
int isEmpty(Pilha *p) {
return p->topo == -1;
}
int size(Pilha *p) {
return p->topo + 1;
}
lisp.c
:
#include <stdio.h>
#include "pilha.h"
int main() {
int quantidade, posicao, nivel;
printf("Quantidade de caracteres:\n");
scanf("%d", &quantidade);
char frase[quantidade];
printf("Frase:\n");
scanf("%s", frase);
printf("Verificar caracter na posicao?\n");
scanf("%d", &posicao);
char procurado = frase[posicao - 1];
int abortado = 0;
Pilha *lisp = create();
for (int i = 0; i < quantidade; i++) {
if (frase[i] == '(') {
push(lisp, frase[i]);
}
if (frase[i] == ')') {
if (isEmpty(lisp)) {
abortado = 1;
break;
} else {
pop(lisp);
}
}
if (i == posicao - 1) {
nivel = size(lisp);
}
}
if (!abortado && isEmpty(lisp)) {
printf("A lista esta balanceada! %c está no nivel %d", procurado, nivel);
} else {
printf("A lista nao esta balanceada");
}
}
Your program should then work like this.
However, there is still a little secret: Once the only thing you stack are parentheses, so you can remove the stack and exchange it for a counter. This shows that this exercise does not actually need to use a stack to check if the parentheses are balanced and a simpler solution exists. This also means that your teacher should devise another battery exercise that cannot be solved without using them. Here’s what your program would look like without using batteries:
#include <stdio.h>
int main() {
int quantidade, posicao, nivel;
printf("Quantidade de caracteres:\n");
scanf("%d", &quantidade);
char frase[quantidade];
printf("Frase:\n");
scanf("%s", frase);
printf("Verificar caracter na posicao?\n");
scanf("%d", &posicao);
char procurado = frase[posicao - 1];
int abortado = 0;
int abertos = 0;
for (int i = 0; i < quantidade; i++) {
if (frase[i] == '(') {
abertos++;
}
if (frase[i] == ')') {
if (abertos == 0) {
abortado = 1;
break;
} else {
abertos--;
}
}
if (i == posicao - 1) {
nivel = abertos;
}
}
if (!abortado && abertos == 0) {
printf("A lista esta balanceada! %c está no nivel %d", procurado, nivel);
} else {
printf("A lista nao esta balanceada");
}
}
This question has two votes to close. One of these votes as "too wide" and the other as "is not clear enough". I disagree with these closing votes and voted for "leave open". Someone who is in favor of closing I would like to explain further?
– Victor Stafusa