几个cmets:
- 我认为最好对代码进行一些结构化,使其更易于管理,例如将程序的主控件与检测升序、降序、升序_然后_降序等功能分开。
- 在我看来,使用 string/char * 来检查升序、降序等似乎更容易,而不是使用数学运算(通过利用 '0' - '9' 字符作为 ASCII)。
以下示例将仅提供检查升序、降序等功能。请注意,以下代码中的定义使用left-to-right 作为序列(正常情况下)。因此,对于您的right-to-left 规则,字符串在处理之前将是reversed。
使用字符串的好处是,也可以通过反转字符串来切换升序或降序的逻辑。不确定您是否有严格的规则,只允许使用整数进行处理。
样本输出:
N: 1234, F: 0, Return value: 0, Expected: 0
N: 4321, F: 0, Return value: 1, Expected: 1
N: 1234, F: 1, Return value: 1, Expected: 1
N: 4321, F: 1, Return value: 0, Expected: 0
N: 12341, F: 2, Return value: 1, Expected: 1
N: 412341, F: 2, Return value: 0, Expected: 0
N: 96589, F: 2, Return value: 0, Expected: 0
N: 96589, F: 3, Return value: 1, Expected: 1
N: 12341, F: 3, Return value: 0, Expected: 0
代码:
#include <stdio.h>
#include <string.h>
int is_ascending(char *str, int currentIdx, int prevChar);
int is_descending(char *str, int currentIdx, int prevChar);
int is_ascending_then_descending(char *str, int currentIdx, int prevChar, char whichMode);
int is_descending_then_ascending(char *str, int currentIdx, int prevChar, char whichMode);
//===================== Helper Function ======================
void inplace_reverse(char *str);
char* my_itoa(int val, int base);
int main() {
int RetVal=-1, Expected = -1;
int N=0, F=0;
//Ascending
N = 1234, F=0, Expected = 0;
char *input1 = my_itoa(N, 10);
inplace_reverse(input1);
RetVal = is_ascending(input1, 0, 0);
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
N = 4321, F=0, Expected = 1;
char *input2 = my_itoa(N, 10);
inplace_reverse(input2);
RetVal = is_ascending(input2, 0, 0);
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
//Descending
N = 1234, F=1, Expected = 1;
char *input3 = my_itoa(N, 10);
inplace_reverse(input3);
RetVal = is_descending(input3, 0, 0);
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
N = 4321, F=1, Expected = 0;
char *input4 = my_itoa(N, 10);
inplace_reverse(input4);
RetVal = is_descending(input4, 0, 0);
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
//Ascending & then Descending
N = 12341, F=2, Expected = 1;
char *input5 = my_itoa(N, 10);
inplace_reverse(input5);
RetVal = is_ascending_then_descending(input5, 0, 0, 'a');
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
N = 412341, F=2, Expected = 0;
char *input6 = my_itoa(N, 10);
inplace_reverse(input6);
RetVal = is_ascending_then_descending(input6, 0, 0, 'a');
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
N = 96589, F=2, Expected = 0;
char *input7 = my_itoa(N, 10);
inplace_reverse(input7);
RetVal = is_ascending_then_descending(input7, 0, 0, 'a');
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
//Descending & then Ascending
N = 96589, F=3, Expected = 1;
char *input8 = my_itoa(N, 10);
inplace_reverse(input8);
RetVal = is_descending_then_ascending(input8, 0, 999, 'd');
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
N = 12341, F=3, Expected = 0;
char *input9 = my_itoa(N, 10);
inplace_reverse(input9);
RetVal = is_descending_then_ascending(input9, 0, 999, 'd');
printf("N: %d, F: %d, Return value: %d, Expected: %d\n", N, F, RetVal, Expected);
return 0;
}
// ========================= Main Functionality ==========================
//Return 1 if str is Ascending from left to right; otherwise return 0
int is_ascending(char *str, int currentIdx, int prevChar) {
char current = str[currentIdx];
if (current == '\0') {
return 1;
} else {
if (current > prevChar) {
return is_ascending(str, currentIdx+1, current);
} else {
return 0;
} //end else
} //
}
//Return 1 if str is Descending from left to right; otherwise return 0.
//Re-use the 'is_asscending' function by reversing the string first
int is_descending(char *str, int currentIdx, int prevChar) {
inplace_reverse(str);
return is_ascending(str, currentIdx, prevChar);
}
//Return 1 if str is Ascending and then Descending (from left to right); otherwise return 0.
int is_ascending_then_descending(char *str, int currentIdx, int prevChar, char whichMode) {
char current = str[currentIdx];
if (current == '\0') {
return 1;
} else {
if (current > prevChar) {
if (whichMode == 'a') {
return is_ascending_then_descending(str, currentIdx+1, current, whichMode);
} else { //mode is already in Descending, but current > prevChar
return 0;
} //end else
} else { //current <= prevChar
if (whichMode == 'a') {
return is_ascending_then_descending(str, currentIdx+1, current, 'd'); //switch to descending mode
} else { //mode is already in Descending, current <= prevChar
if (current < prevChar) {
return is_ascending_then_descending(str, currentIdx+1, current, 'd');
} else { //current == prevChar
return 0;
}
} //end else
} //end else
} //
}
//Return 1 if str is Descending and then Ascending (from left to right); otherwise return 0.
int is_descending_then_ascending(char *str, int currentIdx, int prevChar, char whichMode) {
char current = str[currentIdx];
if (current == '\0') {
return 1;
} else {
if (current < prevChar) {
if (whichMode == 'd') {
return is_descending_then_ascending(str, currentIdx+1, current, whichMode);
} else { //mode is already in Ascending, but current < prevChar
return 0;
} //end else
} else { //current >= prevChar
if (whichMode == 'd') {
return is_descending_then_ascending(str, currentIdx+1, current, 'a'); //switch to ascending mode
} else { //mode is already in Ascending, current <= prevChar
if (current > prevChar) {
return is_descending_then_ascending(str, currentIdx+1, current, 'a');
} else { //current == prevChar
return 0;
}
} //end else
} //end else
} //
}
//============================= Helper Function ==============================
//reverse the given null-terminated string in place
//From: https://stackoverflow.com/questions/784417/reversing-a-string-in-c
void inplace_reverse(char *str) {
if (str) {
char *end = str + strlen(str) - 1;
// swap the values in the two given variables
// XXX: fails when a and b refer to same memory location
# define XOR_SWAP(a,b) do\
{\
a ^= b;\
b ^= a;\
a ^= b;\
} while (0)
// walk inwards from both ends of the string,
// swapping until we get to the middle
while (str < end)
{
XOR_SWAP(*str, *end);
str++;
end--;
}
# undef XOR_SWAP
}
}
char* my_itoa(int val, int base) {
static char buf[32] = {0};
int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}