1

I was asked this question in an interview recently (Java programming que)

Return the sum of all integers from a random String.

VJ_QE
  • 143
  • 1
  • 2
  • 12

5 Answers5

4

Just iterate over the string, handle one digit at a time. This is pretty much exactly what the regex would do anyway:

    String testStrings[] = { "-1a2b3c", "123ab!45c", "abcdef", "0123.4",
            "dFD$#23+++12@#T1234;/.,10" };

    for (String testString : testStrings) {
        String currentNumber = "";
        int sum = 0;
        for (int i = 0; i < testString.length(); i++) {
            char currentChar = testString.charAt(i);

            // Add digits or a leading minus to "currentNumber"
            if (Character.isDigit(currentChar)
                    || (currentNumber.equals("") && currentChar == '-')) {
                currentNumber += currentChar;
            } else {
                // We've stumbled across a non-digit char.
                //Try to parse the "currentNumber" we have so far
                if (!currentNumber.equals("") && !currentNumber.equals("-"))
                    sum += Integer.parseInt(currentNumber);
                currentNumber = "";
            }
        }

        // Add the last "currentNumber" in case the string ends with a
        // number
        if (!currentNumber.equals("") && !currentNumber.equals("-"))
            sum += Integer.parseInt(currentNumber);
        System.out.println(sum);
    }

Output:

4
168
0
127
1279
Malt
  • 28,965
  • 9
  • 65
  • 105
1
public class Random {

    public  int SumofNumbers(String s){

        char[] str = s.toCharArray();
        String answer="";
        int sum = 0;
        List<String> al = new ArrayList();
        for (int i=0;i< str.length;i++){
            if (checkNumber(str[i])){
                answer=answer+str[i];
            }
            else
            {
                if(!answer.isEmpty()){
                    al.add(answer);
                    answer = "";
                }
            }

             if (i == str.length -1 && !answer.isEmpty()) {
                    al.add(answer);
                }
        }

        for (String a1 : al){
            sum = sum + Integer.valueOf(a1);
        }

        return sum;
    }

    private boolean checkNumber(char c) {
        if ((int)c > 47 &&  (int)c < 58){
            return true;
        }else if ((int)c == 45){
            return true;
        }
        return false;
    }

    public static void main(String [] args){
        Random r = new Random();
        String test = "123ab!45c";
        System.out.println(r.SumofNumbers(test));
    }

}
potame
  • 7,597
  • 4
  • 26
  • 33
himanshu
  • 11
  • 2
0

I've got a slightly 'cute' way to do this in Java 8: implement it as a Collector

public DigitCollector {
    private boolean negative = false;
    private int current = 0;
    private int total = 0;

    public int getTotal() {
        if (negative) {
            total -= current;
        } else {
            total += current;
        }
        current = 0;
        negative = false;
        return total;
    }

    public void accept(Character ch) {
        if (Character.isDigit(ch)) {
            current = 10 * current + Integer.parseInt(ch.toString());
        } else if (ch.equals('-')) {
            negative = true;
        } else {
            getTotal();
        }
    }
}

Now you can collect a stream of characters:

text.chars().map(ch -> new Character((char)ch))
    .collect(DigitCollector::new, DigitCollector::accept, null)
    .getTotal();

I realise the mapping ch -> new Character((char)ch)) looks strange but .chars() returns a stream of integers instead of characters. See here for reasons why (though pretty much everyone agrees it was a mistake).

This is a slightly longwinded way of doing it but it's pretty flexible: you could take a stream of Character from anywhere and do any sort of manipulation you wanted before collecting them. It seems to me to be a natural representation of the problem and, mostly, I just reckon streams are cooler than traditional iteration :-)

Community
  • 1
  • 1
sprinter
  • 27,148
  • 6
  • 47
  • 78
0
public class StringToIntAddition {

    public static void main(String[] args) throws Exception {
        String str = "2e40 ssdf 23-9", number="";
        int sum=0;
        for(int i=0; i<str.length() ;i++){

                if(Character.isDigit(str.charAt(i))){
                        number += str.charAt(i);
                }
                else if(!number.isEmpty()){
                    sum += Integer.parseInt(number);
                    number= "";
                }
                if (str.charAt(i) == '-'){
                    number = "-" ;  
                    }

        }
     if(!number.isEmpty()){
            sum += Integer.parseInt(number);
            }
        System.out.println("number= " + sum);
    }

}
VJ_QE
  • 143
  • 1
  • 2
  • 12
0

There's already quite a few answers, but this one seemed fun. I have a different solution that should be pretty efficient:

public static int countString(String input) {
    if (input == null) return 0;

    int sum = 0;
    int accumulator = 0;
    boolean lastCharWasDigit = false;

    for (int i = 0, len = input.length(); ++i) {
        char c = input.charAt(i);

        // If a non-digit character is found, clear the 
        // accumulator and add it to the sum.
        if (c < '0' || c > '9') {
            sum += accumulator;
            accumulator = 0;
            lastCharWasDigit = false;
            continue;
        }

        // If the previous character was a digit, that means
        // this is a continuation. Multiply by ten to shift
        // it over one power of ten before adding the new value
        if (lastCharWasDigit) {
            accumulator *= 10;
        }

        // Add the integer value of the character
        int charValue = c - '0';
        accumulator += charValue;
        lastCharWasDigit = true;
    }

    // Finally, clear the accumulator for any ending digits,
    // and return the sum
    sum += accumulator;
    return sum;
}
Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274