Kay
Kay

Reputation: 25

To print the sum of the numbers(not digits) in a string

I was recently asked to write a function in java which will sum the numbers(not digits) in a string. e.g. if the string is abc35zz400tt15, the output should be 450.

this is what i wrote :

 public static void getSum(String a){
        String[] arr=a.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
        int sum=0;
        for(int i=0;i<arr.length;i++){
            if(Pattern.matches("[0-9]+", arr[i]))
        sum+=Integer.parseInt(arr[i]);
    }
    System.out.println(sum);
    }

Is there a more efficient way to do this as they didn't look satisfied with the above code.

Upvotes: 2

Views: 833

Answers (6)

Jack
Jack

Reputation: 133609

If you are look forward efficiency regex matching and object allocations could be overkill for the task. You can scan the string backwards and accumulate the number:

int currentPower = 1;
int length = string.length();
int value = 0;

for (int i = string.length()-1; i >= 0; --i) {
  char curChar = string.charAt(i);
  if (curChar >= '0' && curChar <= '9') {
    value += (curChar - '0') * currentPower;
    currentPower *= 10;
  }
  else
    currentPower = 1;
}

Upvotes: 5

Floris
Floris

Reputation: 46435

Alternative solution: replace everything that is not a number with a + sign, and evaluate the result. That is not very efficient in Java, but there are other instances (bash for example) where it would be the right thing to do. So I'm putting that suggestion here "for future visitors".

Clarification: I mean something like

echo abc35zz400tt15 | sed -E 's/[^0-9]+/\+/g' | sed 's/^\+//' | bc

That is

find one or more characters that are not a digit
replace all of them with a +
then strip the first `+` if it's the first character in the line
and evaluate the result

The above yields

450

as expected.

Note - bc doesn't like it when the string you feed it starts with a + - hence the need for the second sed.

Note 2 - the -E flag is used on Mac OSX to set "extended regular expressions". This gives special meaning ('one or more') to the + character - shorter than \{1,}\}... I know the Mac one is subtly different than the gnu one, but don't know whether this is one of those occasions.

Upvotes: 1

Justin C
Justin C

Reputation: 333

Edit:: Whoops, read too fast, you wanted numbers, not digits. I believe someone has already answered above. I also have answered the question using my original (but incorrect) approach

Previous Answer

Look at Java's isDigit(char c). It may look something like:

public static void getSum(string a) {
    int sum = 0;
    for(int i = 0; i < a.length(); i++) {
        if(Character.isDigit(a.charAt(i))) {
            sum += Integer.parseInt(a.charAt(i));
        }
    }
    System.out.println(sum);
}

New answer using an iterative approach

public static void getSum(String a) {
    int sum = 0;
    String num = "";
    for(int i = 0; i < a.length(); i++) {
        if(Character.isDigit(a.charAt(i))) {
            num = num + a.charAt(i);
        } else {
            if(!num.equals("")) {
                sum = sum + Integer.parseInt(num);
                num = "";
            }
        }
    }
    if(!num.equals("")) {
        sum = sum + Integer.parseInt(num);
    }
    System.out.println(sum);
}

Upvotes: -2

assylias
assylias

Reputation: 328775

If you fancy Java 8, you can write it in a fairly expressive way:

int sum = Arrays.stream(input.split("\\D+"))
             .filter(s -> ! s.isEmpty())
             .mapToInt(Integer::parseInt)
             .sum();

Upvotes: 1

XpressOneUp
XpressOneUp

Reputation: 195

Quick solution, without any usage of Matcher and Pattern:

    String line = "abc35zz400tt15";
    int sum = 0;

    String[] numbers = line.split("\\D");
    for (String digit : numbers) {
        if (digit.length() > 0) sum += Integer.valueOf(digit);
    }

Upvotes: 2

Mark Peters
Mark Peters

Reputation: 81124

I think it would be a bit simpler just to search for the pattern one at a time, rather than split the String.

Pattern pattern = Pattern.compile("[0-9]+"); //or you can use \\d if you want
Matcher matcher = pattern.matcher(a);

while(matcher.find()) {
    sum += Integer.parseInt(matcher.group());
}

Upvotes: 6

Related Questions