在Java中将字符串手动转换为整数

15

我有一个由数字序列组成的字符串 (例如 "1234")。如何在不使用 Java 库函数(比如 Integer.parseInt)的情况下将这个 String 转换为 int 呢?

public class StringToInteger {
  public static void main(String [] args){
    int i = myStringToInteger("123");
    System.out.println("String decoded to number " + i);
  }

  public int myStringToInteger(String str){
      /* ... */
  }
}

7
如果不想使用Integer.parseInt()函数,请复制粘贴其代码。为什么要提出这样一个荒谬的要求? - JB Nizet
6
哇,不到两分钟就有四个人回答了,却没有看清问题。 真是太神奇了:) - TacticalCoder
3
@JB Nizet:正要评论这个(粘贴parseInt代码)。这可能是一项作业……而“学习编程”从来不是荒谬的要求:) - TacticalCoder
5
这可能是一个面试问题或作业任务... - mcfinnigan
16个回答

30

这个有什么问题吗?

int i = Integer.parseInt(str);

编辑:

如果您确实需要手动进行转换,请尝试以下方法:

public static int myStringToInteger(String str) {
    int answer = 0, factor = 1;
    for (int i = str.length()-1; i >= 0; i--) {
        answer += (str.charAt(i) - '0') * factor;
        factor *= 10;
    }
    return answer;
}

如果数字是正整数,上述代码将正常工作。如果数字是负数,则需要进行一些检查,但我会把这留给读者作为练习。


1
@Oscar.. 要求是不使用任何包装类。 - Manu
1
你不需要将字符串转换为字符数组。可以使用 str.charAt - dogbane
1
toCharArray将整个字符串复制到char数组中,而str.charAt每次只访问底层的char数组索引。此外,请参阅:https://dev59.com/dnVC5IYBdhLWcg3wvT7g - dogbane
1
@Manu,那些包装类在哪里?在这个解决方案中我找不到它们。 - MockerTim
为什么需要执行“-'0'”这一步骤?它有什么作用? - superdemongob
显示剩余6条评论

7
如果标准库不被允许,解决这个问题有很多方法。一种思考方式是使用递归函数:
1. 如果n小于10,只需将其转换为一个字符的字符串,该字符串包含它的数字。例如,3变成“3”。 2. 如果n大于10,则使用除法和模运算来获取n的最后一位数字和由除去最后一位数字形成的数字。递归地获取前几位的字符串,然后附加适当的字符作为最后一位数字。例如,如果n是137,则递归计算“13”,并附加“7”以得到“137”。
你需要处理0和负数的情况,但除此之外,这可以相当简单地完成。
因为我怀疑这可能是一项作业(而且在一些学校中确实是这样),所以我会将实际转换留给读者作为练习。:-)
希望这可以帮到你!

4

在这种情况下使用long而不是int。 您需要检查溢出情况。

public static int StringtoNumber(String s) throws Exception{
    if (s == null || s.length() == 0)
        return 0;
    while(s.charAt(0) == ' '){
        s = s.substring(1);
    }
    boolean isNegative = s.charAt(0) == '-';
    if (s.charAt(0) == '-' || (s.charAt(0) == '+')){
        s = s.substring(1);
    }

    long result = 0l;
    for (int i = 0; i < s.length(); i++){
        int value = s.charAt(i) - '0';
        if (value >= 0 && value <= 9){
            if (!isNegative && 10 * result + value > Integer.MAX_VALUE ){
                throw new Exception();
            }else if (isNegative && -1 * 10 * result - value < Integer.MIN_VALUE){
                throw new Exception();
            }
            result = 10 * result + value;
        }else if (s.charAt(i) != ' '){
            return (int)result;
        }
    }
    return isNegative ? -1 * (int)result : (int)result;
}

您能否解释一下为什么我们要减去 '0' 来获取该值?“int value = s.charAt(i) - '0'”。我不理解这行代码。 - Hengameh
2
@Hengameh 字符 '0' 的 ASCII 值为 48。如果您查看 ASCII 表,所有形成整数的后续字符(1、2、..9)的 ASCII 值都以 1 的增量递增。在上面的代码中,user1559897 利用了这一事实,并将绝对整数值作为与字符 '0' 的 ASCII 值之差获得。 - Mohanasundaram Veeramuthu

3

这里提供一种与已发布答案不同的方法。您可以从前面遍历字符串并构建数字。

 public static void stringtoint(String s){      
    boolean isNegative=false;
    int number =0;      
    if (s.charAt(0)=='-') {
        isNegative=true;            
    }else{
        number = number* 10 + s.charAt(0)-'0';
    }

    for (int i = 1; i < s.length(); i++) {

        number = number*10 + s.charAt(i)-'0';           
    }
    if(isNegative){
        number = 0-number;
    }
    System.out.println(number);
}

