Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
4.2 kB
1
Indexable
Never
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "poly.h"

#define PRINT		0	/* enable/disable prints. */

#if PRINT
#define pr(...) do {fprintf(stderr, __VA_ARGS__);} while (0)
#else
#define pr(...)		/* no effect at all */
#endif

struct term_t
{
    int coeff;
    int exp;
    struct term_t *next;
};

struct poly_t
{
    struct term_t *head;
};

poly_t *new_poly_from_string(const char *str)
{
    poly_t *poly = malloc(sizeof(poly_t));
    poly->head = NULL;

    const char *p = str;
    struct term_t *tail = NULL;
    int sign = 1;
    int coeff;
    while (*p != '\0')
    {
        pr("NU ÄR P %s\n", p);

        while (*p == ' ')
        {
            p++;
        }

        if (*p == '-')
        {
            sign = -1;
            p++;
            continue;
        }
        else if (*p == '+')
        {
            sign = 1;
            p++;
            continue;
        }
        if (*p == 'x')
        {
            coeff = 1;
        }
        else
        {
            coeff = 0;
            while (*p >= '0' && *p <= '9')
            {
                pr("This iteration p is: %s\n", p);
                coeff = coeff * 10 + (*p - '0');
                p++;
            }
            pr("Coefficient read: %d\n", coeff);
        }
        coeff *= sign;
        int exp = 0;
        if (*p == 'x')
        {
            p++;
            if (*p == '^')
            {
                p++;
                while (*p >= '0' && *p <= '9')
                {
                    exp = exp * 10 + (*p - '0');
                    p++;
                }
            }
            else
            {
                exp = 1;
            }
        }

        struct term_t *term = malloc(sizeof(struct term_t));
        term->coeff = coeff;
        term->exp = exp;
        term->next = NULL;
        pr("Term is coeff: %d, exp: %d\n", coeff, exp);

        if (tail == NULL)
        {
            poly->head = term;
            tail = term;
        }
        else
        {
            tail->next = term;
            tail = term;
        }
    }
    return poly;
}

void free_poly(poly_t *poly)
{
    struct term_t *term = poly->head;
    while (term != NULL)
    {
        struct term_t *next = term->next;
        free(term);
        term = next;
    }
    free(poly);
}

poly_t *mul(poly_t *p1, poly_t *p2)
{
    poly_t *result = malloc(sizeof(poly_t));
    result->head = NULL;

    for (struct term_t *t1 = p1->head; t1 != NULL; t1 = t1->next)
    {
        for (struct term_t *t2 = p2->head; t2 != NULL; t2 = t2->next)
        {
            int coeff = t1->coeff * t2->coeff;
            int exp = t1->exp + t2->exp;

            struct term_t *prev = NULL;
            struct term_t *term = result->head;
            while (term != NULL && term->exp > exp)
            {
                prev = term;
                term = term->next;
            }
            if (term != NULL && term->exp == exp)
            {
                term->coeff += coeff;
            }
            else
            {
                struct term_t *new_term = malloc(sizeof(struct term_t));
                new_term->coeff = coeff;
                new_term->exp = exp;
                new_term->next = term;
                if (prev == NULL)
                {
                    result->head = new_term;
                }
                else
                {
                    prev->next = new_term;
                }
            }
        }
    }

    return result;
}

void print_poly(poly_t *poly)
{
    for (struct term_t *term = poly->head; term != NULL; term = term->next)
    {
        if (term != poly->head)
        {
            if (term->coeff > 0)
            {
                printf(" + ");
            }
            else
            {
                printf(" - ");
            }
        }
        if (term->exp == 0)
        {
            printf("%d", abs(term->coeff));
        }
        else
        {
            if (abs(term->coeff) != 1)
            {
                printf("%d", abs(term->coeff));
            }
            printf("x");
            if (term->exp > 1)
            {
                printf("^%d", term->exp);
            }
        }
    }
    printf("\n");
}