Chinaunix首页 | 论坛 | 博客
  • 博客访问: 38029
  • 博文数量: 6
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 72
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-07 18:18
个人简介

享受生活,热爱自由,崇尚科学

文章分类
文章存档

2013年(6)

我的朋友

分类: C/C++

2013-05-24 08:53:12

//拙作不免有些bug,如果您发现了,请指正
#include
#include
#include
#include
/* 多项式运算  加减乘运算
*  输入说明如下:输入的每项 axb ,a为系数,b为次数,且a,b,均不超过三位数,包括负号不超过4位,也不要为了好看加入空格,加入之后程序可能崩溃!
*             若次数b为负数,在输入的时候,应加上阔号,输入的时候应尽可能按高次项,低次项的顺序输入            
*             以#号结束,例如 5x2+6x+5-x(-1)#
*
*           
*/
#define     M     50
#define     M1     550
typedef struct {
    float coe;        //系数
    int index;        //次数
} Node;                //节点结构类型
void initNode(Node * node)
{                //初始化节点
    node->coe = 0.0;
    node->index = 0;
}

typedef struct {
    Node data[M];        //节点数组
    int last;        //最后节点的下标
} Seqlist;            //存放项的结构类型
void initSeqlist(Seqlist * seqlist)
{
    int i;
    i = 0;
    for (; i < M; i++)
        initNode(&seqlist->data[i]);
    seqlist->last = -1;
}

int dxInput(Seqlist * seqlista)
{                //接受多项式输入,并存入数组中

    char str[M1];
    int i, j, v;
    int z, f, w;
    fgets(str, M1, stdin);
    //puts(str);
    i = 0;
    if (!(str[i] >= '0' && str[i] <= '9') && (str[i] != '-')
        && (str[i] != 'x')) {
        puts("输入非法字符!");
        return 0;
    }
    j = 0;            //多项式的第j+1项
    v = 0;
    z = f = 0;        //对于多项式中的每项,负值的标识 f负
    w = 0;
    for (i = 0; str[i] != '#'; i++) {
        if (str[i] == '-')    //检测第一个字符
        {
            f = 1;

        }
        if (str[i] == '+')
            z = 1;
        if (str[i] == 'x') {
            if (w != 1) {
                if (f == 1) {
                    seqlista->data[j].coe = -1;
                } else
                    seqlista->data[j].coe = 1;
            }
            i++;
            if (str[i] == 'x') {
                puts("输入有误!2");
                return 0;
            }
            goto n1;
        }
        if (str[i] >= '0' && str[i] <= '9') {
            for (; str[i] >= '0' && str[i] <= '9'; i++)
                v = v * 10 + str[i] - '0';

            if (f == 1)
                seqlista->data[j].coe = (-1) * v;
            else
                seqlista->data[j].coe = v;
            w = 1;
            if (str[i] == '+' || str[i] == '-'
                || str[i] == '#') {
                seqlista->data[j].index = 0;
                v = 0;
                z = f = 0;
                j++;
                w = 0;
                i--;
                continue;
            }
            i--;
        }
        if (str[++i] == '+' || str[i] == '-')    //容错
        {
            if (f || z) {
                puts("输入有误!1");
                return 0;
            }
        }
        --i;
        continue;
        //判断每项的第一个字符,并标记,若正z=1,若负f=1,
          n1:v = 0;    //往下处理次数,上面处理的是每项的系数
        if (str[i] == '+' || str[i] == '-' || str[i] == '#') {
            seqlista->data[j].index = 1;
            i--;
            j++;
            f = z = 0;
            w = 0;
            continue;
        }
        if (str[i] == '(') {
            i += 2;
            for (; str[i] >= '0' && str[i] <= '9'; i++)
                v = v * 10 + str[i] - '0';
            seqlista->data[j].index = (-1) * v;
            //i--;
            j++;
            v = 0;    //
            w = 0;
            f = 0;
            z = 0;
            continue;
        }
        for (; str[i] >= '0' && str[i] <= '9'; i++)
            v = v * 10 + str[i] - '0';
        seqlista->data[j].index = v;
        v = 0;
        z = f = 0;
        i--;
        j++;
        w = 0;
    }
    seqlista->last = --j;
    return 1;
}

int testXushu(Seqlist * a)
{                //测多项式中的项是否为从高次到低次输入,若是返回1,否则返回0
    int i = 1;
    for (; i <= a->last; i++)
        if (a->data[i].index > a->data[i - 1].index)
            return 0;
    return 1;
}

