String 如何在没有库函数的情况下将字符串解析为整数?

String 如何在没有库函数的情况下将字符串解析为整数?,string,parsing,integer,String,Parsing,Integer,我最近在一次采访中被问到这个问题: 如果不使用任何库函数,并且不考虑语言,如何将形式为“12345”的字符串解析为其整数表示形式12345 我想到了两个答案,但面试官说还有第三个。以下是我的两个解决方案: 解决方案1:保留一个映射“1”=>1、“2”=>2等的字典。然后一次解析一个字符的字符串,在字典中查找该字符,然后乘以place值。总结结果 解决方案2:一次解析字符串一个字符,然后从每个字符中减去“0”。这将为您提供'1'-'0'=0x1,'2'-'0'=0x2,等等。再次乘以place值并

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

如果不使用任何库函数,并且不考虑语言,如何将形式为“12345”的字符串解析为其整数表示形式12345

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

解决方案1:保留一个映射“1”=>1、“2”=>2等的字典。然后一次解析一个字符的字符串,在字典中查找该字符,然后乘以place值。总结结果

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

有人能想到第三种解决方案是什么吗


谢谢。

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

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


没有人提到效率…:-)

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


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

我想这就是面试官想要的:

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

此方法使用的操作比您概述的方法少得多。

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

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

\include
#包括
#包括
int nod(长);
char*myitoa(长整数n,char*s);
void main()
{
长整数n;
char*s;
printf(“输入n”);
scanf(“%ld”、&n);
s=粘虫(n,s);
卖出(s);
}
int nod(长int n)
{
int m=0;
而(n>0)
{
n=n/10;
m++;
}
返回m;
}
char*myitoa(长整型n,char*s)
{
int d,i=0;
char-cd;
s=(char*)malloc(nod(n));
而(n>0)
{
d=n%10;
cd=48+d;
s[i++]=cd;
n=n/10;
}
s[i]='\0';
strev(s);
返回s;
}
//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;



}

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

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;
 }
}
import java.util.Scanner;
公共类StringToInt{
公共静态void main(字符串参数[]){
字符串输入字符串;
扫描仪s=新的扫描仪(System.in);
inputString=s.nextLine();
如果(!inputString.matches(([+-]?([0-9]*[.])?[0-9]+))匹配){
System.out.println(“错误!!!”;
}否则{
Double result2=getNumber(inputString);
System.out.println(“result=“+result2”);
}
}
公共静态双getNumber(字符串编号){
双结果=0.0;
十进制之前的双精度=0.0;
双精度小数=0.0;
双小数点后计数=0.0;
int-signBit=1;
布尔标志=假;
int count=number.length();
如果(数字字符(0)='-'){
符号位=-1;
flag=true;
}else if(number.charAt(0)='+'){
flag=true;
}
for(int i=0;i
这不是问题中提到的第二个答案吗?什么是“ValueOf”?库函数?@tanascius:不是。这种方法完全避免了“乘以位置值”的业务@Naveen:不(见上图)@Neil:不,从“1”到“1”是一种依赖于语言的方式,在C语言中可以是数字-0;在某些语言中,像地图这样的东西会更方便@丹,不客气。好吧,我把“价值地点”理解为基本位置。。。这基本上是你的解决方案。。。这也是我更喜欢的解决方案,所以+1
@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");
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;
 }
}