iT邦幫忙

0

c語言結構問題

題目是將兩個方程式相乘並印出,我的想法是將所乘出來的項目分成兩組存在terms陣列中,之後再比較他們的次方再做加減,但是在相乘的時候發現不能夠存取,想問一下是為甚麼?另外如果我要做比較的話,它們的位置我是想另外再設一個值去讀取他們再做比較,不知道有沒有更好的想法?麻煩大家給小弟一點提示

 #include <stdio.h>
#include <stdlib.h>

#define MAX_TERMS 50
#define COMPARE(x, y) ((x) < (y) ? -1 : ((x) == (y)) ? 0 : 1)

struct polynomial {
    float coef;
    int expon;
};
struct polynomial terms[MAX_TERMS];
int avail = 0;

void padd(int starta, int finisha, int startb, int finishb, int *startc, int *finishc);

void attach(float coefficient, int exponent);

void print_polynomial(int start, int end);

int main() {

    int i, j;

    int a_coef[] = {  2, 1}, b_coef[] = {1, 10, 4, 1},
         a_exp[] = {100, 0},  b_exp[] = {4,  3, 2, 0};

    int a_start = 0, a_finish = 1,
        b_start = 2, b_finish = 5,
        c_start    , c_finish;

    avail = 6;

    for (i = a_start, j = 0; i <= a_finish; i++, j++) {
        terms[i].coef = a_coef[j];
        terms[i].expon = a_exp[j];
    }

    for (i = b_start, j = 0; i <= b_finish; i++, j++) {
        terms[i].coef = b_coef[j];
        terms[i].expon = b_exp[j];
    }

    printf("A(x) = ");
    print_polynomial(a_start, a_finish);
    printf("B(x) = ");
    print_polynomial(b_start, b_finish);

    padd(a_start, a_finish, b_start, b_finish, &c_start, &c_finish);

    printf("A(x) * B(x) = ");
    print_polynomial(c_start, c_finish);

    return 0;
}

void print_polynomial(int start, int end) {
    int i = start, exp;
    float coef;

    printf("%.2f", terms[i].coef);
    if (terms[i].expon != 0) {
        printf("x^%d", terms[i].expon);
    }

    for (i++; i <= end; i++) {
        coef = terms[i].coef;
        exp = terms[i].expon;
        if (coef == 0){
            continue;
        }
        else{
            if(coef > 0){
                printf(" + %.2f", coef);
            }
            else{
                printf(" - %.2f", coef * -1);
            }
        }

        if (terms[i].expon != 0) {
            printf("x^%d", terms[i].expon);
        }
    }
    printf("\n");
}

/* add a new term to the polynomial */
void attach(float coefficient, int exponent) {
    if (avail >= MAX_TERMS) {
        fprintf(stderr,"Too many terms in the  polynomial\n");
        exit(1);
    }
    terms[avail].coef = coefficient;
    terms[avail++].expon = exponent;
}

/* add A(x) and B(x) to obtain C(x) */
void padd(int starta, int finisha, int startb, int finishb, int *startc, int *finishc) {
    float coefficient;
    int exponent;
    *startc = avail;

    for(; starta<=finisha; starta++){
        while(startb<=finishb){
            coefficient=terms[starta].coef*terms[startb].coef;
            exponent=terms[starta].expon+terms[startb].expon;
            attach(coefficient, exponent);
            if(startb==finishb){
                startb=0;
            }
            else{
                startb++;
            }
        }
    }
    int y,z;
    y=(*startc+*finishc)/2;
    z=y+1;
    while (*startc <= y && z <= *finishc)
        switch (COMPARE(terms[*startc].expon, terms[z].expon)) {
            case -1:
                attach(terms[z].coef, terms[z].expon);
                z++;
                break;
            case 0: /* equal exponents */
                coefficient = terms[*startc].coef + terms[z].coef;
                if (coefficient)
                    attach(coefficient, terms[*startc].expon);
                *startc++;
                z++;
                break;
            case 1:
                attach(terms[*startc].coef, terms[z].expon);
                *startc++;
        }

    /* add in remaining terms of A(x) */
    for (; starta <= finisha; starta++)
        attach(terms[starta].coef, terms[starta].expon);
    /* add in remaining terms of B(x) */
    for (; startb <= finishb; startb++)
        attach(terms[startb].coef, terms[startb].expon);
   *finishc = avail - 1;

}

2 個回答

2
淺水員
iT邦高手 3 級 ‧ 2021-03-23 12:58:01
最佳解答

修正

define COMPARE

修正括號位置

#define COMPARE(x, y) ((x) < (y) ? -1 : ((x) == (y) ? 0 : 1))

padd 函式

要合併相同次方,寫入前直接判斷就可

void padd(int starta, int finisha, int startb, int finishb, int *startc, int *finishc) {
    float coefficient;
    int exponent;
    *startc = avail;
    int i, j, k;

    for(i=starta; i<=finisha; i++){
        for(j=startb; j<=finishb; j++){
            coefficient=terms[i].coef*terms[j].coef;
            exponent=terms[i].expon+terms[j].expon;
            //找看看有沒有同樣次方的,有的話直接加上去
            for(k=*startc; k<=avail; ++k) {
                if(COMPARE(terms[k].expon, exponent)==0) {
                    terms[k].coef+=coefficient;
                    continue;
                }
            }
            //沒有同樣次方項,添加在後面
            attach(coefficient, exponent);
        }
    }
    *finishc = avail;
}

其他

初始化多項式時,可以寫一個函式來初始化。
另外透過 sizeof 可以自動算出陣列長度,減少人工寫死出錯的機率。

/* init polynomial*/
void init_polynomial(int *coefArr, int *expArr, int n, int *start, int *end)
{
    int i;
    *start=avail;
    for(i=0; i<n; ++i) {
        attach(coefArr[i], expArr[i]);
    }
    *end=avail-1;
}

int main() {

    int i, j;

    int a_coef[] = {  2, 1}, b_coef[] = {1, 10, 4, 1},
         a_exp[] = {100, 0},  b_exp[] = {4,  3, 2, 0};

    int a_start, a_finish,
        b_start, b_finish,
        c_start, c_finish;
    
    //利用 sizeof 可以自動取得陣列長度
    init_polynomial(a_coef, a_exp, sizeof(a_coef)/sizeof(*a_coef), &a_start, &a_finish);
    init_polynomial(b_coef, b_exp, sizeof(b_coef)/sizeof(*b_coef), &b_start, &b_finish);
    //後面省略
}

最後下面還有幾點提供參考(這邊就不給範例了):

  1. 盡量避免用全域變數,可以把 terms 跟 avail 改成參數或是做為某個 struct 的元素來傳遞。
  2. 可以改用 malloc、realloc 這些函式動態宣告記憶體,對於「上限」會比較彈性。
abalun52 iT邦新手 5 級 ‧ 2021-03-23 13:49:31 檢舉

謝謝大大的修改跟建議我在想一下跟測試一下

1
海綿寶寶
iT邦大神 1 級 ‧ 2021-03-23 09:36:30

1.我不會
2.Google 這幾篇給你參考

abalun52 iT邦新手 5 級 ‧ 2021-03-23 13:49:01 檢舉

謝謝 海綿寶寶的資料

我要發表回答

立即登入回答