请问为什么我们要减去'0'才能得到值?s.charAt(i) - '0'。我不理解这行代码。感谢分享代码。 - Hengameh
如果您打印s.charAt(i),它将打印字符的ASCII码。因此,为了获取实际数字,我们从字符串中的字符减去'0'的ASCII码。 - Sandy

2

如果有正确的提示,我认为大多数高中学历的人都可以自己解决这个问题。每个人都知道 134 = 100x1 + 10x3 + 1x4

大多数人错过的关键部分是,如果你在Java中这样做

 System.out.println('0'*1);//48

代码将会获取ASCII表字符0的十进制表示,并将其乘以1。

ASCII表中,字符0的十进制表示为48。因此,上述代码行将打印48。所以如果你做类似于'1'-'0'的操作,这等同于49-48。在ASCII表中,字符0到9是连续的,因此你可以从0到9选择任意字符并减去0来获得它的整数值。一旦你获得了字符的整数值,将整个字符串转换为整数就很简单。

这是另一种解决方案。

String a = "-12512";
char[] chars = a.toCharArray();
boolean isNegative = (chars[0] == '-');
if (isNegative) {
    chars[0] = '0';
}

int multiplier = 1;
int total = 0;

for (int i = chars.length - 1; i >= 0; i--) {
    total = total + ((chars[i] - '0') * multiplier);
    multiplier = multiplier * 10;
}

if (isNegative) {
    total = total * -1;
}

1
使用Java 8,你可以做到以下内容:
public static int convert(String strNum)
{
   int result =strNum.chars().reduce(0, (a, b)->10*a +b-'0');
}
  1. 将srtNum转换为字符
  2. 对于每个字符(表示为'b')-> 'b' -'0'将给出相对数字
  3. 将所有数字相加(初始值为0) (每次在字符上执行操作时,进行- > a = a * 10

你好!能否请您解释一下第二步和第三步?谢谢。 - Celestine Babayaro

1
使用这个:
static int parseInt(String str) {
    char[] ch = str.trim().toCharArray();
    int len = ch.length;
    int value = 0;
    for (int i=0, j=(len-1); i<len; i++,j--) {
        int c = ch[i];
        if (c < 48 || c > 57) {
            throw new NumberFormatException("Not a number: "+str);
        }
        int n = c - 48;
        n *= Math.pow(10, j);
        value += n;
    }
    return value;
}

顺便提一下,你可以处理负整数的特殊情况,否则它会抛出异常NumberFormatException

1
你可以这样做:从字符串中,为每个元素创建一个字符数组,保留索引并将其ASCII值乘以实际反向索引的幂。求和部分因子,你就得到了它。
只需要使用很少的强制转换来使用Math.pow(因为它返回一个双精度浮点数),但是你可以通过创建自己的幂函数来避免它。
public static int StringToInt(String str){
    int res = 0;
    char [] chars = str.toCharArray();
    System.out.println(str.length());
    for (int i = str.length()-1, j=0; i>=0; i--, j++){
        int temp = chars[j]-48;
        int power = (int) Math.pow(10, i);
        res += temp*power;
        System.out.println(res);
    }
    return res;
}

抱歉我没有看到下面的答案,我在午餐时一直保持着窗口打开,然后才发布它 :) - Rohi
这是什么意思?chars[j]-48。感谢分享代码。 - Hengameh
我的意思是已经有类似的解决方案发布了,只是我没有注意到 :) - Rohi
实际上,我在问的是这个:chars[j]-48。无论如何谢谢 :) - Hengameh
抱歉 :) 如果您查看ASCII表http://www.asciitable.com/,您会发现整数从索引48开始。由于我正在使用ASCII值,因此需要减去48。请注意,没有输入检查-如果没有数字,则转换将出错。 - Rohi

0
public int myStringToInteger(String str) throws NumberFormatException 
{
    int decimalRadix = 10; //10 is the radix of the decimal system

    if (str == null) {
        throw new NumberFormatException("null");
    }

    int finalResult = 0;
    boolean isNegative = false;
    int index = 0, strLength = str.length();

    if (strLength > 0) {
        if (str.charAt(0) == '-') {
            isNegative = true;
            index++;
        } 

        while (index < strLength) {

            if((Character.digit(str.charAt(index), decimalRadix)) != -1){   
                finalResult *= decimalRadix;
                finalResult += (str.charAt(index) - '0');
            } else throw new NumberFormatException("for input string " + str);

            index++;
        }

    } else {
        throw new NumberFormatException("Empty numeric string");
    }

    if(isNegative){
        if(index > 1)
            return -finalResult;
        else
            throw new NumberFormatException("Only got -");
    }

    return finalResult;
}

结果: 1)对于输入“34567”,最终结果将是:34567 2)对于输入“-4567”,最终结果将是:-4567 3)对于输入“-”,最终结果将是:java.lang.NumberFormatException:仅获得- 4)对于输入“12ab45”,最终结果将是:java.lang.NumberFormatException:输入字符串12ab45

0

这是完整的程序,包括所有正面和负面条件,而不使用库

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接