0

I am trying to create a program to solve the classic problem of brackets balancing. The program needs to tell the user if an the parantheses appearing in an expression are balanced.

I am very new to C/C++, coming from Python, so please excuse my ignorance and please point me towards the right direction!

What I have up until now is below. When compiled with gcc -o exec program.c then ./exec it outputs: List is: ) ( ] [ } { , rather than what I would expect: List is: { } [ ] ( )

I do not understand why, is there an obvious mistake? I keep searching for it...

Also, I would be very grateful if you could comment if my logic on how I am designing those functions makes sense and is correct: I feel I actually need to put those pointer variables as arguments to the functions?

Thank you!

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

// Parantheses check:

struct Node {
    char data;
    struct Node* next;
};

struct Node* head_of_listofparans = NULL;
struct Node* head_of_listofparans_open = NULL;
struct Node* head_of_listofparans_close = NULL;


struct Node* insert_at_beginning(char c, struct Node* head) {
    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    temp->data = c;
    temp->next = head;
    head = temp;
    return head;
}


void Delete(int n, struct Node* head) { // removes the n-th node (n=1 represents the head node, n=2 represents the second node)
    struct Node* temp1 = head;
    
    if (n==1) {
        head = temp1->next;
        free(temp1);
        return;
    }

    int i;
    for (i=0; i<n-2; i++) { // if n=2 (want to delete the 2nd node), this for-loop doesn't get executed.
        temp1 = temp1->next;
    } // temp1 now points to the n-1 th node. if n=2, temp1 still (correctly) points towards the head (first node)
    struct Node* temp2 = temp1->next; // temp2 points towards the n-th node
    temp1->next = temp2->next; // n-1 th node now points to the n+1 th node
    free(temp2); // delete the n-th node
}


struct Node* createListOfParantheses(char* parants, struct Node* initial_head) {
    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    temp->data = parants[0];
    temp->next = initial_head;
    initial_head = temp; // 1st node created. the link of this node points to NULL now. head of the list points to this newly created 1st node.

    int i;
    for (i=1; i<=(int)strlen(parants); i++) {
        initial_head = insert_at_beginning(parants[i], initial_head);    
    }
return initial_head;
}

// int ParanthesisCheck(char* parantheses_open, char* parantheses_close, char* expr) {
//     int n = int(strlen(expr));
//     int i;
//     for (i=0; i<=n-1; i++) {
//         if (strchr(parantheses_open, expr[i])!=NULL) { // if expr[i] can be found in "{[("
//             insert_at_beginning(expr[i]) // ppush(expr[i]);
//         }
//         else if (strchr(parantheses_close, expr[i])!=NULL) { // if expr[i] can be found in "}])"
//             if ((check_emptiness_of_stack()==1) || (get_top_of_stack() != expr[i])) { // || signifies the logical OR
//                 return 0;
//             }
//             else {
//                 Delete(1, head_of_stack); // ppop(), delete the very first node (head node), i.e. the most-recently-introduced node
//             }
//         }
//     }
//     return check_emptiness_of_stack()==1 ? 1:0;
// }

void Print_List_Of_Parans(struct Node* head) {
    struct Node* temp = head;
    printf("List is: ");
    while (temp != NULL) { 
        printf(" %c", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

int main() {
    char paras[7] = "{}[]()";
    char paras_open[4] = "{[(";
    char paras_close[4] = "}])";
    char input_expr[20] = "(a+b)";
    // int j;
    // for (j=0; j<7; j++) {
    //     scanf("%c", &paras[j]); // &paras[j] is equivalent to: paras + j if paras is an array
    //     printf("%s %d\n", "Iteration number: ", j);
    // } // doesn't work because scanf reads 1 character, alright, but adds a \n at its end, so consumes 2 memory locations from the array char paras[7], not 1 as expected.
    
    head_of_listofparans = createListOfParantheses(paras, head_of_listofparans);   

    head_of_listofparans_open = createListOfParantheses(paras_open, head_of_listofparans_open);

    head_of_listofparans_close = createListOfParantheses(paras_close, head_of_listofparans_close);


    Print_List_Of_Parans(head_of_listofparans);

    // int result = ParanthesisCheck(head_of_listofparans_open, head_of_listofparans_close, input_expr);
    // printf("%d\n", result);
return 0;
}
velenos14
  • 534
  • 4
  • 13
  • 3
    Aside: for the new to C, avoid the `ptr = (cast) malloc(n * sizeof some_type);` idiom. Instead `ptr = malloc(sizeof ptr[0] * n);`. – chux - Reinstate Monica Jan 07 '22 at 19:06
  • 1
    `Delete()` doesn't work for removing the head of the list. Assigning to the local `head` variable doesn't change the caller's variable. In C++ you would use a reference variable, but C doesn't have references. – Barmar Jan 07 '22 at 19:10
  • 1
    See https://stackoverflow.com/questions/13431108/changing-address-contained-by-pointer-using-function for how to do the equivalent in C. – Barmar Jan 07 '22 at 19:11
  • 1
    You can also just have `Delete()` return the head of the updated list, similar to the way `insert_at_beginning()` works. – Barmar Jan 07 '22 at 19:15
  • 1
    You're inserting each character at the front of the list. So the list is in reverse order, that's why you get that output. – Barmar Jan 07 '22 at 19:17
  • Oh my god, thank you, Barmar! I also thank you two both for all the other comments and indications, I will study and learn from them. @Barmar, please post as an answer (even if I don't know it will benefit someone else, you know it the best). Your help is very much appreciated! – velenos14 Jan 07 '22 at 19:19

0 Answers0