简体   繁体   中英

Return the sum of all integers from a random String without using regex

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

Return the sum of all integers from a random String.

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

}

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 :-)

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

}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM