请大神帮忙用c语言用线性表写一个一元多项式相加相减相乘的程序!!!

2025-06-26 19:59:21
推荐回答(1个)
回答1:

#include 
#include 
#include 
#include 

using namespace std;

unsigned int test_array[] =
{
    1,2,3,4,5,6,7,8,9,10,
    11,12,13,14,15,16,17,18,19,20,
    21,22,23,24,25,26,27,28,29,30,
    31,32,33,34,35,36,37,38,39,40,
    41,42,43,44,45,46,47,48,49,50,
    51,52,53,54,55,56,57,58,59,60,
    61,62,63,64,65,66,67,68,69,70,
    71,72,73,74,75,76,77,78,79,80,
    81,82,83,84,85,86,87,88,89,90,
    91,92,93,94,95,96,97,98,99,100
};

/*+,-,*,/,(,),@,#*/
char cmp_table[][8] =
{
    {'>','>','<','<','<','>','<','>'},
    {'>','>','<','<','<','>','<','>'},
    {'>','>','>','>','<','>','<','>'},
    {'>','>','>','>','<','>','<','>'},
    {'<','<','<','<','<','=','<','$'},
    {'>','>','>','>','$','>','<','>'},
    {'>','>','>','>','<','$','=','>'},
    {'<','<','<','<','<','$','<','='}
};

int swap_table(char c)
{
    switch(c)
    {
        case '+':return 0;
        case '-':return 1;
        case '*':return 2;
        case '/':return 3;
        case '(':return 4;
        case ')':return 5;
        case '@':return 6;
        case '#':return 7;
    }
    return -1;
}

struct UNIT
{
    unsigned int operand;
    char _operator;
    UNIT *next;
};
char cmp_operator(char a,char b)
{
    return cmp_table[swap_table(a)][swap_table(b)];
}

int calc(char *sz);

