חזור לתיקייה: גליון 4

hw4q1

חיפוש בתיקיה
Ctrl K
לחץ כאן או הקש Ctrl K כדי לחפש בכל התיקיה

    hw4q1

    02340114

    מבוא למדמח מ

    רשימות הרצאה לקריאה בשבת

    hw4q1

    הופק מתוך תקיית התואר של שקד

    uni-folder.vercel.app

    hw4q1.c

    הערה (קובץ קוד)

    קובץ זה הוא קובץ קוד מסוג C.

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define MAX_ARR_SIZE 50
    #define STARTING_LETTER 'a'
    #define NUMBER_OF_LETTERS ('z' - 'a' + 1)
    #define MIN(x, y) (x > y ? y : x)
    #define MAX(x, y) (x > y ? x : y)
    #define IS_SPACE(c) ((c == ' ') || (c == '\t') || (c == '\r'))
    
    int min_distance(char *arr[], int n);
    int getChangeLength(char *current, char *final);
    
    //initialization functions:
    void *allocate(int n)
    {
        char *str = (char *) malloc(n);
        if (str == NULL)
        {
            exit(1);
        }
        return str;
    }
    
    char *get_string()
    {
        char *str, *str_i;
        str_i = str = (char *) allocate(MAX_ARR_SIZE);
        while (1)
        {
            int f = scanf("%c", str_i);
            if (f == 0)
            {
                exit(1);
            }
            if (f == EOF || *(str_i) == '\n')
            {
                *str_i = '\0';
                return str;
            }
            str_i++;
        }
    }
    
    char **get_all_string(int n)
    {
        char **arr = (char **) allocate(n * sizeof(char *));
        for (int i = 0; i < n; i++)
        {
            arr[i] = get_string();
        }
        return arr;
    }
    
    void free_all_strings(char **arr, int n)
    {
        for (int i = 0; i < n; i++)
        {
            free(arr[i]);
        }
        free(arr);
    }
    
    
    int main()
    {
        int n;
        int r = scanf("%d ", &n);
        if (r == 0)
        {
            exit(1);
        }
        char **arr = get_all_string(n);
        printf("%s\n", arr[min_distance(arr, n)]);
        free_all_strings(arr, n);
    
        return 0;
    }
    
    
    // auxiliary functions for get_all_sub_strings:
    int count_num_of_one(int n)
    {
        int count = 0;
        while (n > 0)
        {
            count += n % 2;
            n = n / 2;
        }
        return count;
    }
    
    
    char *get_sub_string(char *str, int num_of_ones, int mask)
    {
        char *sub_str, *sub_str_i;
        sub_str_i = sub_str = (char *) allocate(num_of_ones + 1);
        while (*str)
        {
            if (mask % 2)
            {
                *sub_str_i = *str;
                sub_str_i++;
            }
            mask = mask / 2;
            str++;
        }
        *sub_str_i = 0;
        return sub_str;
    }
    
    int pow_of_2(int n)
    {
        int p = 1;
        while (n-- > 0)
        {
            p *= 2;
        }
        return p;
    }
    
    
    char **get_all_sub_strings(char *str, int n)
    {
        int amount_of_sub_strings = pow_of_2(n);
        char **arr = (char **) allocate(amount_of_sub_strings * sizeof(char *));
        for (int i = 0; i < amount_of_sub_strings; i++)
        {
            arr[i] = get_sub_string(str, count_num_of_one(i), i);
        }
        return arr;
    }
    
    int getLength(const char *word)
    {
        int length = 0;
    
        while (*word != '\0')
        {
            length++;
            word++;
        }
    
        return length;
    }
    
    int isInWord(const char c, const char *word)
    {
        for (int i = 0; *word != '\0'; i++)
        {
            if (*word == c)
            {
                return i;
            }
            word++;
        }
    
        return -1;
    }
    
    bool areEqual(const char *wordA, const char *wordB)
    {
        while (*wordA != '\0' && *wordB != '\0')
        {
            if (*wordA != *wordB)
            {
                return false;
            }
            wordA++;
            wordB++;
        }
        if (*wordA != '\0' || *wordB != '\0')
        {
            return false;
        }
    
        return true;
    }
    
    int getDistance(char *wordA, char *wordB)
    {
        if (*wordB == '\0' || areEqual(wordA, wordB))
        {
            return 0;
        }
        if (*wordA == '\0')
        {
            return getLength(wordB);
        }
    
        // is *wordA in wordB
        const int location = isInWord(*wordA, wordB);
        if (location != -1)
        {
            const int keepLetter = location + getDistance(
                wordA + 1, wordB + location + 1
            );
            const int dump = getDistance(wordA + 1,wordB) + 1;
            return MIN(keepLetter, dump);
        }
    
        return getDistance(wordA + 1,wordB) + 1;
    }
    
    void copyString(char *original, int start, int end, char *out)
    {
        for (int i = 0; i < (end - start); i++)
        {
            out[i] = original[start + i];
        }
    }
    
    void addWord(char **words, char *sentence,
        const int lastSpace, const int i, int *n)
    {
        words[*n] = (char *)malloc(sizeof(char) * (i - lastSpace + 1));
        copyString(sentence, lastSpace, i, words[*n]);
        words[*n][i - lastSpace] = '\0';
        (*n)++;
    }
    
    char **divideSentenceToWords(char *sentence, int *n)
    {
        char **words = malloc(sizeof(char *) * getLength(sentence));
        int lastSpace = 0, i = 0;
        bool spaceBefore = false;
        (*n) = 0;
    
        for (; sentence[i] != '\0'; i++)
        {
            if (IS_SPACE(sentence[i]))
            {
                if (!spaceBefore)
                {
                    addWord(words, sentence, lastSpace, i, n);
                }
                spaceBefore = true;
                lastSpace = i + 1;
            }
            else
            {
                spaceBefore = false;
            }
        }
        if (!spaceBefore)
        {
            addWord(words, sentence, lastSpace, i, n);
        }
    
        return words;
    }
    
    int getSentenceMaxDistance(char *sentence)
    {
        int numOfWords = 0, maxDist = 0;
        char **words = divideSentenceToWords(sentence, &numOfWords);
        if (words == NULL)
        {
            return -1;
        }
    
        for (int i = 0; i < numOfWords; i++)
        {
            for (int j = 0; j < numOfWords; j++) // j = i+1 would work?
            {
                if (i != j)
                {
                    const int dist = getDistance(words[i], words[j]);
                    maxDist = MAX(maxDist, dist);
                }
            }
        }
    
        free_all_strings(words, numOfWords);
        return maxDist;
    }
    
    int getMinArray(int arr[], const int length)
    {
        int min = arr[0], minIndex = 0;
    
        for (int i = 1; i < length; i++)
        {
            if (min > arr[i])
            {
                min = arr[i];
                minIndex = i;
            }
        }
    
        return minIndex;
    }
    
    int min_distance(char *arr[], int n)
    {
        int values[MAX_ARR_SIZE] = {0};
    
        for (int i = 0; i < n; i++)
        {
            values[i] = getSentenceMaxDistance(arr[i]);
        }
    
        return getMinArray(values, n);
    }