【问题标题】:Compare Array of Strings and return the smallest one比较字符串数组并返回最小的一个
【发布时间】:2019-03-04 19:24:31
【问题描述】:

我正在实现一个代码来比较 StringsArray 并使用 stringONE.compareTo(stringTwo) 返回最小的一个。

代码将使用递归来交替使用 Array 而不是 for 循环。

  • 我实现了代码,让 compare 方法不断地用不同的参数调用自己,直到它到达 Array 的末尾,然后异常处理将退出递归。

    问题在于:它一直​​在迭代直到达到堆栈溢出而没有触发outofboundsException

下面是我的代码,你可以测试一下:

代码:

public class recursivefindMinimum {
    public static String [] stringArray = {"delta","alpha","omega","zeta"};
    public static String result;

    public static void main (String[]args) {
        System.out.println("result :  "+findMinimum(stringArray, 0, 1));
    }

    public static String findMinimum(String[] stringArray, int index1, int index2) {
        int number = stringArray[index1].compareTo(stringArray[index2]);

        if (number< 0) {
            findMinimum(stringArray,index1,index2++); zebobi="delta1";
        }
        else if (number> 0) {
            findMinimum(stringArray,index2,index2++);zebobi="delta2";
        }
        else if (number== 0) {
            findMinimum(stringArray,index1,index2++);zebobi="delta3";
        }
    } catch(Exception e) {
        System.out.println(index1);
        System.out.println(index2);
        result= stringArray[index1]

        return result;
    }
}

【问题讨论】:

  • 欢迎来到 SO!这将无法编译:您缺少分号并且不能在没有try 的情况下使用catch。我还建议将全局变量放在 main 范围内。

标签: java arrays string recursion compareto


【解决方案1】:

在递归中,您必须始终有一个基本情况,这是您停止递归的地方。目前,您对每个可能的结果都有递归案例:

if (number< 0){
     findMinimum(stringArray,index1,index2++); zebobi="delta1";
}
else if (number> 0){
     findMinimum(stringArray,index2,index2++);zebobi="delta2";
}
else if (number== 0){
     findMinimum(stringArray,index1,index2++);zebobi="delta3";
}

(当number 小于、大于或等于零时)因此您的方法将始终调用自身,这是无限递归。您需要包含一个将停止递归的基本案例

另外,最好将result 设为仅在findMinimum() 范围内声明的变量。然后您需要将递归调用更改为result = findMinimum(...)

此问题的基本情况是索引变量之一超出范围。

public static String findMinimum(String[] stringArray, int index1, int index2) 
{
    String result = "";
    if(index1 > stringArray.length || index2 > stringArray.length-1) {
        return stringArray[index2-1];
    }

    int number = stringArray[index1].compareTo(stringArray[index2]);


    if (number< 0){
        result = findMinimum(stringArray,index1,index2+1); zebobi="delta1";
    }
    else if (number> 0){
        result = findMinimum(stringArray,index2,index2+1);zebobi="delta2";
    }
    else if (number== 0){
        result = findMinimum(stringArray,index1,index2+1);zebobi="delta3";
    }

    return result;
 }

如果你试图触发一个异常然后从异常块中返回:

-你需要添加一个try 块(你不能不尝试就捕获)

-你需要通过index2 + 1而不是index2++

-你需要返回stringArray[index2]而不是stringArray[index1]

public static String findMinimum(String[] stringArray, int index1, int index2) 
{
    String result;
    int number = stringArray[index1].compareTo(stringArray[index2]);

    try {
        if (number< 0){
        result = findMinimum(stringArray,index1,index2+1); zebobi="delta1";}

        else if (number> 0){
        result = findMinimum(stringArray,index2,index2+1);zebobi="delta2";}

        else if (number== 0){
        result = findMinimum(stringArray,index1,index2+1);zebobi="delta3";}

    }catch(Exception e){
        System.out.println(index1);
        System.out.println(index2);
        result= stringArray[index2]; 
    }
    return result;
}

输出:

result :  zeta

【讨论】:

  • 我现在明白了。我认为 outofboundsException 将停止更改。但是,当异常处理完成时,它会返回到原来的位置。我想知道我应该使用什么作为基本案例
  • 你仍然需要声明结果(或者直接在任何地方返回)。另外,catch 块中的 return 似乎是多余的
  • @StefanHaustein OP 将result 声明为static 变量。感谢您对冗余返回语句的建议。我删除了它
  • 呃...静态结果你不需要 if 分支中的分配... O:)
  • 如果结果是静态的,这意味着只有一个值可以在任何地方共享。所以只要在递归函数中赋值,就可以在函数外访问,不需要返回。通常,人们希望函数尽可能地隔离——如果可行的话,只对输入进行操作并返回结果(与写入全局状态相反),因为这样可以确保函数可以很容易地在其他上下文中重用并且推理关于函数可以限定为函数
【解决方案2】:

这是另一种可能的解决方案,可以避免这些索引问题:

public static String findMinimumRecursive(String[] array, String currentMinString){
  if(array.length == 0)
    return currentMinString;

  return findMinimumRecursive(
              Arrays.copyOfRange(array, 1, array.length), 
              ((Integer)currentMinString.length()).compareTo(array[0].length()) < 0 ? currentMinString : array[0]);
}

然后你可以像这样调用这个函数:

String[] arr = {"abc", "abcd", "ab", "abe"};
String result = findMinimumRecursive(Arrays.copyOfRange(arr, 1, arr.length), arr[0]);

此函数将使用数组的第一个元素评估当前最小长度的字符串,并且每次它都会使用相同的数组调用自身,其中移除了评估的元素和当前的最小字符串。 停止条件是输入数组为空,它将只返回当前最小长度字符串,该字符串对应于数组中所有字符串的最小长度

调用将如下所示:

  1. findMinimumRecursivly(["abcd", "ab", "abe"], "abc")
  2. findMinimumRecursivly(["ab", "abe"], "abc")
  3. findMinimumRecursivly(["abe"], "ab")
  4. findMinimumRecursivly(["abe"], "a")
  5. findMinimumRecursivly([], "a")

请注意,方法 Arrays.copyOfRange 创建一个数组,其元素与第一个参数相同,但仅从第二个和第三个参数的开始和结束索引开始 - 请参阅https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#copyOfRange(T[],%20int,%20int)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    相关资源
    最近更新 更多