void showlink(UNIT *start,int pStart)
{
    while(start != NULL)
    {
        if(start->_operator != 0)
        {
            printf("%c ",start->_operator);
        }
        else
            printf("%d ",start->operand);
        start = start->next;
    }
    printf("\n");
}
void showarray(UNIT *start,int pStart)
{
    int i;
    for(i=0;i    {
        if(start[i]._operator != 0)
        {
            printf("%c ",start[i]._operator);
        }
        else
            printf("%d ",start[i].operand);
    }
    printf("\n");
}

int main()
{
    char sz[1000];
    while(1)
    {
        gets(sz);
        printf("%d\n",calc(sz));
    }
    return 0;
}

int calc(char *sz)
{
    bool is_innum = false,is_valid = true;
    char *sz_p = sz,reg[4];
    int i,pUnit = 0,result = 0,len = strlen(sz);
    sz[len] = '#';
    sz[len+1] = '\0';
    len++;
    UNIT *unit = (UNIT*)malloc(len*sizeof(UNIT));
    memset(unit,0,len*sizeof(UNIT));

    for(i=0;i    {
        switch(*sz_p)
        {
        case '+':
        case '-':
        case '*':
            if(pUnit == 0 || (unit[pUnit-1]._operator != 0 && unit[pUnit-1]._operator != ')'))
            {
                unit[pUnit++]._operator = '@';
                break;
            }
        case '/':
        case '(':
        case ')':
        case '#':
            is_innum = false;
            sscanf(sz_p,"%c",&unit[pUnit++]._operator);
            break;
        case '%':
            strncpy(reg,sz_p+1,3);
            reg[3] = 0;
            strupr(reg);
            if(strcmp(reg,"EAX") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[0]);
            else if(strcmp(reg,"EBX") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[10]);
            else if(strcmp(reg,"ECX") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[20]);
            else if(strcmp(reg,"EDX") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[30]);
            else if(strcmp(reg,"ESI") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[40]);
            else if(strcmp(reg,"EDI") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[50]);
            else if(strcmp(reg,"ESP") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[60]);
            else if(strcmp(reg,"EBP") == 0)
                unit[pUnit++].operand = (unsigned int)(&test_array[70]);
            else
                is_valid = false;
            i+=3;
            sz_p+=3;
            break;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            if(!is_innum)
            {
                is_innum = true;
                sscanf(sz_p,"%d",&unit[pUnit++].operand);
            }
            break;
        default:is_valid = false;break;
        }
        sz_p++;
    }

    UNIT *LinearTable = (UNIT*)malloc(pUnit*sizeof(UNIT));
    memset(LinearTable,0,pUnit*sizeof(UNIT));
    int pLinearTable = 0;
    UNIT *Stack = (UNIT*)malloc(pUnit*sizeof(UNIT));
    memset(Stack,0,pUnit*sizeof(UNIT));
    int pStack = 0;
    Stack[pStack++]._operator = '#';

    //showarray(unit,pUnit);
    i = 0;
    while(is_valid && (Stack[pStack-1]._operator != '#' || unit[i]._operator != '#'))
    {
        //showarray(Stack,pStack);
        //showarray(LinearTable,pLinearTable);
        if(unit[i]._operator != 0)
        {
            if(cmp_operator(Stack[pStack-1]._operator,unit[i]._operator) == '$')
            {
                is_valid = false;
                break;
            }
            while(pStack != 0 && cmp_operator(Stack[pStack-1]._operator,unit[i]._operator) == '>')
            {
                LinearTable[pLinearTable++]._operator = Stack[--pStack]._operator;
            }
            if(cmp_operator(Stack[pStack-1]._operator,unit[i]._operator) == '=')
            {
                if(Stack[pStack-1]._operator == '(' && unit[i]._operator == ')')
                {
                    pStack--;
                    if(pStack >0 && Stack[pStack-1]._operator == '@')
                    {
                        LinearTable[pLinearTable++]._operator = Stack[--pStack]._operator;
                    }
                }
            }
            if(cmp_operator(Stack[pStack-1]._operator,unit[i]._operator) == '<')
            {
                Stack[pStack++]._operator = unit[i]._operator;
            }
        }
        else
        {
            LinearTable[pLinearTable++].operand = unit[i].operand;
        }
        if(unit[i]._operator != '#')
            i++;
    }

    for(i=0;i    {
        LinearTable[i].next = &LinearTable[i+1];
    }
    LinearTable[i].next = NULL;

    //printf("\narray:\n");
    //showarray(LinearTable,pLinearTable);

    UNIT *operand_1 = &LinearTable[0],*operand_2 = NULL,*pOperator = NULL;
    assert(operand_1 != NULL);
    while(is_valid && operand_1->next != NULL)
    {
        //printf("%d %d %c\n",operand_1->operand,operand_2->operand,pOperator->_operator);
        //printf("calc:\n");
        //showlink(LinearTable,0);
        if(LinearTable[0].next->_operator == '@')
        {
            printf("is in @\n");
            operand_2 = &LinearTable[0];
            pOperator = LinearTable[0].next;
        }
        else if(LinearTable[0].next->next != NULL)
        {
            operand_2 = LinearTable[0].next;
            pOperator = LinearTable[0].next->next;
        }
        else
            is_valid = false;

        while(pOperator != NULL && pOperator->_operator == 0)
        {
            operand_1 = operand_1->next;
            operand_2 = operand_2->next;
            pOperator = pOperator->next;
        }

        //showlink(LinearTable,0);

        switch(pOperator->_operator)
        {
        case '@':
            operand_2->operand = *((unsigned int *)(operand_2->operand));
            operand_2->next = pOperator->next;
            showlink(LinearTable,0);
            break;
        case '+':
            operand_1->operand = operand_1->operand + operand_2->operand;
            operand_1->next = pOperator->next;
            break;
        case '-':
            operand_1->operand = operand_1->operand - operand_2->operand;
            operand_1->next = pOperator->next;
            break;
        case '*':
            operand_1->operand = operand_1->operand * operand_2->operand;
            operand_1->next = pOperator->next;
            break;
        case '/':
            operand_1->operand = operand_1->operand / operand_2->operand;
            operand_1->next = pOperator->next;
            break;
        }
        operand_1 = &LinearTable[0];
    }

    if(is_valid)
        result = operand_1->operand;
    else
        result = -1;
    free(LinearTable);
    free(Stack);
    free(unit);
    return result;
}

操作示例: