字符串问题:字符串中数字子串的求和

题目

  给定一个字符串 str, 求其中全部数字串所代表的数字之和。

要求

  1. 忽略小数点,例如 “A1.3”,其中包含两个数字 1 和 3.
  2. 如果紧贴数字子串的左侧出现字符"-", 当连续出现的数量为奇数时,则数字视为负,连续出现的数量为偶数时,则数字视为正。比如,“A-1BC--12”, 其中包含数字 -1 和 12.
  3. 若字符串的长度为N,时间复杂度为 O(N), 额外空间复杂度为 O(1)

举例

  str="A1CD2E33", 返回 36。

  str="A-1B--2C--D6E", 返回7。

解答

  解法的关键在于如何在从左到右遍历 str 时,准确收集每个数字并累加起来。

  1. 生成三个变量,整型变量 res, 表示当前的累加和; 整型变量 num, 表示当前收集到的数字; 布尔型变量 posi, 表示如果把 num 累加到 res 中,num 是正还是负。初始时,res = 0, num = 0, posi = true。

  2. 从左到右遍历 str, 假设遍历到 i 位置的字符 cha, 根据具体的 cha 有不同的处理:

  • 如果 cha 为 ‘0’~‘9’,i 位置的值记为 cur, cur = cha - '0'. 例如字符串 str = "123", 当 cha = '1', cur = 1,  num = 1; 当 cha = '2', cur = 2, num = 12 = 1*10+2; 当 cha = '3', cur = 3, num = 123 = 12*10+3, res = res + 123. 若字符串 str = "-123", 当 cha = '3', cur = 3, num = 123, res = res + (-123)

  具体实现请参考下面代码中的 numSum 方法:

 1 public class Main {
 2     
 3     public static void main(String[] args) {
 4         System.out.println(new Main().numSum("A1CD2E33"));//36
 5         System.out.println(new Main().numSum("A-1B--2C--D6E"));//7
 6         System.out.println(new Main().numSum("-A-1B--2C---D----6E--"));//7
 7     }
 8     
 9     public int numSum(String str){
10         if(str == null || str.length() == 0) return 0;
11         char[] chs = str.toCharArray();
12         int res = 0; //表示累积和
13         int num = 0; //表示当前位置收集到的数字
14         boolean posi = true; //表示收集到的数字是否为正, true 为正, false 为负
15         
16         for(int i = 0, len = str.length(); i < len; i++){
17             char ch = chs[i];
18             if(ch >= '0' && ch <= '9'){//若当前字符为数字字符, 则继续收集
19                 int cur = ch - '0';
20                 num = num * 10 + cur;
21                 if(i == len-1){//若最后一个字符为数字字符, 则将 num 其累加到 res
22                     res += posi? num : -num;
23                 }
24             }else{//若遇到非数字字符, 则将 num 累加到 res
25                 res += posi? num : -num;
26                 num = 0; //将收集到的数值 num 累加后, 需要清空
27                 if(ch == '-'){//若遇到负号'-', 则需要更改当前收集数字 num 的正负
28                     if(i > 0 && chs[i-1] == '-'){
29                         posi = !posi;
30                     }else{
31                         posi = false;
32                     }
33                 }else{//若遇到其他字符, 更改 num 为正
34                     posi = true;
35                 }
36             }
37         }
38         
39         return res;
40     }
41     
42 }

 

posted @ 2019-03-14 16:55  米突小搞羊  阅读(913)  评论(0编辑  收藏  举报