【问题标题】:Needless return in recursive method递归方法中的不必要返回
【发布时间】:2018-09-18 00:22:05
【问题描述】:

我正在编写一个递归代码,计算我们需要执行的最小操作次数,以便s2 等于s1,有效操作是insert 1 character (di)delete 1 character (dc)dn stays for do nothing

private static int editDistance(String s1, String s2) {

    if((s2.isEmpty() && (dn == 0 && dc == 0 && di == 0)) || (s1.isEmpty() && (dn == 0 && dc == 0 && di == 0)))
        return Integer.max(s1.length(), s2.length());

    if(s2.isEmpty()) {
        return 0;
    } else if(s1.isEmpty()) {
        dc++;
        return 1 + editDistance(s1, rest(s2));
    } else if(s1.charAt(0) == s2.charAt(0)) {
        dn++;
        return editDistance(rest(s1), rest(s2));
    } else if(s1.charAt(0) != s2.charAt(0) && dc <= di) {
        dc++;
        return 1 + editDistance(s1, rest(s2));
    } else if(s1.charAt(0) != s2.charAt(0) && dc > di) {
        di++;
        return 1 + editDistance(rest(s1), s2);
    }

    return 0;

}

例如,如果我们有 s1 = "home" 和 s2 = "hote",将有 1 个删除操作(用于 't')、1 个插入操作('m')和 3 个无操作操作。

问题是我的语句在那些 if/else if 分支中被淘汰了,所以为了编译我的程序,我必须在底部放置一个 return 0 语句,这是没有意义的,我该如何纠正这个问题?

【问题讨论】:

    标签: java recursion return


    【解决方案1】:

    你可以通过两种方式解决这个问题:

    1. 如果您删除最后一个 if 语句可能会发生另一种可能性

      private static int editDistance(String s1, String s2) {
      
          if((s2.isEmpty() && (dn == 0 && dc == 0 && di == 0)) || (s1.isEmpty() && (dn == 0 && dc == 0 && di == 0)))
              return Integer.max(s1.length(), s2.length());
      
          if(s2.isEmpty()) {
              return 0;
          } else if(s1.isEmpty()) {
              dc++;
              return 1 + editDistance(s1, rest(s2));
          } else if(s1.charAt(0) == s2.charAt(0)) {
              dn++;
              return editDistance(rest(s1), rest(s2));
          } else if(s1.charAt(0) != s2.charAt(0) && dc <= di) {
              dc++;
              return 1 + editDistance(s1, rest(s2));
          } else if(s1.charAt(0) != s2.charAt(0) && dc > di) {
              di++;
              return 1 + editDistance(rest(s1), s2);
          }else
              return 0;
      
      }
      
    2. 如果最后一个 if 语句涵盖了所有剩余的可能性,只需将最后一个 if 语句替换为 else 关键字。

    【讨论】:

      【解决方案2】:

      删除最后一个如果。当然,只有当您的案例涵盖所有可能的变体时,您才应该这样做。有时正确的方法是在 if else 之后抛出异常,以确保如果你不计算某些东西,你的程序不会以不正确的值继续。

      private static int editDistance(String s1, String s2) {
      
          if((s2.isEmpty() && (dn == 0 && dc == 0 && di == 0)) || (s1.isEmpty() && (dn == 0 && dc == 0 && di == 0)))
              return Integer.max(s1.length(), s2.length());
      
          if(s2.isEmpty()) {
              return 0;
          } else if(s1.isEmpty()) {
              dc++;
              return 1 + editDistance(s1, rest(s2));
          } else if(s1.charAt(0) == s2.charAt(0)) {
              dn++;
              return editDistance(rest(s1), rest(s2));
          } else if(s1.charAt(0) != s2.charAt(0) && dc <= di) {
              dc++;
              return 1 + editDistance(s1, rest(s2));
          } else {
              di++;
              return 1 + editDistance(rest(s1), s2);
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果这些条件耗尽了所有可能性,我建议您不要删除任何条件(因为这是程序为何执行它的操作的文档),而是抛出异常 - 例如 AssertionError 带有消息“this can'不会发生”。

        这是因为有时由于重构或魔法,不应该发生的事情确实发生了,最好不要忽略它们,而是让应用程序崩溃(因为它处于不一致的状态)。

        Java 编译器无法始终检测到不可能的场景(计算成本太高,而且在某些情况下 - 不可能 - 请参阅“停止问题”)。

        【讨论】:

          猜你喜欢
          • 2016-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-24
          • 2015-12-13
          相关资源
          最近更新 更多