在Java中递归地对数字的数字进行排序

时间:2018-02-27 17:16:43

标签: java algorithm sorting recursion

我对编程非常陌生,只是在大学里学到了它。我有一个任务,我必须在java中递归地解决这个问题(不使用数组,if,else,while等等)

所以任务是将数字从13542到12345进行排序。

public static void main(String[] args) {
    System.out.println(sort(13542));

}

public static long sort(long n) {
    return n < 10
            ? n
            : sort(n, 0);
}

public static long sort(long n1, long n2) {
    return n1 > 10
            ? xxx
            : xxx;
}

问题在于我不知道该怎么做。我认为我的开始没问题,但我对第二种方法有疑问。

5 个答案:

答案 0 :(得分:2)

首先,递归意味着简单地说,你有一些东西反复调用。赋值是递归的事实暗示了你的讲师希望你如何使用递归方法来解决它。

暂时忽略主要部分,因为虽然它可以被打扮得更加优雅,但这不是问题的核心。

public int recursiveSort(int toSort){

}

为了整洁,我们需要一种方法来检查它是否已排序,并进行排序。

public Boolean isSorted(int toCheck){
    //TODO: Check if input is sorted
}

public int singleSort(int toSort){
    //TODO: Sorting algorithm
}

这为我们提供了递归方法

public int recursiveSort(int toSort){
    toSort = singleSort(toSort);
    return isSorted(toSort) ? toSort : recursiveSort(toSort);
}

施加约束的排序是棘手的部分,并且取决于你不能使用的确切内容 当然,请尝试查看different sorting algorithms并考虑在这种情况下如何实现它们。

答案 1 :(得分:1)

每个递归方法都应该包含2个主要&#34;成分&#34;:

  1. 终止条件
  2. 向前迈进
  3. 正如您所提到的,明显的终止条件是数字只有1位数,这意味着它已经排序(因此递归应该停止)。

    该方法的必要进展是在每次运行中删除一个数字,对较小的数字进行排序,然后将数字合并在一起。
    如您所知,实际的挑战可以是正确合并,也可以有效分离。

    我选择找到最大数字,将其从原始数字中删除,然后将新创建的数字发送回递归函数。最终,该方法将排序的数字与其右侧的最大数字合并。

    public static void main(String[] args) {
        System.out.println(sort(13542));
    }
    
    public static long sort(long n) {
        // For testing purposes:
        // System.out.println("sort(" + n + ")");
    
        if (n < 10) return n;   // Termination condition
    
        int numOfDigits = (int)(Math.log10(n)+1);
        long largestDigit = n % 10;
        long restOfDigits = n / 10;
    
        for(int i=0; i<numOfDigits; i++) {
            long current = (long) (n / Math.pow(10, i)) % 10;
            if (current > largestDigit) {
                largestDigit = current;
                restOfDigits = (long) Math.pow(10, i) * (n / (long) Math.pow(10, i + 1))
                        + (n % (long) Math.pow(10, i));
            }
        }
    
        // Merge the largest number on the right
        return 10 * sort(restOfDigits) + largestDigit;
    }
    

    正如您所看到的,出于测试目的,最好在其开头检查递归方法。您可以打印或使用调试器来查看其进展。

答案 2 :(得分:1)

在其最简单的形式中,递归正在反复调用方法。这是一个简单的例子。

public void eatAllFoodFromTable(Table tbl, Person prsn) {

    if(tbl.hasFood()) {

        prsn.sustain(1);
        tbl.removeFood(1);
        eatAllFoodFromTable(tbl, prsn); /*As you can see here,
            the method calls itself. However, because the method has a condition
            that can prevent it from running indefinitely (or a way to terminate),
            it will repeat until the condition is met, then terminate. This is recursion!*/

    } else {
        //Do nothing.
    }

}

您要做的就是花费很长时间,然后将其输入名为sort的方法或类似方法。然后,该方法将检查其中某些是否按顺序(通过某种迭代),然后再次使用从排序迭代生成的新long调用自身(sort())。

到达排序点后,方法将终止,返回最终的排序值。

答案 3 :(得分:1)

这是一个带有一个函数和一个参数的纯递归;没有日志,电源,字符串转换或循环。我说这是一个非常困难的递归练习,即使不仅仅是初学者。我希望这有帮助。随意要求任何澄清。 (也欢迎简化。)

JavaScript代码:

function main() {
  console.log(sort(13542));
}

function sort(n) {
  if (n < 10)
    return n;
  
  let r = n % 10;
  let l = (n - r) / 10 % 10;

  let sorted = sort(Math.floor(n / 10) - l + r);
  let last = sorted % 10;
    
  if (l < last)
    return 10 * sort(sorted - last + l) + last;
  else 
    return 10 * sorted + l;
}

main();

答案 4 :(得分:0)

非常感谢您的帮助。我想我现在明白了:

public static long sort(long n) {
    return n < 10
            ? n
            : shuffle(sort(n / (long) Math.pow(10, count(n) / 2)),
                    sort(n % (long) (Math.pow(10, count(n) / 2))));
}

public static long count(long n) {
    return n < 10
            ? 1
            : 1 + count(n / 10);
}

public static long shuffle(long n1, long n2) {
    return (n1 > 0 || n2 > 0)
            ? (n1 % 10 > n2 % 10)
                    ? shuffle(n1 / 10, n2) * 10 + n1 % 10
                    : shuffle(n1, n2 / 10) * 10 + n2 % 10
            : 0;
}

可悲的是,我们不允许使用if,else或while。这本来会容易得多。但是,谢谢大家:)