1

I was trying to get around the below problem in codingBat for Java: http://codingbat.com/prob/p121193

Given a string, return the sum of the numbers appearing in the string, ignoring all other characters. A number is a series of 1 or more digit chars in a row. (Note: Character.isDigit(char) tests if a char is one of the chars '0', '1', .. '9'. Integer.parseInt(string) converts a string to an int.) sumNumbers("abc123xyz") → 123 sumNumbers("aa11b33") → 44 sumNumbers("7 11") → 18

Below is my solution

public int sumNumbers(String str) {
  final int len=str.length();

  int[] numbers=new int[len];
  int count=0;
  String temp="";
  int sum=0;

  for(int i=0;i<len;i++)
  {
     if(Character.isDigit(str.charAt(i)))
     {
        temp=temp+str.substring(i, i+1);

        if(i==len-1)
        {
          numbers[count]=Integer.parseInt(temp);
          break;
         }
        if(Character.isDigit(str.charAt(i+1)))
        {
           continue;
        }
        else
        {
          numbers[count]=Integer.parseInt(temp);
          count++;
          temp="";
        } 
     }   

   }
   for(int j=0;j<numbers.length;j++)
   {
      sum=sum+numbers[j];
    }
    return sum;  

}

It's a simple problem please provide any alternative efficient answers using regex or anyway other PLEASE DO NOT USE ANYTHING FROM COLLECTIONS FRAMEWORK.

Anirudh
  • 2,286
  • 4
  • 38
  • 64
  • Okay!! Thanks for focusing on code review part rather than reading the actual question....Dear sir what I meant was if there is any code enthusiast who wants to review the code..then they can provide the nitpicks!! – Anirudh Nov 30 '13 at 13:24
  • Your question does not belong on this site! – Robin Green Nov 30 '13 at 13:25
  • Provide a good reason then why stack overflow has the [code-review] tag?? – Anirudh Nov 30 '13 at 13:28
  • In the tag description for the [code-review] tag, which you can read by hovering over the tag with your mouse or clicking through to the tag wiki, it says "Code reviews are off-topic on Stack Overflow, please use codereview.stackexchange.com to request a code review of otherwise working code." I know, it is stupid that StackOverflow.com doesn't show you this message as an error message, we asked for this feature over 4 years ago but Jeff Atwood denied us this feature. I think it is time to revisit that decision. – Robin Green Nov 30 '13 at 13:31
  • Okay I have edited the question and removed the tag, please provide and answer!! – Anirudh Nov 30 '13 at 13:34
  • The problem is NOT that you added the code review tag, the problem is that you have posted the question on the wrong site. – Robin Green Nov 30 '13 at 13:35
  • If you read now there is nothing wrong with the question! – Anirudh Nov 30 '13 at 13:49

23 Answers23

1

Here's my solution. It's similar to yours.

public int sumNumbers(String str) {
    int sPos = -1;
    int ePos = -1;
    int sum = 0;

    for (int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        if (Character.isDigit(c)) {
            if (sPos < 0) {
                sPos = i;
                ePos = i;
            } else {
                ePos = i;
            }
        } else {
            sum = add(str, sum, sPos, ePos);
            sPos = -1;
        }
    }

    sum = add(str, sum, sPos, ePos);

    return sum;
}

private int add(String str, int sum, int sPos, int ePos) {
    if (sPos >= 0) {
        sum += Integer.parseInt(str.substring(sPos, ePos + 1));
    }
    return sum;
}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
1
public int sumNumbers(String str) {
    int sum = 0;
    StringTokenizer st = new StringTokenizer(str,"$!;Cabcdefghijklmnopqrstuvwxyz ");
    while (st.hasMoreTokens()) {
         sum += Integer.parseInt(st.nextToken());
    }
    return sum;
}

I wrote it a long time ago, and wonder now what I thought when writing this piece of code back in the days.

jcklie
  • 4,054
  • 3
  • 24
  • 42
  • Can you use regex as an alternate solution? Wouldn't it be better than stringTokenizer performance wise? I am not asserting just guessing! – Anirudh Nov 30 '13 at 16:25
  • 1
    I cared about linecount. Regex or tokenizer will degrade the performance I assume, so a solution just based on array access + loops should normally be faster. – jcklie Nov 30 '13 at 17:39
1

I wrote this one. I have no idea does it look better or not :)

    public int sumNumbers(String str) {
String justLetter = "";
int answer = 0; 
int number = 0; 
int factor = 1; 

for (int a = str.length()-1; a >= 0 ; a--) {

justLetter = justLetter + str.charAt(a);

if (Character.isDigit(justLetter.charAt(0))) {
number = Integer.parseInt(justLetter) * factor; 
factor = factor * 10; 
answer = answer + number;
}

else {
factor = 1;
}
justLetter = "";
}
return answer;
}
sjuesju
  • 11
  • 4
