这个程序功能很简单,但具体要求非常多。考虑到程序的严谨性所以要针对所有可能出现的情况进行处理。第一次进行test cases测试的时候一大半的test cases都没有通过,进行分析修改后以下程序通过所有的test cases. 因为限制只能用部分C的function,所以要求较高的逻辑思维能力。
这个程序看似很难看,用了很多个相套的if statement.
如果需要具体的程序说明文档和test cases请与我联系。
#include <stdio.h>
#include <limits.h>
/* Specify the priority of error message */
#define INVALID_SYNTAX 5;
#define OVERFLOW 4;
#define IMPOSSIBLE_TIME 3;
#define END_BEFORE_START 2;
#define AMBIGUOUS 1;
int main(void)
{
int c; /* read a character one by one and save it into c */
int length; /* length of the number */
char s[1000]; /* the string used to save the input number */
unsigned long long start_time, end_time; /* variables used to store the atart time and end time */
int message_number; /* store the defined message number, decide which message should be displayed */
int first_ambi, second_ambi; /* check if the first and second numbers are ambiguous */
while((c = getchar()) != EOF)
{
length = 0; /************************/
start_time = 0; /* */
end_time = 0; /* initialize variables */
message_number = 0; /* */
first_ambi = 1; /* */
second_ambi = 1; /************************/
while(c == ' ' || c == '\t' || c == '\0')
c = getchar(); /* remove the leading space, tab or \0 */
/* if the first input character is a digit */
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
{
s[length] = c;
length++;
int check = 1;
/* get the first input number */
while(check != 0 && (c = getchar()) != EOF)
{
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
{
s[length] = c;
length++;
}
else
check = 0;
}
int i;
/* convert the string to a decimal number */
for(i = 0; i < length; i++)
{
unsigned long long temp_number = s[i] - 48;
if(i == length - 1)
start_time = start_time + s[i] - 48;
else
{
int x;
for(x = i; x < length - 1; x++)
temp_number = temp_number * 10;
start_time = temp_number + start_time;
}
}
/* check if the number overflow */
if(start_time > UINT_MAX)
{
if(message_number < 4)
message_number = OVERFLOW;
}
/* If the number ends with white space, which means no "am" or "pm".
We have to check if the number is from 0 to 23 */
if(c == ' ' || c == '\t' || c == '\0')
{
if(start_time != 0 && start_time <= 12)
first_ambi = 0;
if(start_time > 24)
{
if(message_number < 3)
message_number = IMPOSSIBLE_TIME;
}
if(start_time == 12)
start_time = 0; /*12 can be 12am and 12pm, now we let start_time be 12am */
}
/* when the number ends with "am" */
else if(c == 'a')
{
if((c = getchar()) == 'm')
{
/* check if the number which ends with "am" is greater than 12 or equals to 0 */
if(start_time > 12 || start_time == 0)
{
if(message_number < 3)
message_number = IMPOSSIBLE_TIME;
}
/* 12am means midnight */
if(start_time == 12)
start_time = 0;
}
else
message_number = INVALID_SYNTAX;
}
/* when the number ends with "pm" */
else if(c == 'p')
{
if((c = getchar()) == 'm')
{
/* check if the number which ends with "pm" is greater than 12 or equals to 0 */
if(start_time > 12 || start_time == 0)
{
if(message_number < 3)
message_number = IMPOSSIBLE_TIME;
}
/* 12pm means noon */
else if(start_time == 12)
;
else
start_time = start_time + 12;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
/* if the first input character is 'n', we want to check if it is followed by "oon" */
else if(c == 'n')
{
if((c = getchar()) == 'o')
{
if((c = getchar()) == 'o')
{
if((c = getchar()) == 'n')
{
if((c = getchar()) == '\0' || c == ' ' || c == '\t') /* the end of string "noon" */
{
start_time = 12;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
/* if the first input character is 'm', we want to check if it is followed by "idnight" */
else if(c == 'm')
{
if((c = getchar()) == 'i')
{
if((c = getchar()) == 'd')
{
if((c = getchar()) == 'n')
{
if((c = getchar()) == 'i')
{
if((c = getchar()) == 'g')
{
if((c = getchar()) == 'h')
{
if((c = getchar()) == 't')
{
if((c = getchar()) == '\0' || c == ' ' || c == '\t') /* the end of string "midnight" */
{
start_time = 0;
first_ambi = 1;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;

length = 0; /* initialize variable */
if(c != '\n')
{
/* check if there is no white space after the start time */
if((c == 'm'||c == 't'||c == 'n') && (c = getchar()) != ' ' && c != '\t' && c != '\0')
message_number = INVALID_SYNTAX;
/* remove the white space after the start time */
while(c == ' ' || c == '\t' || c == '\0')
c = getchar();
}
/* if the second input character is a digit */
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
{
s[length] = c;
length++;
int check = 1;
/* get the second input number */
while(check != 0 && (c = getchar()) != EOF)
{
if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
{
s[length] = c;
length++;
}
else
check = 0;
}
int i;
/* convert the string to a decimal number */
for(i = 0; i < length; i++)
{
unsigned long long temp_number = s[i] - 48;
if(i == length - 1)
end_time = end_time + s[i] - 48;
else
{
int x;
for(x = i; x < length - 1; x++)
temp_number = temp_number * 10;
end_time = temp_number + end_time;
}
}
/* check if the number overflow */
if(end_time > UINT_MAX)
{
if(message_number < 4)
message_number = OVERFLOW;
}
/* If the number ends with white space, which means no "am" or "pm".
We have to check if the number is from 0 to 23 */
if(c == ' ' || c == '\t' || c == '\n' || c == '\0')
{
if(end_time <= 12)
second_ambi = 0;
if(end_time > 24)
{
if(message_number < 3)
message_number = IMPOSSIBLE_TIME;
}
}
/* when the number ends with "am" */
else if(c == 'a')
{
if((c = getchar()) == 'm')
{
/* check if the number which ends with "am" is greater than 12 or equals to 0 */
if(end_time > 12 || end_time == 0)
{
if(message_number < 3)
message_number = IMPOSSIBLE_TIME;
}
/* 12am means midnight */
if(end_time == 12)
{
end_time = 24;
second_ambi = 0;
}
}
else
message_number = INVALID_SYNTAX;
}
/* when the number ends with "pm" */
else if(c == 'p')
{
if((c = getchar()) == 'm')
{
/* check if the number which ends with "pm" is greater than 12 or equals to 0 */
if(end_time > 12 || end_time == 0)
{
if(message_number < 3)
message_number = IMPOSSIBLE_TIME;
}
/* 12pm means noon */
else if(end_time == 12)
;
else
end_time = end_time + 12;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
/* if the first input character is 'n', we want to check if it is followed by "oon" */
else if(c == 'n')
{
if((c = getchar()) == 'o')
{
if((c = getchar()) == 'o')
{
if((c = getchar()) == 'n')
{
if((c = getchar()) == '\0' || c == ' ' || c == '\t' || c == '\n') /* the end of string "noon" */
{
end_time = 12;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
/* if the first input character is 'm', we want to check if it is followed by "idnight" */
else if(c == 'm')
{
if((c = getchar()) == 'i')
{
if((c = getchar()) == 'd')
{
if((c = getchar()) == 'n')
{
if((c = getchar()) == 'i')
{
if((c = getchar()) == 'g')
{
if((c = getchar()) == 'h')
{
if((c = getchar()) == 't')
{
if((c = getchar()) == '\0' || c == ' ' || c == '\t' || c == '\n') /* the end of string "midnight" */
{
end_time = 24;
second_ambi = 0;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
}
else
message_number = INVALID_SYNTAX;
/* if the two times are definite, we do not have to check if they are ambiguous.
Just check if the time end before start*/
if((first_ambi == 1 || start_time > 12) && (second_ambi == 1 || (end_time > 12 && end_time != 24)))
{
if(end_time < start_time && message_number < 2)
message_number = END_BEFORE_START;
}
/* if the first time is definite but the second time is ambiguous,
the time interval may be ambiguous */
else if((first_ambi == 1 || start_time >= 12) && (second_ambi == 0 && (end_time <= 12 || end_time == 24)))
{
if(start_time == 0 && (end_time == 0 || end_time == 24) && message_number < 1)
message_number = AMBIGUOUS;
if((start_time < end_time) && end_time != 24)
{
if(message_number < 1)
message_number = AMBIGUOUS;
}
else
{
if(end_time <= 12)
end_time = end_time + 12;
if(end_time < start_time && message_number < 2)
message_number = END_BEFORE_START;
}
}
/* if the first time is ambiguous but the second time is definite,
the time interval may be ambiguous */
else if((first_ambi == 0 && start_time <= 12) && (second_ambi == 1 || end_time > 12))
{
if(start_time + 12 < end_time)
{
if(message_number < 1)
message_number = AMBIGUOUS;
}
if(end_time < start_time && message_number < 2)
message_number = END_BEFORE_START;
}
/* When the two times are both ambiguous, we have to check if there is only one pair of times
that can be calculated */
else if((first_ambi == 0 && start_time <= 12) && (second_ambi == 0 && (end_time <= 12 || end_time == 24)))
{
if(start_time == 0 && (end_time == 0 || end_time == 24) && message_number < 1)
message_number = AMBIGUOUS;
if(start_time >= end_time)
end_time = end_time + 12; /* if end_time + 12, then end_time must be greater than start_time */
else if((start_time < end_time) && message_number < 1)
message_number = AMBIGUOUS;
}
/* if the input time ends with 'm', read one more character */
if(c == 'm')
c = getchar();
while(c != '\n')
{
/* when the input contains something else except the white space after the second time,
print error message*/
if(c != '\t' && c != ' ' && c != '\0')
message_number = INVALID_SYNTAX;
c = getchar();
}
/* One message should be print. That depends on the specified priority */
if(message_number == 5)
printf("invalid syntax\n");
else if(message_number == 4)
printf("overflow\n");
else if(message_number == 3)
printf("impossible time\n");
else if(message_number == 2)
printf("end before start\n");
else if(message_number == 1)
printf("ambiguous\n");
else
printf("%d\n", end_time - start_time); /* printf the number of hours worked */
}
return 0;
}


浙公网安备 33010602011771号