北理工42.五年级小学生的题目

42. 五年级小学生的题目

   那两个小朋友在不断进步,他们已经学会了负数和多位数,于是他们又开始进行游戏了。小明给出一堆整数和运算要求(+、-、*、/、%),小丽要找出这些整数中的最大值和最小值,然后按照小明的要求算出最大数与最小数进行算术运算的结果。

输入:
    用逗号分隔的整数序列,及其运算符和等号

输出:
    最大数 op 最小数=结果

说明:本题目应该可以不使用数组就可以完成,关键是如何处理负数和减法。计算结果为 int。

  测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1 以文本方式显示
  1. 1,10,100,+,=↵
以文本方式显示
  1. 100 + 1 = 101↵
1秒 64M 0
测试用例 2 以文本方式显示
  1. -100,-1,1,100,+,=↵
以文本方式显示
  1. 100 + (-100) = 0↵
1秒 64M 0
测试用例 3 以文本方式显示
  1. -20,-10,0,10,20,*,=↵
以文本方式显示
  1. 20 * (-20) = -400↵
1秒 64M 0

 

其实这道题不难,不过我写的很坎坷!特此做博客,来记录辛酸史!

 

第一版的思路是这样的,但是很可惜,失败了!

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void)
{
    /*用scanf读入%d,
    * 如果是','等非数值输入,scanf会返回0,并且将数据放回缓冲区,
    * 通过对scanf返回值的判断,进行下一步    
    * 用getchar读入符号后,然后用switch-case看符号选择
    */
    int max, min;
    int temp;
    scanf("%d", &temp);
    min = max = temp;
    char ch = 0;
    bool flag = true;
    while (flag) {
        if (1 == scanf("%d", &temp)) {
            max = temp > max ? temp : max;
            min = temp < min ? temp : min;
        }
        else {
            //printf("first, ch = %c\n", ch);
            switch (ch = getchar()) {
            case '+':
                flag = false;
                scanf("%*s");
                printf("%d %c %d = %d\n", max, ch, min, max + min);
                break;
            case '-':
                flag = false;
                scanf("%*s");
                printf("%d %c %d = %d\n", max, ch, min, max - min);
                break;
            case '*':
                flag = false;
                scanf("%*s");
                printf("%d %c %d = %d\n", max, ch, min, max * min);
                break;
            case '/':
                flag = false;
                scanf("%*s");
                printf("%d %c %d = %d\n", max, ch, min, max / min);
                break;
            case '%':
                flag = false;
                scanf("%*s");
                printf("%d %c %d = %d\n", max, ch, min, max % min);
                break;
            case ',':
                flag = true;
                break;
            default:
                printf("Oops!\n");
                break;
            }
            //printf("second, ch = %c\n", ch);
        }
    }
    return 0;
}

 

百思不得其解,甚至于跑去问助教,当然,助教并没有回复我!我的消息一个月后仍然显示着未读……

于是只能自己找bug,终于找到了,是scanf()的问题,它会吞掉我的+、-

用代码测试一下

/*测试scanf()*/
int a;
	if (1 == scanf("%d", &a)) {
		printf("true!\n");
		printf("interger a %d, character a %c\n", a, a);
		putchar(getchar());
	}
	else {
		printf("false!\n");
		printf("interger %d, character %c\n", a, a);
		putchar(getchar());
	}

输入样例,+,

原本想当然的认为会输出 一行乱码,然后再输出+

 

实际输出:

  false!
  interger -858993460, character ?
  ,

最后一行居然是',',这是一件很不友好的消息!但是要学会接收(哦,补充一下,第二行的数据如果不一样的话,也用不着慌张,可能编译器不同,电脑不同都会有影响)

这个bug让我找了一个月

 

