0
#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 *create_node(char ch);

int main(void) {
    char name[50];
    ListofChar chars = NULL;

    scanf("%49s", name);
    letters(name, &chars);
    report(chars);

    return 0;
}

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

void letters(char name[50], ListofChar *lst_ptr) {
    int str_lenth = strlen(name);
    *lst_ptr = create_node(name[0]);
    CharNode_ptr current = *lst_ptr;

    for (int i = 1; i < str_lenth; i++) {
        
        CharNode_ptr new = create_node(name[i]);
        current->next = new;
        current = new;
        
    }
    
    return;
}

void report(ListofChar chars) {
    int apostasi = 0;
    int epanalipsi = 0;
    
    for (CharNode_ptr current = chars; current != NULL; current = current->next) {
        if (current->next != NULL && current->next->ch == current->ch) {
            apostasi++;
            epanalipsi = apostasi;
        } 
        else {
            apostasi = 0;
            epanalipsi = 0;
        }
        
        current->occurs = apostasi;
        printf("%c: %d\n", current->ch, current->occurs);
    }
}

I want to make a program that if a letter repeats it self after the first time then I get the distance between them if not then I get a 0.

It know works if the distance between the letter is only 1.

For example:

Input:hello
h:0
e:0
l:1
l:0
o:0

Which is correct.

But for input helol I get:

h:0
e:0
l:0
o:0
l:0

The correct would be:

h:0
e:0
l:2
o:0
l:0

How do I fix it by only messing with the letters and report functions?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    Why do you have two typedefs for `Char *`? In general, typedef for pointer is a bad idea, see https://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers – Barmar May 16 '23 at 17:40
  • 1
    You need a nested loop inside `report()`. Instead of just checking if `current->next->ch` is the same, you have to loop through all the following elements, counting the steps. – Barmar May 16 '23 at 17:42
  • What is the expected output for `helolxl`? – 001 May 16 '23 at 18:03
  • Why do you need the `charact` struct? You're not really using the `occurs` member and the data is already in an array. – 001 May 16 '23 at 18:09
  • 1
    You need to tell the computer what to do. First, figure out what to do, then tell the computer to do it. It looks like you don't know what you want the computer to do. – user253751 May 16 '23 at 18:13
  • I would simplify it and just you a 128 byte `char` array (initialized to all `-1`) as a where each index maps to an ASCII character and holds the index for the first occurrence of that letter in the string. In that case you can get the distance from the first simply by `if (array[current_char] >= 0) { array[current_char] = current_idx - array[current_char]; } else { array[current_char] = 0; }` You will have to decide what you do if there is a 3rd repetition. – David C. Rankin May 17 '23 at 04:34
  • What should `"heloooll"` be? `0,0,5,2,1,0,1,0`? – David C. Rankin May 17 '23 at 05:41

1 Answers1

0

You got a couple of problems. First of all, as @Barmar said, you are missing a second, internal loop, for scaning each "target" character after the current one. Also, you're defining but not using the epanalipsi variable. I think apostasi is supposed to be the distance between the "current" and the "target", while probing, and epanalipsi is supposed to have the same value when a match is found (ie. the result).

This works:

void report(ListofChar chars) {
    // Scan each node in the list
    for (CharNode_ptr current = chars; current != NULL; current = current->next) {
        int apostasi = 0;       // Distance from current to each target (aux variable)
        int epanalipsi = 0;     // The same distance, but only set when a match is found

        // Scan each node after "current", don't pass the end of the string.
        for (CharNode_ptr target = current->next; target != NULL; target = target->next) {
            apostasi++;
            printf("Comparing %c to %c, distance is %d\n", current->ch, target->ch, apostasi);

            // If a match is found, save the distance and exit the internal loop.
            // If a letter appears more than two times (ie. "helolxxxl"), stop at the first repeat.
            if (target->ch == current->ch) {
                epanalipsi = apostasi;
                break;
            }

        }

        current->occurs = epanalipsi;
        printf("%c: %d\n", current->ch, current->occurs);
    }
}

Anyway, I suggest you to always test your algorithm using a simpler version, like this one (using an array of char, and not a list of CharNode).

#include "stdio.h"

void report(char* chars) {
    // Scan each node in the list
    for (char* current = chars; *current != NULL; current++) {
        int apostasi = 0;       // Distance from current to each target (aux variable)
        int epanalipsi = 0;     // The same distance, but only set when a match is found

        // Scan each node after "current", don't pass the end of the string.
        for (char* target = current + 1; *target != NULL; target++) {
            apostasi++;
            printf ("Comparing %c to %c, distance is %d\n", *current, *target, apostasi);

            // If a match is found, save the distance and exit the internal loop.
            // If a letter appears more than two times (ie. "helolxxxl"), stop at the first repeat.
            if (*target == *current) {
                epanalipsi = apostasi;
                break;
            }
        }

        printf("%c: %d\n", *current, epanalipsi);
    }
}

int main() {
    report((char*) "hello");        // 00100
    report((char*) "helol");        // 00200
    report((char*) "helolxxxl");    // 002041100
    return 0;
}