void quickSort(Node a[], int left, int right)    //快速排序法
{
    int middle = (left + right) / 2;
    int i, j, t1, t2, midvalue;
    i = left;
    j = right;
    midvalue = a[middle].index;
    while (i <= j) {
        while (a[i].index > midvalue && i < right)
            i++;
        while (a[j].index < midvalue && j > left)
            j--;
        if (i <= j) {
            t1 = a[i].coe;
            t2 = a[i].index;
            a[i].coe = a[j].coe;
            a[i].index = a[j].index;
            a[j].coe = t1;
            a[j].index = t2;
            i++;
            j--;
        }

        if (i > j && i < right)
            quickSort(a, i, right);
        if (i > j && j > left)
            quickSort(a, left, j);
    }
}

void kuaiPaiDuoXiang(Seqlist * adr)
{
    quickSort(adr->data, 0, adr->last);
}

void deleteFromDm(Seqlist * S, int n)    //从多项式存储结构中删除一项,接受被删项的(下标!!!)
{
    int i = n + 1;
    for (; i <= S->last; i++) {
        S->data[i - 1] = S->data[i];
    }
    S->last--;
}

void addToDm(Seqlist * S, int n, Node * data)    //在多项式存储结构中添加一项,接受添加的位置的(下标!!!)
{
    int i;
    for (i = S->last; i >= n; i--) {
        S->data[i + 1] = S->data[i];
    }
    S->data[n].coe = data->coe;
    S->data[n].index = data->index;
    S->last++;
}

int testCiXu(Seqlist * adr)    //测试有无同次项,有返回1,无返回零
{
    int i, j;
    for (i = 0; i < adr->last; i++)
        for (j = i + 1; j <= adr->last; j++) {
            if (adr->data[j].index == adr->data[i].index)
                return 1;
        }
    return 0;
}

void deleteLingXiang(Seqlist * adr)    //删除零项
{
    for (int i = 0; i <= adr->last; i++)    //删掉系数为零的项
    {
        if (fabs(adr->data[i].coe) <= 0.000001)
            deleteFromDm(adr, i);
    }
}

void heBingTongCiXiang(Seqlist * adr)    //合并同次项
{
    int i, j;
    for (i = 0; i < adr->last; i++)
        for (j = i + 1; j <= adr->last; j++) {
            if (adr->data[j].index == adr->data[i].index) {
                adr->data[i].coe += adr->data[j].coe;
                deleteFromDm(adr, j);
                j--;
            }
        }
    deleteLingXiang(adr);
}

int paiXuDuoXiang(Seqlist * a)    //将存储结构中的每项重新排列,如果输入的多项式次数从高到低排列,那么就不排,否则重新排列,使用快速排序法
{
    deleteLingXiang(a);
    if (!testXushu(a)) {    //printf("多项式排序中……\n");//可当掉
        kuaiPaiDuoXiang(a);
        return 1;
    }
    if (testCiXu(a)) {
        //printf("yes!同次数项\n");//可当掉
        heBingTongCiXiang(a);
        return 1;
    }
    return 0;
}

void print(Seqlist * adr)
{
    for (int i = 0; i <= adr->last; i++)
        printf("%f,%d\n", adr->data[i].coe, adr->data[i].index);
    if (adr->last < 0)    //处理和为零的情况
        printf("0\n");
}

void print2(Seqlist * adr)
{
    float f;
    int t, v;
    v = adr->last;
    if (adr->last < 0)    //处理和为零的情况
    {
        printf("0\n");
        return;
    }
    for (int i = 0; i <= v; i++) {
        f = adr->data[i].coe;
        t = adr->data[i].index;
        if (f > 0.0) {
            if (i != 0)
                printf("+");
            if (fabs(f - 1.0) < 0.000002) {
                if (t == 0)
                    printf("%.0f", f);
            } else
                printf("%.0f", f);
        } else {
            if (fabs(f + 1.0) < 0.000002) {
                printf("-");
                if (t == 0)
                    printf("\b%.0f", f);
            } else
                printf("%.0f", f);
        }
        if (t > 0) {
            printf("x");
            if (t > 1)
                printf("%d", t);
        }
        if (t < 0) {
            printf("x(");
            printf("%d", t);
            printf(")");
        }
    }
    printf("\n");
}