1

Here's another solution:

public int sumNumbers(String str) {
      if (str.length()<1)
        return 0;

      int sum=0;
      int lengthOfDigits;

      for (int i=0;i<str.length();i++)
      {
        char currentChar = str.charAt(i);
        lengthOfDigits=1;
        if (Character.isDigit(currentChar))
        {
            for (int j=i;j<str.length()-1;j++)
            {
                char nextChar = str.charAt(j+1);
                if (Character.isDigit(nextChar))
                    lengthOfDigits++;
                else
                    break;
            }   
            String number = str.substring(i,i+lengthOfDigits);
            sum+=Integer.parseInt(number);          

            //dont double count, in the case of 123, skip to 3 instead of count 23 again
            i+=lengthOfDigits;
        }                       
      }
      return sum;
    }
enducat
  • 1,676
  • 3
  • 17
  • 16
1

Simple and short solution in a single for-loop:

   public int sumNumbers(String str) {
    int sum = 0;
    String num = "0";
    for (int i = 0; i < str.length(); i++) {
        char ch = str.charAt(i);
        if (Character.isDigit(ch)) {
            num += ("" + ch);
        } else {
            sum += Integer.parseInt(num);
            num = "0";
        }
    }
    sum += Integer.parseInt(num);
    return sum;
}

Note: It is recommended to use StringBuilder.append() instead of concatenating new strings using +.

mel3kings
  • 8,857
  • 3
  • 60
  • 68
user3437460
  • 17,253
  • 15
  • 58
  • 106
  • 1
    This is a hidden gem here, ingenious way of using String to hold the ints using "0", deserves more upvote – mel3kings Dec 18 '18 at 08:51
1

My solution

public int sumNumbers(String str) {

    int sum = 0;

    if (!str.matches(".*\\d.*")) return 0;

    for (int i = 0; i < str.length(); i++) {
        if (!Character.isDigit(str.charAt(i))) {
            str = str.replace(str.charAt(i), ' ');
        }

    }
    str = str.trim();

    String[] splitStr = str.split("\\s+");

    for (int z = 0; z < splitStr.length; z++) {
        sum += Integer.parseInt(splitStr[z]);
    }

    return sum;
}
0
public int sumNumbers(String str) {
    int sum = 0;
    int tmp = 0;
    str = str + " ";
    for (int i = 0; i < str.length(); i++) {
            if(Character.isDigit(str.charAt(i))){
                tmp = 0;
                for(int j = i; j < str.length(); j++){
                    if(!Character.isDigit(str.charAt(j))){
                        tmp = Integer.parseInt(str.substring(i,j));
                        i=j;
                        break;
                    }
            }   
                sum += tmp; 
        }
    }
    return sum;
}
0

Alternative solution with single loop:

public int sumNumbers(String str) {
    boolean b = false;
    String con = null;
    int sum = 0;
    int index = 0;

    for (int i = 0; i <= str.length(); i++) {
        if (i < str.length() && Character.isDigit(str.charAt(i))) {
            if (!b) {
                index = i;
                b = true;
            }
        } else if (b) {
            con = str.substring(index, i);
            b = false;
            sum += Integer.parseInt(con);
        }
    }
    return sum;
}
0
public int sumNumbers(String str) {

  int sum = 0;
  for(int i = 0 ; i < str.length(); i++ ) {
    if(Character.isDigit(str.charAt(i))) {
       int count = 0;
       for (int j = i; j < str.length(); j ++ ) {
           if (Character.isDigit(str.charAt(j))) {
              count++;
           } else {
              break;
           }
       }
       sum += Integer.parseInt(str.substring(i, i + count));
       i += count;
    }
  }


  return sum;
}
cynobody
  • 33
  • 7
0

In a single loop:

public int sumNumbers(String str) {

    int sum=0;
    String temp="";
    str=str+" ";
    for (int i = 0; i < str.length(); i++) {
        if(Character.isDigit(str.charAt(i))){
            temp+=str.charAt(i);
        }else if(temp!=""){
                sum+=Integer.parseInt(temp);
                temp="";
        }
    }

    return sum; 
}
Community
  • 1
  • 1
Pradeep
  • 1
  • 1
  • 4
0
public int sumNumbers(String str) {
if(str.length()==0){return 0;}
 String [] s = str.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
     int sum = 0;
     for (int i = 0; i < s.length; i++) {
        char c = s[i].charAt(0);
        if(Character.isDigit(c)){
            sum += Integer.valueOf(s[i]);
        }

    }

    return sum;
     }

