【问题标题】:How to parse a string to an integer without library functions?如何在没有库函数的情况下将字符串解析为整数?
【发布时间】:2009-05-15 09:18:08
【问题描述】:

我最近在一次采访中被问到这个问题:

“你如何在不使用任何库函数且不考虑语言的情况下将 '12345' 形式的字符串解析为其整数表示 12345?”

我想到了两个答案,但面试官说还有第三个。这是我的两个解决方案:

解决方案 1:保留一个映射 '1' => 1、'2' => 2 等的字典。然后一次解析一个字符,在字典中查找字符,然后乘以位置值.对结果求和。

解决方案 2:一次解析一个字符并从每个字符中减去“0”。这将为您提供 '1' - '0' = 0x1、'2' - '0' = 0x2 等。同样,乘以位置值并对结果求和。

谁能想到第三种解决方案可能是什么?

谢谢。

【问题讨论】:

    标签: string parsing integer


    【解决方案1】:

    我想这就是面试官所追求的:

    number = "12345"
    value = 0
    for digit in number:                    //Read most significant digit first
        value = value * 10 + valueOf(digit)
    

    此方法使用的操作远少于您概述的方法。

    【讨论】:

    • 那不是解决方案2(只使用ValueOf())
    • 这不是问题中提到的第二个答案吗?
    • 什么是“valueOf”?库函数?
    • @tanascius:不。这种方法完全避免了“乘以位置值”业务。 @Naveen:不。(见上文)@Neil:不,这是从“1”到 1 等的一种依赖于语言的方式,在 C 中它可能是数字-'0';在某些语言中,地图之类的东西会更方便。 @dan,不客气。
    • 好的,我将“价值位置”理解为 base^position ......这基本上是你的解决方案......这也是我更喜欢的解决方案,所以 +1
    【解决方案2】:

    以相反的顺序解析字符串,使用两种方法之一解析单个数字,将累加器乘以 10,然后将数字添加到累加器中。

    这样您就不必计算位置值。每次得到相同的结果时,将累加器乘以十。

    【讨论】:

      【解决方案3】:

      Artelius 的答案非常简洁且与语言无关,但对于那些寻求更详细的答案和解释以及 C 和 Java 实现的人可以查看此页面:

      http://www.programminginterview.com/content/strings

      向下滚动(或搜索)到“练习题:将 ASCII 编码的字符串转换为整数。”

      【讨论】:

        【解决方案4】:

        //java版本

        public static int convert(String s){
            if(s == null || s.length() == 0){
                throw new InvalidParameterException();
            }
        
            int ret = 0;
        
            boolean isNegtive = false;
        
            for(int i=0;i<s.length();i++){
                char c = s.charAt(i);
        
                if( i == 0 && (c == '-')){
                    isNegtive = true;
                    continue;
                }
        
                if(c - '0' < 0 || c - '0' > 10){
                    throw new InvalidParameterException();
                }
        
                int tmp = c - '0';
        
                ret *= 10;
                ret += tmp;
        
            }
        
            return isNegtive ? (ret - ret * 2) : ret;
        
        
        
        }
        

        //单元测试

        @Test
        public void testConvert() {
        
            int v = StringToInt.convert("123");
            assertEquals(v, 123);
        
            v = StringToInt.convert("-123");
            assertEquals(v, -123);
        
            v = StringToInt.convert("0");
            assertEquals(v, 0);
        
        
        }
        
        @Test(expected=InvalidParameterException.class)
        public void testInvalidParameterException() {
             StringToInt.convert("e123");
        }
        
        @Rule
        public ExpectedException  exception = ExpectedException.none();
        @Test
        public void testInvalidParameterException2() {
        
            exception.expect(InvalidParameterException.class);
            StringToInt.convert("-123r");
        

        }

        【讨论】:

          【解决方案5】:

          保留一个字典,将所有字符串映射到它们的整数对应项,直到某个限制?可能没有多大意义,除了如果上限很小,这可能 更快,例如两位或三位数字。

          【讨论】:

            【解决方案6】:

            您总是可以通过大量的字符串表示查找表尝试二进制搜索!

            没有人谈论效率... :-)

            【讨论】:

              【解决方案7】:
              #include<stdio.h>
              #include<string.h>
              #include<stdlib.h>
              
              int nod(long);
              char * myitoa(long int n, char *s);
              void main()
              {
              
                long int n;
                char *s;
                printf("Enter n");
                scanf("%ld",&n);
                s=myitoa(n,s);
                puts(s);
              }
              
              int nod(long int  n)
              {
                int m=0;
                while(n>0)
                {
                  n=n/10;
                  m++;
                }
                return m;
              }
              
              char * myitoa(long int n, char *s)
              {
              
                int d,i=0;
                char cd;
                s=(char*)malloc(nod(n));
                while(n>0)
                {
                  d=n%10;
                  cd=48+d;
                  s[i++]=cd;
                  n=n/10;
                }
                s[i]='\0';
                strrev(s);
                return s;
              }
              

              【讨论】:

                【解决方案8】:

                这是一个完整的程序,所有条件为正、负,不使用库

                import java.util.Scanner;
                
                
                public class StringToInt {
                 public static void main(String args[]) {
                  String inputString;
                  Scanner s = new Scanner(System.in);
                  inputString = s.nextLine();
                
                  if (!inputString.matches("([+-]?([0-9]*[.])?[0-9]+)")) {
                   System.out.println("error!!!");
                  } else {
                   Double result2 = getNumber(inputString);
                   System.out.println("result = " + result2);
                  }
                
                 }
                 public static Double getNumber(String number) {
                  Double result = 0.0;
                  Double beforeDecimal = 0.0;
                  Double afterDecimal = 0.0;
                  Double afterDecimalCount = 0.0;
                  int signBit = 1;
                  boolean flag = false;
                
                  int count = number.length();
                  if (number.charAt(0) == '-') {
                   signBit = -1;
                   flag = true;
                  } else if (number.charAt(0) == '+') {
                   flag = true;
                  }
                  for (int i = 0; i < count; i++) {
                   if (flag && i == 0) {
                    continue;
                
                   }
                   if (afterDecimalCount == 0.0) {
                    if (number.charAt(i) - '.' == 0) {
                     afterDecimalCount++;
                    } else {
                     beforeDecimal = beforeDecimal * 10 + (number.charAt(i) - '0');
                    }
                
                   } else {
                    afterDecimal = afterDecimal * 10 + number.charAt(i) - ('0');
                    afterDecimalCount = afterDecimalCount * 10;
                   }
                  }
                  if (afterDecimalCount != 0.0) {
                   afterDecimal = afterDecimal / afterDecimalCount;
                   result = beforeDecimal + afterDecimal;
                  } else {
                   result = beforeDecimal;
                  }
                
                  return result * signBit;
                 }
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-09-20
                  • 2019-05-03
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-08-29
                  • 2018-03-21
                  • 1970-01-01
                  相关资源
                  最近更新 更多