1

I am writing a groovy program. I have an output like below

red 5green 5blue 10white 15

I want to sum up the digits in the output. The sum would be 35

I wrote the below logic however the program returned 17 which is right as the below logic takes into account digits.

can you please guide me as to how I make the program understand two digit numbers? so that i get the right sum?

for (int i =0; i < output.length(); i++)
    {
        {
            sum=sum+Character.getNumericValue(grps.charAt(i))
        }
    }

Thanks

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
Raj
  • 29
  • 1
  • 2

4 Answers4

3

Since you tagged for [groovy] too:

You could "findAll" number-strings in the string with a regexp /\d+/, turn all of them into numbers, and finally sum() them. e.g.

def sumNumberStrings(s) {
    s.findAll(/\d+/)*.toLong().sum()
}
assert 35==sumNumberStrings("red 5green 5blue 10white 15")
cfrick
  • 35,203
  • 6
  • 56
  • 68
  • Thanks @cfrick this worked stuck with one more problem now. My output has below numbers seperated by space and these needs to be multiplied. [120.98 7, 151.99 8, 141.39 4, 137.71 7, 121.27 6, 187.29 11] Trying to split them by space using split and multiply them however facing issues, any ideas ? – Raj Dec 14 '18 at 12:15
0

I would use a regular expression to replace all non-digits with a space, trim() that to remove any leading and trailing and white-spaces and then split on (optionally consecutive) white-space; like,

String output = "red 5green 5blue 10white 15";
int sum = 0;
for (String token : output.replaceAll("\\D+", " ").trim().split("\\s+")) {
    sum += Integer.parseInt(token);
}
System.out.println(sum);

Outputs (as requested)

35

Another option would be a Pattern to find all sequences of one or more digits and group them, then use a loop to parse and add to the sum. Like,

Pattern p = Pattern.compile("(\\d+)");
Matcher m = p.matcher(output);
while (m.find()) {
    sum += Integer.parseInt(m.group(1));
}
System.out.println(sum);

Which will also give you 35.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • The only think I would add to this is you could us slash strings for the regex, and you can drop both the semicolons, and the System.out String output = "red 5green 5blue 10white 15" int sum = 0 for (String token : output.replaceAll(/\D+/, " ").trim().split(/\s+/)) { sum += Integer.parseInt(token) } println(sum) – virtualdogbert Dec 09 '18 at 03:26
  • Brilliant. Thanks Elliott – Raj Dec 10 '18 at 08:33
0

Apparently I can't write code in comment, but just to follow on with the answer you could take it a bit further and using slashing strings, drop the semicolons and the System.out.

String output = "red 5green 5blue 10white 15"
int sum = 0

for (String token : output.replaceAll(/\D+/, " ").trim().split(/\s+/)) {
    sum += Integer.parseInt(token)
}

println(sum)
virtualdogbert
  • 462
  • 3
  • 12
  • Thanks Stuck with one more problem now. My output has below numbers seperated by space and these needs to be multiplied. [120.98 7, 151.99 8, 141.39 4, 137.71 7, 121.27 6, 187.29 11] Trying to split them by space using split and multiply them however facing issues, any ideas ? – Raj Dec 14 '18 at 12:18
0

A simple algorithm that does not require usage of regular expressions or other complicated features would be something like this:

String output = "red 5green 5blue 10white 15";

// The result
int sum = 0;
// Sum of the current number
int thisSum = 0;
for (char c : output.toCharArray()) {
    // Iterate through characters
    if (Character.isDigit(c)) {
        // The current character is a digit so update thisSum so it includes the next digit.
        int digitValue = c - '0';
        thisSum = thisSum * 10 + digitValue;
    } else {
        // This character is not a digit, so add the last number and set thisSum 
        // to zero to prepare for the next number.
        sum += thisSum;
        thisSum = 0;
    }
}
// If the string ends with a number, ensure it is included in the sum.
sum += thisSum;

System.out.println(sum);

This works with numbers of any number of digits.

Alice Ryhl
  • 3,574
  • 1
  • 18
  • 37