Find character occurrences using a linked list in C

Viewed 119

My program as shown below does not count characters properly. I also want the matching characters to be shown only once.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct charact
{
    char ch;
    int occurs;
    struct charact *next;
};
typedef struct charact Char;
typedef Char * ListofChar;
typedef Char * CharNode_ptr;
void letters(char name[50], ListofChar * chars_ptr);
void report(ListofChar chars);
Char * createnode(char ch);
int main(void)
{
    size_t i;
    char name[50]= {0};
    ListofChar chars = NULL;
    scanf("%49s", name);

    for(i=0; i<strlen(name); i++)
    {
        letters(name, &chars);
        report(chars);
    }

    return 0;
}
Char * createnode(char ch)
{
    CharNode_ptr newnode_ptr ;
    newnode_ptr = malloc(sizeof (Char));
    newnode_ptr -> ch = ch;
    newnode_ptr -> occurs;
    newnode_ptr -> next = NULL;
    return newnode_ptr;
}

The above is the function to search the list. I think that the problem is in this function.

void letters(char name[50], ListofChar * lst_ptr)
{
    size_t i,k;
    static int j=0;
    ListofChar temp_ptr= *lst_ptr;

    temp_ptr=malloc(sizeof(temp_ptr));

    *lst_ptr=createnode(name[j]);

    for(i=1; i<strlen(name); i++)
    {
        temp_ptr->next= createnode(name[i]);
        temp_ptr=temp_ptr->next;
    }

    for(k=1; k<=i; k++)
    {

        if(createnode(name[i])==createnode(name[k]))
        {
            temp_ptr->occurs++;
        }
    }

    j++;

    return  ;
}

This is the function to print the output

void report(ListofChar chars)
{

    ListofChar temp = chars;

    temp = malloc(sizeof(chars));

    if(temp == NULL)
    {
        printf("Empty list\n");
        return ;
    }

    for(temp = chars; temp!= NULL; temp = temp->next)
    {

        printf("%c: %d\n", temp->ch, temp->occurs);

    }

    return ;
}

My current output is :

hello

h:0

e:0

l:0

l:0

o:0

This is the wanted output :

example 1 :

hello

h:1

e:1

l:2

o:1

example 2 :

array

a:2

r:2

y:1

1 Answers

The major problem is indeed in the function letters, which blindly allocates a new node for each character without checking whether it is already in the list. Here's a corrected version:

void letters(char name[50], ListofChar *lst_ptr)
{
    for (ListofChar *chars_ptr = lst_ptr, temp_ptr; *name; ++name)
    {   // search list for character; if found, occurs one more
        for (lst_ptr = chars_ptr; temp_ptr = *lst_ptr; lst_ptr = &temp_ptr->next)
            if (temp_ptr->ch == *name) { ++temp_ptr->occurs; break; }
        if (!temp_ptr) *lst_ptr = createnode(*name);    // not found
    }
}

Besides that, createnode must initialize occurs to 1, and main should drop the loop.

Related