Chinaunix首页 | 论坛 | 博客
  • 博客访问: 743345
  • 博文数量: 141
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1115
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-17 14:32
个人简介

小公司研发总监,既当司令也当兵!

文章分类

全部博文(141)

分类: LINUX

2017-07-22 14:26:29

题目描述

  明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。

  这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?

  这个选择题中的每个表达式都满足下面的性质:

  1. 表达式只可能包含一个变量‘a’。

  2. 表达式中出现的数都是正整数,而且都小于10000。

  3. 表达式中可以包括四种运算‘+’(加),‘-’(减),‘*’(乘),‘^’(乘幂),以及小括号‘(’,‘)’。小括号的优先级最高,其次是‘^’,然后是‘*’,最后是‘+’和‘-’。‘+’和‘-’的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符‘+’,‘-’,‘*’,‘^’以及小括号‘(’,‘)’都是英文字符)

  4. 幂指数只可能是1到10之间的正整数(包括1和10)。

  5. 表达式内部,头部或者尾部都可能有一些多余的空格。


  下面是一些合理的表达式的例子:

((a^1) ^ 2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1 + (a -1)^3,1^10^9……

分析:表达式运算,一般都是用一个操作数栈,一个操作符栈,依据操作符的优先级逐级运算
本题的麻烦在于有一个变量,字符串操作起来就比较繁琐。
于是乎,就将多项式的每一项抽象为一个数据结构,因为每个项都可以由一个系数和指数唯一确定;那么一个多项式就可以表示为一组【系数+指数】的集合;


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define MAX_EXPONENT 100
  5. #define MAX_POLYNOMIAL 100

  6. typedef struct POLYNOMIAL_NODE {
  7.     unsigned int number;
  8.     short *coeff;
  9.     unsigned short *exp;
  10. } polynomial_t;


  11. polynomial_t* generate_from_list(short *exp_coeff, int len)
  12. {
  13.     polynomial_t *ret = NULL;
  14.     short *coeffs;
  15.     unsigned short *exps;

  16.     int cnt = 0;
  17.     int i, j;

  18.     for (i = 0; i < len; i++)
  19.     {
  20.         if (exp_coeff[i] != 0)
  21.         {
  22.             cnt++;
  23.         }
  24.     }
  25.     if (cnt == 0)
  26.     {
  27.         cnt = 1;// return 0
  28.     }

  29.     ret = (polynomial_t *)calloc(sizeof(polynomial_t), 1);
  30.     if (NULL == ret)
  31.     {
  32.         return NULL;
  33.     }

  34.     coeffs = (short *)calloc(sizeof(short), cnt);
  35.     exps = (unsigned short *)calloc(sizeof(unsigned short), cnt);
  36.     if (NULL == coeffs || NULL == exps)
  37.     {
  38.         return NULL;
  39.     }

  40.     j = 0;
  41.     for (i = 0; i < len; i++)
  42.     {
  43.         if (exp_coeff[i] != 0)
  44.         {
  45.             coeffs[j] = exp_coeff[i];
  46.             exps[j++] = i;
  47.         }
  48.     }
  49.     ret->number = cnt;
  50.     ret->coeff = coeffs;
  51.     ret->exp = exps;

  52.     return ret;
  53. }

  54. polynomial_t* polynomial_multip(polynomial_t *p1, polynomial_t *p2)
  55. {
  56.     short exp_coeff[MAX_EXPONENT] = { 0 };
  57.     int i, j;

  58.     for (i = 0; i < p2->number; i++)
  59.     {
  60.         for (j = 0; j < p1->number; j++)
  61.         {
  62.             exp_coeff[p1->exp[j] + p2->exp[i]] += p1->coeff[j] * p2->coeff[i];
  63.         }
  64.     }
  65.     return generate_from_list(exp_coeff, MAX_EXPONENT);
  66. }


  67. polynomial_t* polynomial_add(polynomial_t *p1, polynomial_t *p2)
  68. {
  69.     short exp_coeff[MAX_EXPONENT] = { 0 };
  70.     int i, j;

  71.     for (i = 0; i < p1->number; i++)
  72.     {
  73.         exp_coeff[p1->exp[i]] += p1->coeff[i];
  74.     }
  75.     for (i = 0; i < p2->number; i++)
  76.     {
  77.         exp_coeff[p2->exp[i]] += p2->coeff[i];
  78.     }
  79.     return generate_from_list(exp_coeff, MAX_EXPONENT);
  80. }

  81. polynomial_t* polynomial_sub(polynomial_t *p1, polynomial_t *p2)
  82. {
  83.     short exp_coeff[MAX_EXPONENT] = { 0 };
  84.     int i, j;

  85.     for (i = 0; i < p1->number; i++)
  86.     {
  87.         exp_coeff[p1->exp[i]] += p1->coeff[i];
  88.     }
  89.     for (i = 0; i < p2->number; i++)
  90.     {
  91.         exp_coeff[p2->exp[i]] -= p2->coeff[i];
  92.     }
  93.     return generate_from_list(exp_coeff, MAX_EXPONENT);
  94. }

  95. void polynomial_free(polynomial_t *p)
  96. {
  97.     if (!p)
  98.     {
  99.         return;
  100.     }
  101.     if (p->exp)
  102.     {
  103.         free(p->exp);
  104.     }
  105.     if (p->coeff)
  106.     {
  107.         free(p->coeff);
  108.     }
  109.     free(p);
  110. }

  111. void polynomial_print(polynomial_t *p)
  112. {
  113.     int i;
  114.     char sym;
  115.     char py[16];
  116.     if (!p)
  117.     {
  118.         return;
  119.     }

  120.     printf("polynomial<%p>, total %d:\n", p, p->number);
  121.     for (i = 0; i < p->number; i++)
  122.     {
  123.         memset(py, 0, 16);
  124.         if (p->coeff[i] < 0)
  125.         {
  126.             if (p->exp[i] == 0)
  127.             {
  128.                 sprintf(py, "%d", p->coeff[i]);
  129.             }
  130.             else if (p->exp[i] == 1)
  131.             {
  132.                 if (p->coeff[i] == -1)
  133.                 {
  134.                     sprintf(py, "-x");
  135.                 }
  136.                 else
  137.                     sprintf(py, "%dx", p->coeff[i]);
  138.             }
  139.             else
  140.             { if (p->coeff[i] == -1)
  141.                 {
  142.                     sprintf(py, "-x^%d", p->exp[i]);
  143.                 }
  144.                 else
  145.                     sprintf(py, "%dx^%u", p->coeff[i], p->exp[i]);
  146.             }
  147.         }
  148.         else
  149.         {
  150.             char* tmp = py;
  151.             if (i > 0)
  152.             {
  153.                 tmp[0] = '+';
  154.                 tmp++;
  155.             }

  156.             if (p->exp[i] == 0)
  157.             {
  158.                 sprintf(tmp, "%d", p->coeff[i]);
  159.             }
  160.             else if (p->exp[i] == 1)
  161.             {
  162.                 if (p->coeff[i] == 1)
  163.                 {
  164.                     sprintf(tmp, "x");
  165.                 }
  166.                 else
  167.                     sprintf(tmp, "%dx", p->coeff[i]);
  168.             }
  169.             else
  170.             {
  171.                 if (p->coeff[i] == 1)
  172.                 {
  173.                     sprintf(tmp, "x^%d", p->exp[i]);
  174.                 }
  175.                 else
  176.                     sprintf(tmp, "%dx^%d", p->coeff[i], p->exp[i]);
  177.             }
  178.         }
  179.         printf("%s", py);
  180.     }
  181.     printf("\n");
  182. }

  183. polynomial_t* polynomial_power(polynomial_t *p1, polynomial_t *p2)
  184. {
  185.     short exp_coeff[MAX_EXPONENT] = { 0 };
  186.     int i, j;
  187.     int exp = 0;
  188.     polynomial_t *ret;
  189.     polynomial_t *tmp;

  190.     if (p2->number != 1)
  191.     {
  192.         printf("polynomial power only support number\n");
  193.         return NULL;
  194.     }
  195.     exp = p2->coeff[0];

  196.     if (exp == 0)
  197.     {
  198.         exp_coeff[0] = 1;
  199.         return generate_from_list(exp_coeff, MAX_EXPONENT);
  200.     }
  201.     else if (exp < 0)
  202.     {
  203.         printf("polynomial power only support positive exponal\n");
  204.         return NULL;
  205.     }
  206.     if (exp == 1)
  207.     {
  208.         return p1;
  209.     }

  210.     ret = p1;
  211.     tmp = NULL;
  212.     while (exp > 1)
  213.     {
  214.         ret = polynomial_multip(ret, p1);
  215.         if (tmp)
  216.         {
  217.             polynomial_free(tmp);
  218.         }
  219.         tmp = ret;
  220.         exp--;
  221.     }
  222.     return ret;
  223. }

  224. char* parse_polynomial(char *str, polynomial_t **ptr)
  225. {
  226.     char *cur = str;
  227.     polynomial_t *ret = NULL;
  228.     short exp_coeff[2] = { 0 };
  229.     short coeff = 0;

  230.     if (*cur == 'x')
  231.     {
  232.         exp_coeff[1] = 1;
  233.         ret = generate_from_list(exp_coeff, 2);
  234.         *ptr = ret;
  235.         return ++cur;
  236.     }

  237.     while (*cur >= '0' && *cur <= '9')
  238.     {
  239.         coeff = coeff * 10 + (*cur - '0');
  240.         cur++;
  241.     }

  242.     exp_coeff[0] = coeff;
  243.     ret = generate_from_list(exp_coeff, 2);
  244.     *ptr = ret;
  245.     return cur;
  246. }

  247. polynomial_t* polynomial_comput(char *str)
  248. {
  249.     char symstack[MAX_POLYNOMIAL] = { 0, };
  250.     int symhead = -1;
  251.     polynomial_t *pstack[MAX_POLYNOMIAL] = { NULL };
  252.     int phead = -1;

  253.     polynomial_t *opt1;
  254.     polynomial_t *opt2;
  255.     polynomial_t *ret;
  256.     char optch;

  257.     char *cur;

  258.     if (!str)
  259.     {
  260.         return NULL;
  261.     }

  262.     cur = str;
  263.     while (*cur != '\0')
  264.     {
  265.         if (*cur == 'x' || (*cur >= '0' && *cur <= '9'))
  266.         {
  267.             cur = parse_polynomial(cur, &pstack[++phead]);
  268.             continue;
  269.         }
  270.         else
  271.         {
  272.             switch (*cur)
  273.             {
  274.             case '(': // 左括号直接入栈
  275.                 symstack[++symhead] = *cur;
  276.                 break;

  277.             case '^': // 查看符号栈顶是否为'^',如果是 弹出运算,其余的直接压栈
  278.                 if (symhead >= 0 && symstack[symhead] == '^')
  279.                 {
  280.                     optch = symstack[symhead--];
  281.                     opt2 = pstack[phead--];
  282.                     opt1 = pstack[phead--];

  283.                     ret = polynomial_power(opt1, opt2);
  284.                     pstack[++phead] = ret;
  285.                     symstack[++symhead] = *cur;
  286.                     polynomial_free(opt2);
  287.                     polynomial_free(opt1);
  288.                 }
  289.                 else
  290.                 {
  291.                     symstack[++symhead] = *cur;
  292.                 }
  293.                 break;

  294.             case '*': // 符号栈顶为'^''*'则运算,否则压栈
  295.                 if (symhead >= 0 && (symstack[symhead] == '^' || symstack[symhead] == '*'))
  296.                 {
  297.                     optch = symstack[symhead--];
  298.                     opt2 = pstack[phead--];
  299.                     opt1 = pstack[phead--];

  300.                     if (optch == '^')
  301.                         ret = polynomial_power(opt1, opt2);
  302.                     else
  303.                         ret = polynomial_multip(opt1, opt2);

  304.                     pstack[++phead] = ret;
  305.                     symstack[++symhead] = *cur;
  306.                     polynomial_free(opt2);
  307.                     polynomial_free(opt1);

  308.                 }
  309.                 else
  310.                 {
  311.                     symstack[++symhead] = *cur;
  312.                 }
  313.                 break;
  314.             case '+':
  315.             case '-':
  316.                 if (symhead >= 0 & symstack[symhead] != '(')
  317.                 {
  318.                     optch = symstack[symhead--];
  319.                     opt2 = pstack[phead--];
  320.                     opt1 = pstack[phead--];

  321.                     if (optch == '^')
  322.                         ret = polynomial_power(opt1, opt2);
  323.                     else if (optch == '*')
  324.                     {
  325.                         ret = polynomial_multip(opt1, opt2);
  326.                     }
  327.                     else if (optch == '+')
  328.                     {
  329.                         ret = polynomial_add(opt1, opt2);
  330.                     }
  331.                     else if (optch == '-')
  332.                     {
  333.                         ret = polynomial_sub(opt1, opt2);
  334.                     }

  335.                     pstack[++phead] = ret;
  336.                     symstack[++symhead] = *cur;
  337.                     polynomial_free(opt2);
  338.                     polynomial_free(opt1);
  339.                 }
  340.                 else
  341.                     symstack[++symhead] = *cur;

  342.                 break;

  343.             case ')': // 如果是右括号,则一直运算直到找到左括号
  344.                 while (symhead >= 0 && symstack[symhead] != '(')
  345.                 {
  346.                     optch = symstack[symhead--];
  347.                     opt2 = pstack[phead--];
  348.                     opt1 = pstack[phead--];

  349.                     if (optch == '^')
  350.                         ret = polynomial_power(opt1, opt2);
  351.                     else if (optch == '*')
  352.                     {
  353.                         ret = polynomial_multip(opt1, opt2);
  354.                     }
  355.                     else if (optch == '+')
  356.                     {
  357.                         ret = polynomial_add(opt1, opt2);
  358.                     }
  359.                     else if (optch == '-')
  360.                     {
  361.                         ret = polynomial_sub(opt1, opt2);
  362.                     }

  363.                     pstack[++phead] = ret;
  364.                 }
  365.                 if (symstack[symhead] != '(')
  366.                 {
  367.                     printf("miss match of ')'\n");
  368.                     return NULL;
  369.                 }
  370.                 symhead--;
  371.                 break;
  372.             default:
  373.                 break;
  374.             }
  375.             cur++;
  376.         }
  377.     }

  378.     while (symhead >= 0)
  379.     {
  380.         optch = symstack[symhead--];
  381.         opt2 = pstack[phead--];
  382.         opt1 = pstack[phead--];

  383.         if (optch == '^')
  384.         {
  385.             ret = polynomial_power(opt1, opt2);

  386.         }
  387.         else if (optch == '*')
  388.         {
  389.             ret = polynomial_multip(opt1, opt2);
  390.         }
  391.         else if (optch == '+')
  392.         {
  393.             ret = polynomial_add(opt1, opt2);
  394.         }
  395.         else if (optch == '-')
  396.         {
  397.             ret = polynomial_sub(opt1, opt2);
  398.         }

  399.         pstack[++phead] = ret;
  400.         polynomial_free(opt2);
  401.         polynomial_free(opt1);
  402.     }

  403.     if (phead != 0)
  404.     {
  405.         printf("error : %d\n", phead);
  406.         polynomial_print(pstack[phead]);
  407.         return NULL;
  408.     }
  409.     return pstack[0];

  410. }

  411. int main(int argc, char **argv)
  412. {
  413.     polynomial_t *pyn;
  414.     char src[32] = "(x+1)^2^2-(x-x)^3+((x-1)*(x-1))";

  415.     pyn = polynomial_comput(src);
  416.     polynomial_print(pyn);
  417.     return 0;
  418. }

阅读(2788) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~