【问题标题】:CodingBat sumNumbersCodingBat sumNumbers
【发布时间】:2016-02-20 18:44:01
【问题描述】:

对于这个问题:http://codingbat.com/prob/p121193

我已经写了这段代码:

public int sumNumbers(String str) {
  int y = 0;
  int z = 0;
  for (int f4 = 0; f4 < str.length(); f4++) {
    if (Character.isDigit(str.charAt(f4))) {
      for (int f5 = f4; f5 < str.length(); f5++) {
        if (!Character.isDigit(str.charAt(f5))) {
          z = (Integer.parseInt(str.substring(f4, f5)));
          y = y + z;
          f4 = f5 - 1;
          break;
        }
      }
    }
  }
  return y;
}

这些是问题(它们不是代码,但它拒绝接受我的问题):

sumNumbers("abc123xyz") Expected: 123; Returned: 123
sumNumbers("aa11b33") Expected: 44; Returned: 11
sumNumbers("7 11") Expected: 18; Returned: 7
sumNumbers("Chocolate") Expected: 0; Returned: 0
sumNumbers("5hoco1a1e") Expected: 7; Returned: 7
sumNumbers("5$$1;;1!!") Expected: 7; Returned: 7
sumNumbers("a1234bb11") Expected: 1245; Returned: 1234
sumNumbers("") Expected: 0; Returned: 0
sumNumbers("a22bbb3") Expected: 25; Returned: 22

总而言之,由于某种原因,我的代码无法处理多个数字中的多个数字,我不知道为什么。我已经断断续续地研究了一段时间,虽然我拒绝直接查找答案,但我真的可以使用一些帮助。 我在高中AP Comp。科学。

【问题讨论】:

  • sumNumbers 输出的最后一行:您说预期是 25,返回 22...看起来返回应该是 22? sumNumbers("s1234bb11") 相同,看起来将正确的值返回给我。你能描述一下你所期望的算法吗?没关系。 codingbat 链接描述了它。

标签: java string


【解决方案1】:

您的代码没有任何问题。唯一的问题是您没有正确处理边界条件。您正在检查是否if (!Character.isDigit(str.charAt(f5)))。现在,如果你的内在时间已经耗尽并且没有遇到这种情况怎么办?

例如,如果您的测试用例失败,最后或最后几个字符是整数。

看到这个,aa11b33。现在在这里,33 永远不会被添加到您的总和中,即y,因为您的 if 条件永远不会被执行并且内部会被耗尽。

您需要处理边界条件以识别这些有效输入,然后将它们添加到总和中。

这里是更正后的代码 sn-p 供您参考:

public int sumNumbers(String str) {
  int y = 0, z = 0, f4, f5 = 0;
  for (f4 = 0; f4 < str.length(); f4++) {
    if (Character.isDigit(str.charAt(f4))) {
      for (f5 = f4; f5 < str.length(); f5++) {
        if (!Character.isDigit(str.charAt(f5))) {
          z = (Integer.parseInt(str.substring(f4, f5)));
          y = y + z;
          f4 = f5;
          break;
        }
      }
      /* Handle Boundary Conditions */
      if (f4 != f5) {
          z = (Integer.parseInt(str.substring(f4, str.length())));
          y = y + z;
          break;
      }
    }
  }
  return y;
}

【讨论】:

  • 啊,我没有意识到那里实际上需要一个角色来运行操作。我有良好逻辑的问题,但经常忘记一个小细节。巧合的是,所有数字都包含多位数字。
  • 是的,但是这就是好的问题制定者和测试制定者所做的! :)
  • 我的问题是,我注意到所有数字都在具有多个数字的数字上,其中至少一个数字超过一个数字,而我忽略了继续寻找其他相似之处,这就是为什么我好困惑。
  • 你做得很好。当我第一次开始编码时,我的情况要糟糕得多。
【解决方案2】:

您的代码已修改为处理在字符串末尾找到有效数字的情况。我确实认为您可以对此进行一些重构,以将重复的逻辑提取到一个方法中,并且只计算一次 str.length() 。但它在这里并返回您期望的结果:

    public int sumNumbers(String str) {
      int y = 0;
      int z = 0;

      for (int f4 = 0; f4 < str.length(); f4++) {
        Character c = str.charAt(f4);
        if (Character.isDigit(c)) {
          for (int f5 = f4; f5 < str.length(); f5++) {
            Character c2 = str.charAt(f5);

            if (!Character.isDigit(c2)) {
              z = (Integer.parseInt(str.substring(f4, f5)));
              y+= z;
              f4 = f5 - 1;
              break;
            }
            else if(Character.isDigit(c2) && f5 == str.length() -1){
                z = Integer.parseInt(str.substring(f4 ,str.length()));
                y += z;
                f4 = f5;
                break;
            }
          }
        }
      }
      return y;
    }

