我需要编写一个递归函数,如果整数的数字从左到右递增,则返回1;如果递减,则返回-1;否则则返回0。
我的解决方案尝试每次都返回0,我知道为什么,但是我不知道如何解决它。
这是我的代码:
#include <stdio.h>
int check_order(int n)
{
if (n % 10 > n / 10 % 10)
{
return check_order(n / 10);
if (n == 0)
{
return 1;
}
}
else if (n % 10 < n / 10 % 10)
{
return check_order(n / 10);
if (n == 0)
{
return -1;
}
}
else
{
return 0;
}
}
int main()
{
int n;
printf("enter a whole number (n > 9):");
scanf_s("%d", &n);
printf("function returned: %d\n", check_order(n));
}
答案 0 :(得分:0)
在return
语句之后的代码无法访问:
return check_order(n / 10);
if (n == 0)
{
return -1;
}
除此之外,您在将当前数字与下一个数字进行比较的正确位置上,但是我看不到明确的基本情况(当n < 10
,即一个数字时)。 / p>
试图用一种递归函数检查升序和降序很难管理。特别是,在堆栈帧之间传递状态并确定在给定调用中哪些情况仍然有效,则表明返回值工作过度。
为省去返回结构或使用枚举或魔术数字作为标志的麻烦,我将编写两个常规的辅助函数ascending_digits
和descending_digits
。
#include <stdbool.h>
#include <stdio.h>
bool ascending_digits(int n) {
if (n < 10) return true;
if (n % 10 < n / 10 % 10) return false;
return ascending_digits(n / 10);
}
bool descending_digits(int n) {
if (n < 10) return true;
if (n % 10 > n / 10 % 10) return false;
return descending_digits(n / 10);
}
int check_order(int n) {
if (ascending_digits(n)) return 1;
if (descending_digits(n)) return -1;
return 0;
}
int main() {
printf("12345: %d\n", check_order(12345));
printf("54321: %d\n", check_order(54321));
printf("54323: %d\n", check_order(54323));
printf("454321: %d\n", check_order(454321));
printf("1: %d\n", check_order(1));
printf("12: %d\n", check_order(12));
printf("21: %d\n", check_order(21));
return 0;
}
输出:
12345: 1
54321: -1
54323: 0
454321: 0
1: 1
12: 1
21: -1
这些功能不仅更易于理解和单独维护,而且与密不可分地捆绑在一起相比,它们也更具可重用性。
这不处理负数-如果需要,您可以申请abs
并从那里去。处理相等的值也是如此;此实现接受诸如1223
之类的数字,但是您可以使用<=
来执行严格的排序。
答案 1 :(得分:0)
请解释您的算法?
假设您使用以下内容:
我们可以使用字符串来简化数字比较,并接受很长的数字序列。
我们可以使用枚举类型来表示顺序。
您如何合并结果?定义一个将两个相邻重叠对的顺序组合在一起的函数,然后就可以组合结果。
#include <stdio.h>
#include <string.h>
typedef enum { descending=-1, other=0, ascending=1 } order_t;
order_t pair_order(int a, int b) {
if( a < b ) return ascending;
if( a > b ) return descending;
return other;
}
//strict (increasing/decreasing)
order_t strict_order( order_t x, order_t y ) {
if( x == y ) return x;
return other;
}
//monotone (increasing/decreasing)
order_t monotone_order( order_t x, order_t y ) {
if( x == y ) return x;
if( other == x ) return y;
if( other == y ) return x;
return other;
}
order_t check_order( char* p, int remain ) {
//printf("p:%s\n",p); //uncomment to watch progress
if( remain<2 ) return other;
if( remain==2 ) return pair_order(p[0], p[1]);
return strict_order( pair_order(p[0], p[1]), check_order(p+1, remain-1) );
//return monotone_order( pair_order(p[0], p[1]), check_order(p+1, remain-1) );
}
char* order_name[] = {
"descending",
"other",
"ascending"
""
};
int main()
{
char line[666] = "none";
while ( strlen(line) > 0 ) {
printf("enter a number (at least 2 digits):");
fgets(stdin,line,sizeof(line)-1);
if( strlen(line) > 0 && line[strlen(line)-1] == '\n' )
line[strlen(line)-1] = '\0';
order_t order = check_order(line);
printf("function returned: (%d)%s\n", order, order_name[order+1]);
}
}
答案 2 :(得分:0)
我认为您是从正确的道路开始的,但需要进一步完善代码。我的解决方案借用@ChuckCottrill的方法,因为我喜欢他的enum
,但我不喜欢他不打球(即转换为字符串而不是处理int
) 。)我还借用了@ggorlen的漂亮测试示例,但我也不喜欢这种解决方案,因为当只需要一次通过时,它可能需要多次通过数字才能找出答案:
#include <stdio.h>
typedef enum { descending=-1, other=0, ascending=1 } order_t; // a la @ChuckCottrill
order_t check_order(int n)
{
if (n > 9) {
int right = n % 10;
int left = n / 10 % 10;
if (right > left) {
n /= 10;
if (n > 9) {
return (ascending == check_order(n)) ? ascending : other;
}
return ascending;
}
if (right < left) {
n /= 10;
if (n > 9) {
return (descending == check_order(n)) ? descending : other;
}
return descending;
}
}
return other;
}
int main() { // a la @ggorlen
printf("12345: %d\n", check_order(12345));
printf("54321: %d\n", check_order(54321));
printf("54323: %d\n", check_order(54323));
printf("454321: %d\n", check_order(454321));
printf("1: %d\n", check_order(1));
printf("12: %d\n", check_order(12));
printf("21: %d\n", check_order(21));
}
输出
> ./a.out
12345: 1
54321: -1
54323: 0
454321: 0
1: 0
12: 1
21: -1
>
答案 3 :(得分:0)
该版本可以使用任何长度,因为它将字符串作为参数。 并且以递归状态(递归或递减)的形式递归函数可以使代码更短,功能更少。
int check_order(char *str, int index, int previous) {
char current = str[index]; // char at index
char next = str[index+1]; // char at index+1
if (current == 0 || next == 0) {
return previous; // End of string
}
// Ascending or descending?
int status = next > current ? 1 : (next < current ? -1 : 0);
if (status == 0 || index > 0 && status != previous) {
// If neither -1/1 nor status == previous (while not initial call)
return 0;
}
return check_order(str, index+1, status); // Check from next index
}
main 函数必须确保字符串至少为2个字符
int main(int argc, char **argv) {
char *str = *++argv;
// Some optional checks on str here... (like this is a number)
int status = 0; // Default value if string length < 2
if (strlen(str) >= 2) {
status = check_order(str, 0, 0);
}
printf("Check order for %s is %d\n", str, status);
return 0;
}
答案 4 :(得分:0)
这是一个简单的递归:
int f(int n){
if (n < 10)
return 0;
int dr = n % 10; // rightmost digit
n = n / 10;
int dl = n % 10; // second digit from the right
int curr = dl < dr ? 1 : -1; // current comparison
if (dl == dr) curr = 0; // keep strict order
if (n < 10)
return curr;
return curr == f(n) ? curr : 0; // are the comparisons consistent?
}