based on this link

Community
  • 1
  • 1
ML13
  • 895
  • 8
  • 15
0
    public int sumNumbers(String str) {
    StringBuilder sb = new StringBuilder(); 
    int count = 0;

    for (int i = 0; i < str.length(); i++) {
        if (Character.isDigit(str.charAt(i)) {                           
            sb.append(str.charAt(i));
        } else {                             //clear buffer to take next num
            if (sb.length() != 0) {
                count += (Integer.parseInt(sb.toString()));
                sb.setLength(0);
            }
        }
    }
    if (sb.length() != 0) {
        count += (Integer.parseInt(sb.toString()));
    }

    return count;
    }
Rk R Bairi
  • 1,289
  • 7
  • 15
  • 39
0

Here's how I did mine. (I have comments inside).

public int sumNumbers(String str) 
  {
    //Create a sum for the program.
    int sum = 0;
    //Create a blank string
    String temp = "";
    //Create a for loop with i iterations, the amount of str.length().
    for (int i = 0; i < str.length(); i++)
    {
      //If we are not on the last iteration,
      if (i >= 0 && i < str.length() - 1)
      {
        //If the current character is a digit,
        if (Character.isDigit(str.charAt(i)))
        {
          //We add the current character to the temporary String
          temp = temp + str.charAt(i);
          //If the next character is not a digit, we add the temporary String to the sum.
          //And wipe out the temporary string so that when we have another number, we can add it.
          if (!Character.isDigit(str.charAt(i + 1)))
          {
            sum = sum + Integer.parseInt(temp);
            temp = "";
          }
        }
      }
      //If we are on the last iteration, we do all three without conditions because
      //We know it ends with the last character in the String.
      if (i == str.length() - 1)
      {
        if (Character.isDigit(str.charAt(i)))
        {
          temp = temp + str.charAt(i);
          sum = sum + Integer.parseInt(temp);
          temp = "";
        }
      }
    }
    //We return the sum of the numbers.
    return sum;
  }
0
Using String builder the performance is slightly improved 


public static int sumNumbers(String str) {
int sum = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);

if (Character.isDigit(c)) {
sb.append(c);
} else {
if (sb.length() > 0) {
sum = sum + Integer.parseInt(sb.toString());
sb.setLength(0);
}
}
}
return sum + Integer.parseInt(sb.toString());
}
jegadeesh
  • 109
  • 2
  • 8
  • Hello, and welcome to StackOverflow. Please format your code, and add some explanation to the answer. – Chait Mar 07 '17 at 03:34
0

Solution with single for loop. Advantage of Using string builder will improve performance by 20%.

public static int sumNumbers(String str) {
        int sum = 0;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);

            if (Character.isDigit(c)) {
                sb.append(c);
            } else {
                if (sb.length() > 0) {
                    sum = sum + Integer.parseInt(sb.toString());
                    sb.setLength(0);
                }
            }
        }
        return sum + Integer.parseInt(sb.toString());
    }
jegadeesh
  • 109
  • 2
  • 8
0

This is a solution based off another post that I'm happy with. What's happening is appending each number to a StringBuilder and adding a space for non-numbers. Then, replace all double+ spaces with a single space and parse + sum it from a stream of the split..

public  int sumNumbers(String str){
  int len = str.length();
  StringBuilder nums = new StringBuilder();

  for(int i=0; i< len; i++){
      char c = str.charAt(i);
      if(Character.isDigit(c)) nums.append(c);
      else nums.append(" ");
  }
  String result = nums.toString().trim().replaceAll(" +", " ");
  return result.equals("") ? 0 : Arrays.stream(result.split(" ")).mapToInt(Integer::parseInt).sum();
}
Taladork
  • 41
  • 2
0
public int sumNumbers(String str) {
int count = 0;
int i =0;
while(i<str.length()){
boolean isDigit = Character.isDigit(str.charAt(i));
int j =i;
String tote = "";
while(isDigit==true&&j<str.length()){
 if(Character.isDigit(str.charAt(j))==true)
 {tote += str.charAt(j);
 j++;}
 else
 break;
}
if(tote.length() > 0)
{count += Integer.parseInt(tote);
i+=tote.length();}
else
{i++;}

}
return count;}

This was the easiest way for me!

0

Here is my answer

