-2

So I have a question that asks me to write a method that is passed a String consisting of digits, and this method should return the sum of those digits. So if the String is "123" my method should return the value 6. If the null String is passed, my method should return zero. It asks me to use Recursion. Here's what I have so far:

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;
  } 
}

I'm just having a bit of trouble trying to see if I'm on the right track, I know it's totally wonky and recursion is still really odd to me so any help is really appreciated. Thank you!

Edit: I don't think this is a duplicate of any other problems asking how to find sum of digits using recursion, this is very similar but it's different because it asks to find sum of digits from a String.

Bug Scramble
  • 61
  • 3
  • 8
  • 3
    `sumDig()` is declared with an `int` argument but is called from `main` with a `String` – Sharon Ben Asher Oct 26 '18 at 19:32
  • 2
    Possible duplicate of [Find Sum of Digits Using Recursion](https://stackoverflow.com/questions/48547526/find-sum-of-digits-using-recursion) – Nicholas K Oct 26 '18 at 19:34
  • 1
    Why would you need to do `Integer.parseInt` if `num` is already an integer? This shouldn't even compile as written. – EJoshuaS - Stand with Ukraine Oct 26 '18 at 19:38
  • Since the method is supposed to take a `String` as the parameter ("method that is passed a String"), you should determine the digit value of the first character (e.g. using `Character.digit()`), then make recursive call with rest of string (using `substring(1)`). – Andreas Oct 26 '18 at 19:39

6 Answers6

1

The key issue that folks are pointing out is that you've inverted your method signature:

public static String sumDig(int num)

which should be:

public static int sumDig(String num)

Let's also address another issue in that you took data that you could process directly, made it into something else more complicated, and processed that instead. Let's operate directly on what you are handed:

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]));
    }
}

USAGE

% java Q2 123
6
%
cdlane
  • 40,441
  • 5
  • 32
  • 81
0
// TODO not working with negative numbers
public static int sumDig(String str) {
    return str.isEmpty() ? 0 : str.charAt(0) - '0' + sumDig(str.substring(1));
}

public static int sumDig(int num) {
    return Math.abs(num) < 10 ? Math.abs(num) : (Math.abs(num) % 10 + sumDig(num / 10));
}
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
  • 3
    Is providing straight answers to homework questions the right thing to do? The class even is called Q2 - there's no doubt this is a homework question. – Owen Oct 26 '18 at 19:42
  • Can be done as a single statement, that even ignores non-digits: `return (s.isEmpty() ? 0 : Math.max(0, Character.digit(s.charAt(0), 10)) + sumDig(s.substring(1)));` – Andreas Oct 26 '18 at 19:43
  • @Andreas one line of code is not good for all cases. I prefer simple one. – Oleg Cherednik Oct 26 '18 at 19:48
  • @oleg.cherednik I don't understand "not good for all cases". Which "cases" is it not good for? Sure, it behaves different than your code for non-digit text (exception vs ignored), but since there is no defined behavior for non-digit input, both are equally valid. For digit-only inputs, they produce same result. – Andreas Oct 26 '18 at 19:48
  • I just want to say, that one-line solution (I do not talk about yours) is not the best in all situations. Some time it is really hard to realise at first sight. Therefore, I prefer to write couple `if...else` than e.g. single line 200 chars expression. – Oleg Cherednik Oct 26 '18 at 19:51
  • @oleg.cherednik *FYI:* My single line is actually shorter than your longest line (by 4 characters). – Andreas Oct 26 '18 at 19:53
  • @oleg.cherednik is saying compressing everything into one line, while valid, is not easy to understand for beginners. Honestly, it's easier for everyone to understand and maintain the code when each logical step is on a separate line and descriptive names are used. I'll write 10 easy-to-understand lines of code any day over 1 cryptic line of code. – Michael Bruesch Oct 26 '18 at 19:58
0

These are three variations of recursive methods, differing by parameter and return type but they all do the same job of adding input number and printing the output.

// 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()))));
}
Pushpesh Kumar Rajwanshi
  • 18,127
  • 2
  • 19
  • 36
  • I'm not sure what you mean by "proper recursive function" in this case - you can write a recursive function with a string, too. – EJoshuaS - Stand with Ukraine Oct 26 '18 at 19:53
  • Since we are dealing with numbers, why to involve strings. Will just have to keep dealing with substrings and parseInt unnecessarily. Anyway, here is a String recursive method. – Pushpesh Kumar Rajwanshi Oct 26 '18 at 19:58
  • My objection was more to the phrasing of referring to the integer version of this as somehow "better recursion" than the string version. Both versions are equally recursive (although you could make an argument that the integer version you present is better coding style; that's different than saying that one is "proper recursion" and the other one isn't, though). – EJoshuaS - Stand with Ukraine Oct 26 '18 at 20:06
  • Yea, exactly, I probably couldn't use better words (sorry about that) but I meant, when we were dealing with numbers, it should have been pure maths. I have updated String version too where argument is int and return type as String. I even made another method where input as well as return type both are String. – Pushpesh Kumar Rajwanshi Oct 26 '18 at 20:07
0

In the comments below I want you to see the logical and syntactical mistakes you made:

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;
}

This does not mean that if you make all the proposed corrections that the method will work as expected. For example what happens when the string is null, etc?

forpas
  • 160,666
  • 10
  • 38
  • 76
0

Assuming the String is all digits, the below works with String of length longer than Integer.MAX_VALUE

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');
}
elvaston5
  • 33
  • 7
-1

I'll give you a hint: what would happen if you did a for loop over the characters in the string and added the digits up that way? I'd suggest trying to write such a for loop. Here's an example of what I'm talking about (with apologies for it being in C# rather than Java - the syntax is very similar, though):

string s = "123";

int sum = 0;

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

After that, how would you write a recursive function that's equivalent to the for loop?