void add2DuoXiangShi(Seqlist * a, Seqlist * b)    //将两个多项式做加法
{
    int i, j;
    i = j = 0;        //两个存储结构的指向
    //Seqlist c;            
    paiXuDuoXiang(a);
    paiXuDuoXiang(b);
    if (a->last == -1) {
        for (; i <= b->last; i++) {
            addToDm(a, i, &b->data[i]);
        }
        return;
    }
    for (i = 0; i <= a->last; i++)    //第一个存储结构
    {
        for (; j <= b->last; j++)    //第二个存储结构
        {
            if (a->data[i].index < b->data[j].index) {
                addToDm(a, i, &b->data[j]);
                i++;
                continue;
            }
            if (a->data[i].index == b->data[j].index) {
                a->data[i].coe += b->data[j].coe;
                if (fabs(a->data[i].coe) <= 0.000001) {
                    deleteFromDm(a, i);
                    i--;
                }
                j++;
                if (i == a->last) {
                    i--;
                    break;
                }
                break;
            }
            if (a->data[i].index > b->data[j].index) {
                if (i < a->last)
                    break;
                else {
                    for (; j <= b->last; j++)
                        addToDm(a, i + 1,
                            &b->data[j]);
                }
            }
        }
    }
    if (testCiXu(a)) {
        //printf("yes!同次数项\n");
        heBingTongCiXiang(a);
    }
}

void changeZheng2Fu(Seqlist * a)
{
    int i = 0;
    for (; i <= a->last; i++)
        a->data[i].coe *= -1;
}

void chengDuoXiang(Seqlist * a, Seqlist * b, Seqlist * ji)    //多项式乘积函数
{
    int i, j;
    Seqlist d;
    Node e;
    //initSeqlist(&c);
    //print2(a);
    //print2(b);
    //exit(0);              
    i = 0;
    j = 0;
    for (; i <= a->last; i++) {
        initSeqlist(&d);
        for (j = 0; j <= b->last; j++) {
            e.coe = a->data[i].coe * b->data[j].coe;
            e.index = a->data[i].index + b->data[j].index;
            addToDm(&d, j, &e);
            //printf("%f,%d",e.coe,e.index);
        }
        add2DuoXiangShi(ji, &d);
        //print2(ji);
    }
}

void divideDuoXiang(Seqlist * a, Seqlist * b, Seqlist * ji)
{
    paiXuDuoXiang(a);
    paiXuDuoXiang(b);
    if (a->last == -1 && b->last != -1) {
        printf("0\n");
        return;
    }
    if (a->last != -1 && b->last == -1) {
        printf("除数不能为零!\n");
        return;
    }
    if (a->data[0].index < b->data[0].index) {
        printf("商:0;\n余数:");
        print2(b);
        return;
    }
}

void dealInput2(int i)
{

    Seqlist a, b, c;    //
    initSeqlist(&a);
    initSeqlist(&b);
    initSeqlist(&c);
    printf("请输入第一个多项式!,以#号结束!\n");
    dxInput(&a);
    //print(&a);
    //if(paiXuDuoXiang(&a));
    //print(&a);
    printf("请输入第二个多项式!,以#号结束!\n");
    dxInput(&b);
    //print(&b);
    //if(paiXuDuoXiang(&b));
    //print(&b);
    if (i == 1) {
        printf("两个多项式的和为:");
        add2DuoXiangShi(&a, &b);
        print2(&a);
    }
    if (i == 2) {
        printf("两个多项式的差为:");
        changeZheng2Fu(&b);
        add2DuoXiangShi(&a, &b);
        print2(&a);
    }
    //print(&a);
    if (i == 3) {
        printf("两个多项式的积为:");
        chengDuoXiang(&a, &b, &c);
        print2(&c);
    }
    //print(&a);   
/*     
    printf("两个多项式的商为:");
*/
}

void menu(void)
{
    printf("**********************************************\n");
    printf("****************多项式运算**********************\n");
    printf("***1:多项式加\n");
    printf("***2:多项式减\n");
    printf("***3:多项式乘\n");
    printf("***4:退出\n");
    printf("**********************************************\n");
    printf("请输入选项!");
}

int main(int argc, char *arg[])
{
    char c;
    puts("");
    puts(" 多项式运算  加减乘运算");
    puts("输入说明如下:输入的每项 axb ,a为系数,b为次数,且a,b,均不超过三位数,包括负号不超过4位,也不要为了好看加入空格,加入之后程序可能崩溃!");
    puts("若次数b为负数,在输入的时候,应加上阔号,输入的时候应尽可能按高次项,低次项的顺序输入");
    puts("以#号结束,例如 5x2+6x+5-x(-1)#");
    while (1) {
        menu();
        c = getchar();
        getchar();
        //getchar();    
        switch (c) {
        case '1':
            dealInput2(1);
            break;
        case '2':
            dealInput2(2);
            break;
        case '3':
            dealInput2(3);
            break;
        case '4':
            exit(0);
        }
    }
    return 1;
}
阅读(1676) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~