【讨论】:

    【解决方案3】:

    分析输出,我们清楚地看到输入字符串末尾的数字被忽略了。所有末尾有非数字的字符串都被正确解析 - 例如“5$$1;;1!!”总和为 7。

    查看查找已识别数字长度的内部 for 循环,我们可以看到循环在内部条件语句有机会总结之前结束。

    解决方案是简单地将求和功能移出内部循环:

    public static int sumNumbers(String str) {
        int sum = 0;
        for (int start = 0; start < str.length(); start++) {
            if (Character.isDigit(str.charAt(start))) {
                int end;
                for (end = start; end < str.length(); end++) {
                    if (!Character.isDigit(str.charAt(end))) {
                        break;
                    }
                }
                sum += (Integer.parseInt(str.substring(start, end)));
                start = end - 1;
            }
        }
        return sum;
    }
    

    请注意,我稍微重命名了您的变量以使其更具可读性。


    总结的另一种方法是使用regular expression。我之所以提到这一点,是因为 for 循环看起来非常复杂,而且这个任务的正则表达式非常可读。

    // \d+ means numbers with a minimum of 1 character
    // (...) makes it a group that can be referred to later
    private static Pattern NUMBERS = Pattern.compile("(\\d+)");
    
    public static int sumNumbers(String str) {
        Matcher matcher = NUMBERS.matcher(str);
        int sum = 0;
        while (matcher.find()) {
            sum += Integer.parseInt(matcher.group());
        }
        return sum;
    }
    

    【讨论】:

      【解决方案4】:

      您的解决方案根本不处理字符串末尾的数字。我会建议这样的解决方案:

      int y = 0;
      int z = 0;
      for (int f4 = 0; f4 < str.length(); f4++) {
          int f5 = 0;
          // forward while digits found
          for (f5 = f4; f5 < str.length() && Character.isDigit(str.charAt(f5)); f5++);
          // if found at least one digit parse it
          if(f5 > f4){
              z = (Integer.parseInt(str.substring(f4, f5)));
              y = y + z;
              f4 = f5 - 1;
          }
      }
      return y;
      

      【讨论】:

        【解决方案5】:
        public int sumNumbers(String str) {
            int y = 0;
            int z = 0;
            for (int f4 = 0; f4 < str.length(); f4++) {
                if (Character.isDigit(str.charAt(f4))) {
                    for (int f5 = f4; f5 < str.length(); f5++) {
                        if (!Character.isDigit(str.charAt(f5))) {
                            z = (Integer.parseInt(str.substring(f4, f5)));
                            y = y + z;
                            z = 0;
                            f4 = f5;
                            break;
                        }
                        if (!Character.isDigit(str.charAt(f5)) || f5 == (str.length() - 1)) {
                            z = (Integer.parseInt(str.substring(f4, f5 + 1)));
                            y = y + z;
                            z = 0;
                            f4 = f5;
                            break;
                        }
                    }
                }
            }
            return y;
        }
        

        【讨论】:

        • 请在您的回答中提供更多信息,例如解释为什么此代码提供了一个好的解决方案
        • 在这段代码中有两部分从字符串中查找数字。 if (!Character.isDigit(str.charAt(f5)) || f5 == (str.length() - 1)) { z = (Integer.parseInt(str.substring(f4, f5 + 1))); y = y + z; z = 0; f4 = f5;休息; } 处理字符串最后的整数,其他处理字符串中的剩余整数。并且 Z 被视为临时变量,因此在每次操作后将其设为零。
        【解决方案6】:

        这个问题也可以用另一种方式解决。

         public int sumNumbers(String str) {
          int result=0;
          int firstPosOfDig=0;
          int LastPosOfDig=0;
        
          for(int i=0; i<str.length();i++)
          {
            if(Character.isDigit(str.charAt(i)))
            {
              if(i==0 || !Character.isDigit(str.charAt(i-1)))
                firstPosOfDig=i;
              if(i==str.length()-1 || !Character.isDigit(str.charAt(i+1)))
                {
                  LastPosOfDig=i;
                  result+=Integer.parseInt(str.substring( firstPosOfDig, LastPosOfDig+1));
                }
            }
          }
          return result;
        }
        

        【讨论】:

          猜你喜欢
          • 2013-12-16
          • 1970-01-01
          • 1970-01-01
          • 2015-04-27
          • 1970-01-01
          • 2015-03-01
          • 2014-03-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多