北理工42.五年级小学生的题目
42. 五年级小学生的题目
那两个小朋友在不断进步,他们已经学会了负数和多位数,于是他们又开始进行游戏了。小明给出一堆整数和运算要求(+、-、*、/、%),小丽要找出这些整数中的最大值和最小值,然后按照小明的要求算出最大数与最小数进行算术运算的结果。
输入:
用逗号分隔的整数序列,及其运算符和等号
输出:
最大数 op 最小数=结果
说明:本题目应该可以不使用数组就可以完成,关键是如何处理负数和减法。计算结果为 int。
| 测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
|---|---|---|---|---|---|
| 测试用例 1 | 以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
| 测试用例 2 | 以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
| 测试用例 3 | 以文本方式显示
|
以文本方式显示
|
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);
}

浙公网安备 33010602011771号