C语言课设,一元稀疏多项式计算(链式储存+文件读取输入+文件存储)

这个博客介绍了一个使用C语言实现的多项式计算程序。程序包括多项式的创建、更新、插入、删除零项、加减乘运算以及升序和降序输出。用户可以输入系数和指数创建多项式,也可以从文件读取数据。计算完成后,用户可以选择不同的输出方式,如保存到文件或按特定顺序显示结果。
摘要由CSDN通过智能技术生成

学校C语言课设

Calculate.h

#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node* LIST;

struct Date//每个数字的系数和指数
{
    int c;//系数
    int n;//指数
};

struct node
{
    Date Val;
    LIST NEXT;
};

LIST UpDate(LIST Head)
{
    LIST Node = Head;
    while (Node != NULL)
    {
        if (Node->Val.c == 0)
        {
            if (Node == Head)
            {
                Head = Head->NEXT;
                free(Node);
                Node = Head;
            }
            else
            {
                LIST next = Node->NEXT;
                free(Node);
                Node = next;
            }
        }
        else
        {
            Node = Node->NEXT;
        }
    }
    return Head;
}

void Insert(int c, int n,LIST* head)
{
    LIST Node = *head;
    //找尾巴
    LIST BefNode = NULL;
    while (Node != NULL)
    {
        if (Node->Val.n == n)//合并同类项
        {
            Node->Val.c += c;
            break;
        }
        BefNode = Node;
        Node = Node->NEXT;
    }
    if (Node == NULL)//没有找到同类项
    {
        Node = (LIST)malloc(sizeof(struct node));
        Node->Val.c = c;
        Node->Val.n = n;
        Node->NEXT = NULL;
        if (BefNode != NULL)
        {
            BefNode->NEXT = Node;
        }
        else
        {
            *head = Node;
        }
    }
}

LIST UserInit()
{
    printf("输入系数和指数,以0 0结束\n");
    //输入系数和指数
    LIST head = NULL;
    int n, c;
    while (1)
    {
        scanf("%d%d", &c, &n);
        if (c == 0 && n == 0)
        {
            break;
        }
        else
        {
            Insert(c, n, &head);
        }
    }

    return UpDate(head);//去除链表中的0
}

void output(LIST head,FILE*fp)
{
    if (head == NULL)
    {
        fprintf(fp,"\n");
        return;
    }
    LIST P = head;
    if (!P) return;
    //输出第一个
    if (P->Val.c < 0)
        fprintf(fp,"-");
    if (P->Val.n == 0)
        fprintf(fp,"%d", abs(P->Val.c));
    else if (abs(P->Val.c) == 1)//判断系数
    {
        if (P->Val.n == 1)
            fprintf(fp,"x");
        else
            fprintf(fp,"x^%d", P->Val.n);
    }
    else
    {
        if (P->Val.n == 1)
            fprintf(fp,"%dx", abs(P->Val.c));
        else
            fprintf(fp,"%dx^%d", abs(P->Val.c), P->Val.n);
    }
    P = P->NEXT;
    //继续输出
    while (P)
    {
        if (P->Val.n == 0)
            fprintf(fp,"%c%d", P->Val.c > 0 ? '+' : '-', abs(P->Val.c));
        else if (abs(P->Val.c) == 1)
        {
            if (P->Val.n == 1)
                fprintf(fp,"%cx", P->Val.c > 0 ? '+' : '-');
            else
                fprintf(fp,"%cx^%d", P->Val.c > 0 ? '+' : '-', P->Val.n);
        }
        else
        {
            if (P->Val.n == 1)
                fprintf(fp,"%c%dx", P->Val.c > 0 ? '+' : '-', abs(P->Val.c));
            else
                fprintf(fp,"%c%dx^%d", P->Val.c > 0 ? '+' : '-', abs(P->Val.c), P->Val.n);
        }
        P = P->NEXT;
    }
    fprintf(fp,"\n");
}

LIST sub(LIST A, LIST B)
{
    LIST NodeB = B;
    LIST NodeA = A;
    LIST RET = NULL;
    while (NodeA != NULL)
    {
        Insert(NodeA->Val.c, NodeA->Val.n, &RET);
        NodeA = NodeA->NEXT;
    }
    while (NodeB != NULL)
    {
        Insert(-(NodeB->Val.c), NodeB->Val.n, &RET);
        NodeB = NodeB->NEXT;
    }
    return RET;
}

LIST add(LIST A, LIST B)
{
    LIST NodeB = B;
    LIST NodeA = A;
    LIST RET = NULL;
    while (NodeA != NULL)
    {
        Insert(NodeA->Val.c, NodeA->Val.n, &RET);
        NodeA = NodeA->NEXT;
    }
    while (NodeB != NULL)
    {
        Insert((NodeB->Val.c), NodeB->Val.n, &RET);
        NodeB = NodeB->NEXT;
    }
    return RET;
}

LIST mul(LIST A, LIST B)
{
    if (A == NULL || B == NULL)
    {
        return NULL;
    }
    else
    {
        LIST NodeB = B;
        LIST NodeA = A;
        LIST RET = NULL;
        while (NodeA != NULL)
        {
            while (NodeB != NULL)
            {
                Insert((NodeA->Val.c) * (NodeB->Val.c), (NodeA->Val.n) + (NodeB->Val.n), &RET);
                NodeB = NodeB->NEXT;
            }
            NodeA = NodeA->NEXT;
            NodeB = B;
        }
        return RET;
    }
}

