Abstract: PHP语言if-else/switch-casewhile练习

题目一:输入年月日,计算是该年的多少天。

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
<?php
//form: year.month.day
$date = fgets(STDIN);
$Date = explode('.', $date);
echo $Date;
$year = $Date[0];
$month = $Date[1];
$day = $Date[2];
echo "<br>";
echo $year;
echo "<br>";
echo $month;
echo "<br>";
echo $day;
if(($year%4==0 && $year%100!=0)||($year%400==0)){
$flag=1;
}
else{
$flag=0;
}
switch($month){
case($month<=2):
$days = 31*($month-1)+$day;
break;
case(3<=$month&&$month<=8):
if($flag==1){
if($month%2==1) {
$days = 31 * (intval($month - 1) / 2) + 29 + 30 * (intval($month / 2) - 1) + $day;
}
else{
$days = 31 * (intval($month) / 2) + 29 + 30 * (intval($month/ 2)-2) + $day;
}
}else{
if($month%2==1) {
$days = 31 * (intval($month - 1) / 2) + 28 + 30 * (intval($month / 2) - 1) + $day;
}
else{
$days = 31 * (intval($month) / 2) + 28 + 30 * (intval(($month) / 2)-2) + $day;
}
}
break;
default:
if($flag==1){
if($month%2==1) {
$days = 31 * (intval($month + 1) / 2) + 29 + 30 * (intval($month / 2) - 2) + $day;
}
else{
$days = 31 * (intval($month) / 2) + 29 + 30 * (intval($month/ 2)-2) + $day;
}
}else{
if($month%2==1) {
$days = 31 * (intval($month + 1) / 2) + 28 + 30 * (intval($month / 2) - 2) + $day;
}
else{
$days = 31 * (intval($month) / 2) + 28 + 30 * (intval($month/ 2)-2) + $day;
}
}
break;
}
echo $days;
?>

代码缺点:可以看出来代码有些地方重复使用,没有达到简洁的目的,瑞年和平年在二月相差一天,完全可以通过flag这个标识来弥补。改进思路:设置一个FebDays的变量,把值设为28,在case里面不需要再次判断瑞年平年,计算days时,把flag加上,这样就可以把瑞平年分开。

改进版:

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
<?php
//year-month-day
$date = fgets(STDIN);
$Date = explode('.', $date);
echo $Date;
$year = $Date[0];
$month = $Date[1];
$day = $Date[2];
echo "<br>";
echo $year;
echo "<br>";
echo $month;
echo "<br>";
echo $day;
if(($year%4==0 && $year%100!=0)||($year%400==0)){
$flag=1;
}
else{
$flag=0;
}
$FebDays = 28;
switch($month){
case($month<=2):
$days = 31*($month-1)+$day;
break;
case(3<=$month&&$month<=8):
if($month%2==1) {
$days = 31 * (intval($month - 1) / 2) + $FebDays + $flag + 30 * (intval($month / 2) - 1) + $day;
}
else{
$days = 31 * (intval($month) / 2) + $FebDays + $flag + 30 * (intval($month/ 2)-2) + $day;
}
break;
default:
if($month%2==1) {
$days = 31 * (intval($month + 1) / 2) + $FebDays + $flag + 30 * (intval($month / 2) - 2) + $day;
}
else{
$days = 31 * (intval($month) / 2) + $FebDays + $flag + 30 * (intval($month/ 2)-2) + $day;
}
break;
}
echo $days;
?>

两段代码对比可以发现,计算天数的代码量较少的将近一半。

题目二:可以一直输入学生成绩,知道输入q/exit/quit退出程序

思路一:在死循环里面执行代码,符合退出条件时break

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
<?php

while(1){
echo "Please Input Your Mes: ";
$inMes = fgets(STDIN);
var_dump($inMes);
if((trim($inMes)=="q")||(trim($inMes)=="quit")||(trim($inMes)=="exit")){
break;
}
else {
switch ($inMes) {
case(90 <= $inMes && $inMes <= 100):
echo "Your Grade is A";
break;
case(80 <= $inMes && $inMes < 90):
echo "YourGrade is B";
break;
case(70 <= $inMes && $inMes < 80):
echo "Your Grade is C";
break;
case(60 <= $inMes && $inMes < 70):
echo "YourGrade is D";
break;
case($inMes < 60):
echo "YourGrade is E";
break;
default:
break;
}
echo PHP_EOL;
}
}

?>

问题与解决:

* 退出不成功,用`var_dump($inMes)`查看发现,系统会在输入字符后加`\n`,用`trim()`函数解决
* 输入其他字符,php会把字符转换成数字,然后进行比较

思路二:把退出逻辑写在while()括号内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
$Grade = fgets(STDIN);
$sss = array("q","exit","quit");
//如果$Grade不在$sss数组中就继续执行程序
while(!in_array(trim($Grade), $sss)){
switch($Grade){
case $Grade>=90 && $Grade<100;
echo "A";
break;
case $Grade>=60 && $Grade<90;
echo "B";
break;
case $Grade<60 && $Grade>=0;
echo "C";
break;
default:
echo 'ERROR!';
}
echo PHP_EOL;
$Grade = fgets(STDIN);
}
?>

问题与解决:

* 在处理`$Grade`与`$sss`时,想另辟蹊径,在数组`$sss`里面字符后加上`\n`但始终没有成功,最终还是对`$Grade`进行`trim()`处理。