Java:编写递归函数,检查一位数字是否为偶数,另一位数字是否为偶数

ca1c2owp  于 2023-01-15  发布在  Java
关注(0)|答案(5)|浏览(134)

我正在做一个练习。我需要写一个递归函数来检查一个数字是奇数还是偶数,它需要在任何数字中切换。
例如,

  • 123为真(3为奇数,2为偶数,1为奇数)
  • 1234也是真的
  • 12354为假(4为偶数,5为奇数,3为奇数)

数字必须在偶数和奇数之间交替。
如果数字只有一位,则返回true。所有数字都是正数。
下面是我写的函数,我找不到我的错误在哪里:/

//Assumption : num > 0
//this function will return if true or not if number is alternating
public static boolean isAlternatingNumber(int num) {
    boolean flag;
    if(num < 10) {
        return true;
    }
    else {
        flag =  isAlternatingNumber(num/10);
        int n = num% 10;
        if(num%10 % 2 == 0 && flag) {
            return true;
        }else {
            return false;
        }
    }
}
mhd8tkvw

mhd8tkvw1#

假设原始函数签名public static boolean isAlternatingNumber(int num)无法更改,则可以通过使用recursive helper function向递归函数添加额外参数来解决此问题。
下面是一个示例,说明如何使用recursive helper function来解决这个问题;

class Main {  
  public static void main(String args[]) { 
    System.out.println("123: " + isAlternatingNumber(123)); // true
    System.out.println("1234: " + isAlternatingNumber(1234)); // true
    System.out.println("12354: " + isAlternatingNumber(12354)); // false
  }
  
  // Original function with unmodified signature
  public static boolean isAlternatingNumber(int num) {
    // Base case, returns true if num is only 1 digit
    if (num < 10) {
        return true;
    }
    
    /*
        + First argument; num with its first digit "sliced" (if num is 123, num / 10 is 12)
        + Second argument; Whether or not if the first digit of num is even (if num is 123,
        (num % 10) % 2 == 0 is false, as (num % 10) gives 3, and 3 % 2 is 1, as 3 is an odd number)
    */
    return findIfAlternating((num / 10), (num % 10) % 2 == 0);
  }

  /**
  * Recursive helper function to find if a given number is alternating
  * between odd and even (or vice versa) digits
  * @param num number to be checked, without its first digit
  * @param isCurrentDigitEven whether or not if the first digit of the number to be checked is even
  */
  public static boolean findIfAlternating(int num, boolean isCurrentDigitEven) {
    boolean isNextDigitEven = (num % 10) % 2 == 0;
    
    // Base case, returns true if the digits are alternating between odd and even
    if (num < 10) {
        return (isCurrentDigitEven ^ isNextDigitEven); // ^ is the XOR operator in Java, returns true if either one of the variables are true, and returns false if both variables are false or true
    }  
    
    return (isCurrentDigitEven ^ isNextDigitEven) && findIfAlternating((num / 10), isNextDigitEven);
  }
}
luaexgnf

luaexgnf2#

这个问题实际上可以被认为是算法问题,这会吸引更多的注意力、有趣的实现、React、建议等等。
由于OP提供了非常接近正确的解决方案,任何一个修正导致工作算法。我只是张贴可能的评价OP的想法。

public static boolean isAlter(int num, boolean isPrevEven) 
{
    int next = (num - num % 10) / 10;
    boolean isCurrEven = num % 2 == 0;
    boolean isOk = (isCurrEven && !isPrevEven) || (!isCurrEven && isPrevEven);

    if (isOk) 
         return next == 0 || isAlter(next, isCurrEven);
    else return false;
}

在这个问题上,更有趣的是对可接受的算法有什么要求?例如,* 时间限制、内存使用限制、数据大小 * 或mb any big-o复杂度限制。
递归算法通常可以用迭代的方式重写,这通常也会导致时间/内存消耗的改善。然而,递归是优雅的,如果它不与需求或效率相矛盾,那就没什么不好的。只要记住正确的 * 基本情况 *,这样递归就不会无限,这会导致StackOverflow错误。
PS:如果方法只接受一个参数,这肯定不是一个问题:

public boolean isAlternatingNumber(int num) 
{
    boolean isEven = num % 2 == 0;
    return isAlter(num, !isEven);
}
v6ylcynt

v6ylcynt3#

正则表达式的拯救:

public static boolean isAlternatingNumber(int num) {
    return !("" + num).matches(".*([02468]{2}|[13579]{2}).*");
}
esbemjvw

esbemjvw4#

我写的函数,我找不到我的错误在哪里

flag =  isAlternatingNumber(num/10);

方法isAlternatingNumber一直调用自身,直到num小于10。
例如,如果我们最初使用数字123调用方法isAlternatingNumber,那么将有三次对该方法的调用,如下所示:

isAlternatingNumber(123);
isAlternatingNumber(12);
isAlternatingNumber(1);

最后一个调用将返回 true
然后,在倒数第二个调用中,该方法将继续,即执行以下行:

if(num%10 % 2 == 0 && flag)

注意,局部变量n从未被使用过,所以这一行实际上并不影响isAlternatingNumber方法返回的值:

int n = num % 10;

只要num是奇数,方法isAlternatingNumber就会返回 false,然后每个递归调用都会返回 false
对于交替为偶数/奇数的数字的最后两位,要么该数字为偶数,除以10的数字为奇数,要么相反(除非该数字小于10,这被视为“正确”),即

(num % 2 == 0 && (num / 10) % 2 == 1) || (num % 2 == 1 && (num / 10) % 2 == 0) || num < 10

如果上述表达式返回true(并且num大于10),则对num / 10重复上述步骤。

public static boolean isAlternatingNumber(int num) {
    if (num < 10) {
        return true;
    }
    else {
        int rem1 = num % 2;
        int rem2 = (num / 10) % 2;
        boolean flag = ((rem1 == 0 && rem2 == 1) || (rem1 == 1 && rem2 == 0));
        return flag && isAlternatingNumber(num / 10);
    }
}

如果rem1rem2具有相同的值,则flag为真。

return flag && isAlternatingNumber(num / 10);

如果flag为false,Java将不会[递归地]调用方法isAlternatingNumber

mklgxw1f

mklgxw1f5#

对于递归求解,用true/false ets递归检查最后一位数就足够了。每次递归时,删除值的最后一位数。

public static boolean isAlternatingNumber(int num) {
    boolean lastDigitEven = num % 10 % 2 == 0;
    return isAlternatingNumber(num, lastDigitEven);
}

private static boolean isAlternatingNumber(int num, boolean expectedLastDigitEven) {
    if (num == 0)
        return true;

    boolean lastDigitEven = num % 10 % 2 == 0;

    if (lastDigitEven == expectedLastDigitEven)
        return isAlternatingNumber(num / 10, !lastDigitEven);

    return false;
}

相关问题