void SortRET(LIST* RET,int flag)
{
    Date Array[30] = { 0 };//最大30项
    LIST Node = *RET;
    int Pos = 0;
    while (Node != NULL)
    {
        if (Pos >= 30)
        {
            printf("项数太大\n");
        }
        Array[Pos] = Node->Val;
        Pos++;
        Node = Node->NEXT;
    }
    if (flag == 1)//升序排序
    {
       for(int i=0;i<Pos;i++)
       {
           for (int j = 0; j < Pos - i - 1; j++)
           {
               if (Array[j].n > Array[j + 1].n)
               {
                   Date tmp = Array[j];
                   Array[j] = Array[j + 1];
                   Array[j + 1] = tmp;
               }
           }
       }
    }
    else
    {
        for (int i = 0; i < Pos; i++)
        {
            for (int j = 0; j < Pos - i - 1; j++)
            {
                if (Array[j].n < Array[j + 1].n)
                {
                    Date tmp = Array[j];
                    Array[j] = Array[j + 1];
                    Array[j + 1] = tmp;
                }
            }
        }
    }
    Node = *RET;
    for (int i = 0; i < Pos; i++)
    {
        Node->Val.c = Array[i].c;
        Node->Val.n = Array[i].n;
        Node = Node->NEXT;
    }
}

void Show(LIST*RET)
{
    while (1) {
        int flag;
        printf("请问你想升幂输出还是降幂输出-> \n\t1:升幂;\n\t2:降幂;\n\t3:all;\n\t4:升幂排列保存到文件中\n\t5:return\n");
        scanf("%d", &flag);
        switch (flag)
        {
        case 1:
            SortRET(RET,flag);
            break;
        case 2:
            SortRET(RET, flag);
            break;
        case 3:
            SortRET(RET, 1);
            output(*RET,stdout);
            SortRET(RET, 2);
            break;
        case 4:
        {
            SortRET(RET, 1);
            FILE* fp = fopen("RET.txt", "a");
            output(*RET, fp);
            printf("保存文件成功\n");
            break;
        }
        case 5:
            return;
        default:
            printf("输出错误\n");
            break;
        }
        output(*RET,stdout);
    }
}

void CalCul(LIST A,LIST B,LIST RET)//初始化
{
    if (A == NULL && B == NULL)
    {
        printf("都为空多项式,无法计算\n");
        return;
    }
    printf("A = "); output(A,stdout);
    printf("B = "); output(B,stdout);
    while (1) {
        int flag;
        printf("请选择操作命令-> \n \t1:加法;\n\t2:A - B;\n\t3:B - A;\n\t4:乘法;\n\t5:return\n");
        scanf("%d", &flag);
        switch (flag) {
        case 1:
            RET = UpDate(add(A, B));
            break;
        case 2:
            RET=UpDate(sub(A, B));
            break;
        case 3:
            RET = UpDate(sub(B, A));
            break;
        case 4:
            RET = UpDate(mul(A, B));
            break;
        case 5:
            return;
        default:
            printf("输入错误\n");
            break;
        }
        Show(&RET);
    }
}

void FushDate(char(*c)[10], int flag, LIST* A, LIST* B)
{
    int cNum = atoi(c[0]);
    int nNum = atoi(c[1]);
    if (flag == 0)
    {
        Insert(cNum, nNum, A);
    }
    else
    {
        Insert(cNum, nNum, B);
    }
}

void ReadFile(FILE* fp, LIST* A, LIST* B)
{
    char buff[300] = { 0 };
    int size=fread(buff, sizeof(char), sizeof(buff), fp);//数据读取到缓冲区中
    if (size > 300)
    {
        printf("缓冲区溢出\n");
        return;
    }
    int flag = 0;
    char c[2][10] = { 0 };
    int Chsize = 0;
    int Type = 0;//区分系数还是指数
    for (int i = 0;buff[i]!='\0'; i++)
    {
        if (buff[i] == '\n')
        {
            Type = 0;
            FushDate(c, flag, A, B);
            Chsize = 0;
            flag = 1;
            continue;
        }
        if (buff[i] >= '0' && buff[i] <= '9')
        {
            c[Type][Chsize] = buff[i];
            c[Type][Chsize + 1] = 0;
            Chsize++;
        }
        else if (buff[i] == '-')
        {
            if (i > 0 && buff[i - 1] >= '0' && buff[i - 1] <= '9')
            {
                Type = 0;
                FushDate(c, flag, A, B);
                Chsize = 0;
            }
            c[Type][Chsize] = '-';
            Chsize += 1;
        }
        else if (buff[i] == 'x')//找系数
        {
            if (Chsize == 0)
            {
                //系数为1
                c[Type][Chsize] = '1';
                c[Type][Chsize + 1] = 0;
                Chsize++;
            }
            if (buff[i - 1] == '-' || buff[i - 1] == '+')
            {
                c[Type][Chsize] = '1';
                Chsize += 1;
            }
        }
        else if (buff[i] == '^')//找指数
        {
            Type = 1;
            Chsize = 0;
        }
        else//'+'
        {
            if (i>0&&buff[i - 1] >= '0' && buff[i - 1] <= '9')
            {
                Type = 0;
                FushDate(c, flag, A, B);
                Chsize = 0;
            }
        }
    }
}

Calculate.cpp

#include"Calculator.h"

int main()
{
    int choce = 0;
    printf("是否从文件中读取要计算的数据? 1.是 0.否\n");
    LIST A = NULL; LIST B = NULL; LIST RET = NULL;
    scanf("%d", &choce);
    if (choce == 0)
    {
        A=UserInit();
        B=UserInit();
    }
    else
    {
        printf("输入文件名\n");
        char FileName[32] = { 0 };
        scanf("%s", FileName);
        FILE* fp = fopen(FileName,"r");
        if (fp == NULL)
        {
            printf("文件打开失败\n");
        }
        ReadFile(fp, &A, &B);
        fclose(fp);
    }
    CalCul(A, B,RET);
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NUC_Dodamce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值