于是后来修改了一下代码:

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#define SIZE 20
int main(void)
{
    /*我能想到的只能是字符了,遇到逗号将其转换为\0
    * 然后将其转换为数字
    * 再从转换的数字中挑出最大与最小
    * 一直遇到运算符才跳出循环 
    */
    char ch[SIZE] = {0};
    char sign = '+';
    bool flag = true;
    bool alter = false;
    int i = 0;
    int max=-1000000, min=1000000;/*此处max我故意使用了一个非常小的数, 
                                    一定要充分小, 而min则相反*/
    while (flag) {
        *(ch+i) = getchar();
        switch (*(ch+i)) {
        case ',':
            *(ch+i) = '\0';
            alter = true;
            i = 0;
            break;
        case '+':
            flag = false;
            sign = '+';
            break;
        case '-':
            ++i;
            *(ch + i) = getchar();
            if (isdigit(*(ch + i))) {
                i++;
                break;
            }
            flag = false;
            sign = '-';
            break;            
        case '*':
            flag = false;
            sign = '*';
            break;
        case '/':
            flag = false;
            sign = '/';
            break;
        case '%':
            flag = false;
            sign = '%';
            break;
        default:
            i++;
            break;
        }
        if (alter) {
            int temp = atoi(ch);
            max = max > temp ? max : temp;
            min = min < temp ? min : temp;
            alter = false;
        }
    }
    switch (sign) {
    case '+':
        if (max < 0)  printf("(%d) %c (%d) = %d\n", max,sign, min, max + min);
        else if(min<0) printf("%d %c (%d) = %d\n", max,sign, min, max + min);
        else printf("%d %c %d = %d\n", max,sign, min, max + min);
        break;
    case '-':
        if (max < 0)  printf("(%d) %c (%d) = %d\n", max, sign, min, max - min);
        else if (min < 0) printf("%d %c (%d) = %d\n", max, sign, min, max - min);
        else printf("%d %c %d = %d\n", max, sign, min, max - min);
        break;
    case '*':
        if (max < 0)  printf("(%d) %c (%d) = %d\n", max, sign, min, max * min);
        else if (min < 0) printf("%d %c (%d) = %d\n", max, sign, min, max * min);
        else printf("%d %c %d = %d\n", max, sign, min, max * min);
        break;
    case '/':
        if (max < 0)  printf("(%d) %c (%d) = %d\n", max, sign, min, max / min);
        else if (min < 0) printf("%d %c (%d) = %d\n", max, sign, min, max / min);
        else printf("%d %c %d = %d\n", max, sign, min, max / min);
        break;
    case '%':
        if (max < 0)  printf("(%d) %c (%d) = %d\n", max, sign, min, max % min);
        else if (min < 0) printf("%d %c (%d) = %d\n", max, sign, min, max % min);
        else printf("%d %c %d = %d\n", max, sign, min, max % min);
        break;
    }    
    return 0;
}

可以看到,代码非常的长

又过了一段时间,我把他又优化了一点

#include <stdio.h>
#define SIZE 200
void my_print(int max, char op, int min, int num);
int main(void)
{
    /*学习新思想,争做新青年
    * 通过进一步的学习,又了解到了一个新函数,sscanf(),它的强大特性可以更好的帮助我
    * 这次我将利用新的武器重构代码
    */
    char s[SIZE] = { 0 };
    int maxn = 0x80000000, minn = 0x7fffffff;
    scanf("%s", s);
    int t;
    while (s[2] != '=') {
        sscanf(s, "%d,%s", &t, s);
        maxn = maxn > t ? maxn : t;
        minn = minn < t ? minn : t;
    }
    char op = s[0];
    int num;
    switch (op) {
    case '+':
        num = maxn + minn;
        break;
    case '-':
        num = maxn - minn;
        break;
    case '*':
        num = maxn * minn;
        break;
    case '/':
        num = maxn / minn;
        break;
    case '%':
        num = maxn % minn;
        break;
    }
    my_print(maxn, op, minn, num);    
    return 0;
}
void my_print(int max, char op, int min, int num)
{
    if (max < 0) printf("(%d) %c (%d) = %d\n", max, op, min, num);
    else if(min<0) printf("%d %c (%d) = %d\n", max, op, min, num);
    else printf("%d %c %d = %d\n", max, op, min, num);
}

 

posted @ 2022-12-04 21:51  我千五可以  阅读(243)  评论(0)    收藏  举报