Java 如何使用递归方法返回字符串中的数字和?

Java 如何使用递归方法返回字符串中的数字和?,java,string,recursion,int,Java,String,Recursion,Int,所以我有一个问题,要求我写一个方法,它传递一个由数字组成的字符串,这个方法应该返回这些数字的总和。因此,如果字符串是123,我的方法应该返回值6。如果传递空字符串,我的方法应该返回零。它要求我使用递归。以下是我目前掌握的情况: public class Q2 { public static void main(String[] args) { String s = "135"; System.out.println(sumDig(s)); } public static String

所以我有一个问题,要求我写一个方法,它传递一个由数字组成的字符串,这个方法应该返回这些数字的总和。因此,如果字符串是123,我的方法应该返回值6。如果传递空字符串,我的方法应该返回零。它要求我使用递归。以下是我目前掌握的情况:

public class Q2 {


public static void main(String[] args) { 

String s = "135";
System.out.println(sumDig(s));
}

public static String sumDig(int num)
{
  int i = Integer.parseInt(num);
  int sum = 0;
  if (i == 0)
    return sum;
  int sum = num%10 + sumDig(num/10);
  return sum;
  } 
}
我只是有点麻烦,试图看看我是否在正确的轨道上,我知道这是完全不可靠的,递归对我来说仍然是非常奇怪的,所以任何帮助都非常感谢。谢谢大家!


编辑:我不认为这是重复任何其他问题,即如何使用递归查找数字和,这是非常相似的,但它不同,因为它要求从字符串中查找数字和。

我将给你一个提示:如果对字符串中的字符进行for循环,并以这种方式添加数字,会发生什么?我建议尝试编写这样一个for循环。下面是一个我所说的例子,很抱歉它是用C语言而不是Java语言编写的-尽管语法非常相似:

string s = "123";

int sum = 0;

for (int i = 0; i < s.Length; i++)
{
    sum += int.Parse(s[i].ToString());
}

在那之后,您将如何编写一个与for循环等效的递归函数?

这是递归方法的三种变体,参数和返回类型不同,但它们都做相同的工作,即添加输入编号和打印输出

// Recursive method where parameter is int and return type String
public static String getSumStr(int n) {
    n = n < 0 ? -n : n; // takes care of negative numbers
    if (n < 10) {
        return String.valueOf(n);
    }
    return String.valueOf(n % 10 + Integer.parseInt(getSumStr(n / 10)));
}

// Recursive method where parameter and return type both are int
public static int getSum(int n) {
    n = n < 0 ? -n : n; // takes care of negative numbers
    return n < 10 ? n : (n % 10 + getSum(n / 10));
}

// Recursive method where parameter and return type both are String
public static String getSumStr(String s) {
    if (s == null || s.length() == 0) {
        return "0";
    }
    if (s.length() == 1) {
        return s;
    }
    return String.valueOf(Integer.parseInt(s.substring(0, 1))
            + Integer.parseInt(getSumStr(s.substring(1, s.length()))));
}

人们指出的关键问题是,您已经反转了方法签名:

public static String sumDig(int num)
应该是:

public static int sumDig(String num)
我们还要解决另一个问题,即您获取了可以直接处理的数据,将其转换为其他更复杂的数据,然后进行处理。让我们直接对你的手进行操作:

public class Q2 {

    public static int sumDig(String digits) {

        int sum = 0;

        if (! digits.isEmpty()) {
            sum += Character.getNumericValue(digits.charAt(0)) + sumDig(digits.substring(1));
        }

        return sum;
    } 

    public static void main(String[] args) { 
        System.out.println(sumDig(args[0]));
    }
}
用法


在下面的评论中,我想让你看到你犯的逻辑和语法错误:

public static String sumDig(int num) {
    // the return type should be int and not String
    // the parameter num should be String and not int

    int i = Integer.parseInt(num);
    int sum = 0;
    if (i == 0)
        return sum;
    int sum = num%10 + sumDig(num/10);
    // sum has been previously declared as int, so int is not required in the above line
    // the number is i and this should be used and not num (which is a String)
    // in the calculations
    // num/10 cannot be used as a parameter of sumDig because sumDig needs
    // a String parameter

    return sum;
}

这并不意味着,如果您进行了所有建议的更正,该方法将按预期工作。例如,当字符串为空时会发生什么情况,等等

假设字符串都是数字,下面的字符串长度大于Integer.MAX\u值

public static void main(String[] args) {
    String s = "123344566777766545";
    long i = sumDig(s);
    System.out.println(i);
}

public long sumDig(String s) {
    return sumDigits(s.toCharArray(), 0);
}

public long sumDigits(char[] chars, int index) {
    if (index == chars.length - 1) {
        return chars[index] - '0';
    }
    return sumDigits(chars, index + 1) + (chars[index] - '0');
}

sumDig是用int参数声明的,但从main调用时使用了stringreplice,如果num已经是整数,为什么需要执行Integer.parseInt?这甚至不应该像编写的那样编译。由于该方法应该以字符串作为传递字符串的参数方法,因此您应该确定第一个字符的数字值,例如使用character.digit,然后使用substring1对字符串的其余部分进行递归调用。为家庭作业问题提供直接答案是正确的吗?这个类甚至被称为Q2——毫无疑问,这是一个家庭作业问题。可以作为一个语句来完成,甚至可以忽略非数字:返回s.isEmpty?0:Math.max0,Character.digits.charAt0,10+sumDigs.substring1@Andreas一行代码并不适用于所有情况。我更喜欢简单的。@oleg.cherednik我不明白不适合所有情况。哪种情况不好?当然,它的行为不同于非数字文本异常和忽略的代码,但由于没有定义非数字输入的行为,所以两者都是同等有效的。对于纯数字输入,它们产生相同的结果。我只想说,我没有提到的一行解决方案在所有情况下都不是最好的。有时候,一见钟情真的很难实现。因此,我更喜欢编写耦合if…,而不是单行200个字符的表达式。我不确定在这种情况下,正确的递归函数是什么意思-你也可以用字符串编写递归函数。既然我们处理的是数字,为什么要涉及字符串。只需要继续处理不必要的子字符串和parseInt。不管怎样,这里有一个字符串递归方法。我的反对意见更多的是将整数版本称为比字符串版本更好的递归。这两个版本都是同样递归的,尽管您可以提出一个论点,即您提供的整数版本是更好的编码样式;这不同于说一个是正确的递归,而另一个不是。是的,确切地说,我可能无法用更好的词来表示抱歉,但我的意思是,当我们处理数字时,它应该是纯数学。我也更新了字符串版本,其中参数为int,返回类型为String。我甚至还制作了另一个方法,其中输入和返回类型都是字符串。这与指定的方法签名不匹配,该方法被传递一个由DigitUpdated组成的字符串,以包含一个接受字符串的sumDig方法
public static String sumDig(int num) {
    // the return type should be int and not String
    // the parameter num should be String and not int

    int i = Integer.parseInt(num);
    int sum = 0;
    if (i == 0)
        return sum;
    int sum = num%10 + sumDig(num/10);
    // sum has been previously declared as int, so int is not required in the above line
    // the number is i and this should be used and not num (which is a String)
    // in the calculations
    // num/10 cannot be used as a parameter of sumDig because sumDig needs
    // a String parameter

    return sum;
}
public static void main(String[] args) {
    String s = "123344566777766545";
    long i = sumDig(s);
    System.out.println(i);
}

public long sumDig(String s) {
    return sumDigits(s.toCharArray(), 0);
}

public long sumDigits(char[] chars, int index) {
    if (index == chars.length - 1) {
        return chars[index] - '0';
    }
    return sumDigits(chars, index + 1) + (chars[index] - '0');
}