public int sumNumbers(String str) {
  String num = "";
  int total= 0;

  for(int i=0;i<str.length();i++){

    if(Character.isDigit(str.charAt(i))){ // detected a number
        int pos = i;
        while(pos < str.length() && Character.isDigit(str.charAt(pos))){
          pos++; // running the loop until we reach the end of the digits that comprise the number

        }
          //Now adding the number to the total
         total += Integer.parseInt(str.substring(i,pos));  
          i = pos; // skipping the position of iterator to past the obtained number 
    }


  }

  return total;//returning result


}
Varad Paralikar
  • 81
  • 1
  • 11
  • Plese explain you answer with proper comment. – Kaushik Burkule Oct 30 '19 at 18:22
  • Well In the for loop I first detect if a char is digit then I run a while loop for the chars that are in front of our digit char to get the whole number then I just add the number obtained to the total and skip the loop iterator (here i) to past the position of obtained number ( i = pos) simple :) – Varad Paralikar Oct 30 '19 at 18:46
0
public static int sumNumbers(String str) {
        int result = 0;
        StringBuilder sb = new StringBuilder();
        if (str.length() < 1) return 0;
        for (int i = 0; i < str.length(); i++) {
            if (Character.isDigit(str.charAt(i))) {
                sb.append(str.charAt(i));
            } else {
                if (sb.length() > 0) {
                    result += Integer.parseInt(sb.toString());
                    sb.delete(0, sb.length());  //we need to clear the stringBuilder to account for new Numbers
                }
            }
        }
        if (sb.length() > 0) {
            result += Integer.parseInt(sb.toString());
        }
        return result;
    }
0
public int sumNumbers(String str) {
      String nums = "";
      int sum = 0;
      for (int i = 0; i < str.length(); i++){
        if (Character.isDigit(str.charAt(i))){
          nums += str.charAt(i);
          if (i == str.length()-1 && Character.isDigit(str.charAt(i)))
            sum += Integer.parseInt(nums);
        }
        else if (i > 0 && !Character.isDigit(str.charAt(i)) && Character.isDigit(str.charAt(i-1))){
          sum += Integer.parseInt(nums);
          nums = "";
        }
      }
      return sum;
    }
justNate
  • 1
  • 2
  • this uses a for loop that checks whether a certain index is a character and if it is, then parse that character to a integer. Since Integer.parseInt() takes in a string we need to turn the character into a string. – justNate Jul 20 '20 at 15:34
  • This does not solve the problem. Several tests fail with this answer. (https://codingbat.com/prob/p121193) – tim-montague Aug 06 '20 at 07:56
  • @tfmontague this should fix that – justNate Aug 07 '20 at 13:26
0

CodingBat sumNumbers solution

  • Uses one for-loop, and avoids special-case logic
  • Uses integers, and avoids method calls
public int sumNumbers(String str) {
  int sum = 0;
  int num = 0;

  // If the string is closed,
  // we don't have to write a special case
  // to sum in numbers at the end of a string
  String closedString = str + ".";

  for (int i = 0; i < closedString.length(); i += 1) {
    // Characters are just integers
    int c = (int) closedString.charAt(i);

    if (c >= '0' && c <= '9') {
      // ParseInt alternative
      // Decimals are base 10
      num = num * 10 + c - '0';
    } else {
      sum += num;
      num = 0;
    }
  }

  return sum;
}

Or maybe you have other stuff to do?

public int sumNumbers(String str) {
  return Arrays
    .stream(str.split("\\D+"))
    .filter(s -> !s.equals(""))
    .mapToInt(Integer::parseInt)
    .sum();
}
tim-montague
  • 16,217
  • 5
  • 62
  • 51
0

My solution:

public int sumDigits(String str) {
  int counter = 0;
  
  for (int i = 0; i < str.length(); i++) {
    if (Character.isDigit(str.charAt(i))) {
      counter += Integer.parseInt(str.valueOf(str.charAt(i)));
    }
  }
  
  return counter;
}

It passed all the tests on CodingBat.

Evgeniy
  • 140
  • 1
  • 8
-1

See My code.

    public static int sumNumbers(String str) {
        char[] characters= str.toCharArray();
        int start=-1,end,sum=0,prev=0;
        for(int i=0; i<str.length(); i++){
            if(i==0) {
                if (Character.isDigit(characters[0])) {
                    start = 0;
                }
            }else{
                if (Character.isDigit(characters[i]) && !Character.isDigit(characters[i-1])) {
                    start = i;
                }
                if (!Character.isDigit(characters[i]) && Character.isDigit(characters[i-1])) {
                    end = i;
                    if(start>-1){
                        sum+=Integer.parseInt(str.substring(start,end));
                    }
                }
            }
            if(i==str.length()-1){
                if(start>-1) {
                    sum += Integer.parseInt(str.substring(start));
                }
            }
        }
        return sum;
    }