14

I'm having string consisting of a sequence of digits (e.g. "1234"). How to return the String as an int without using Java's library functions like Integer.parseInt?

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){
      /* ... */
  }
}
4
  • 8
    Copy-paste the code of Integer.parseInt() if you don't want to use it. Why such an absurd requirement? Commented Jan 17, 2012 at 11:26
  • 6
    Wow. Four people answering without reading the question in less than two minutes. Quite amazing : ) Commented Jan 17, 2012 at 11:27
  • 3
    @JB Nizet: was going to comment exactly that (pasting the parseInt code). It may be homework... And "learning to program" is never an absurd requirement : ) Commented Jan 17, 2012 at 11:28
  • 6
    @JBNizet could be an interview question or homework assignment... Commented Jan 17, 2012 at 11:29

17 Answers 17

29

And what is wrong with this?

int i = Integer.parseInt(str);

EDIT :

If you really need to do the conversion by hand, try this:

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

The above will work fine for positive integers - assuming that the string only contains numbers, otherwise the result is undefined. If the number is negative you'll have to do a little checking first, but I'll leave that as an exercise for the reader.

Sign up to request clarification or add additional context in comments.

12 Comments

@Oscar.. Requirement is, should not use any wrapper classes
You don't need to convert the string to a char array. Use str.charAt instead.
@dogbane but doing so will call a method each time, I prefer to do the conversion once and direct array accesses afterwards
toCharArray copies the whole string into a char array, whereas str.charAt just accesses the underlying char array index each time. Also, take a look at: stackoverflow.com/questions/196830/…
@Manu Where are those wrapper classes? I can't see them in this solution.
|
7

If the standard libraries are disallowed, there are many approaches to solving this problem. One way to think about this is as a recursive function:

  1. If n is less than 10, just convert it to the one-character string holding its digit. For example, 3 becomes "3".
  2. If n is greater than 10, then use division and modulus to get the last digit of n and the number formed by excluding the last digit. Recursively get a string for the first digits, then append the appropriate character for the last digit. For example, if n is 137, you'd recursively compute "13" and tack on "7" to get "137".

You will need logic to special-case 0 and negative numbers, but otherwise this can be done fairly simply.

Since I suspect that this may be homework (and know for a fact that at some schools it is), I'll leave the actual conversion as an exercise to the reader. :-)

Hope this helps!

Comments

4

Use long instead of int in this case. You need to check for overflows.

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

2 Comments

Could you please explain why we deduct '0' to get the value? int value = s.charAt(i) - '0'. I don't understand this line.
@Hengameh ASCII value of the character '0' = 48. And if you look at the ASCII table, all other subsequent characters that form an integer (1,2,..9) have ASCII values in increments of 1. In the above code, user1559897 uses this fact and obtains the absolute integer value as the difference from ascii value of character '0'.
3

Alternate approach to the answer already posted here. You can traverse the string from the front and build the number

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

2 Comments

Could you please explain why we deduct '0' to get the value? s.charAt(i) - '0'. I don't understand this line. thanks for sharing the code.
if you print s.charAt(i) it prints the ascii code of the character. So to get the actual number we subtract the ascii code of '0' from the character in the string
2

Given the right hint, I think most people with a high school education can solve this own their own. Every one knows 134 = 100x1 + 10x3 + 1x4

The key part most people miss, is that if you do something like this in Java

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

it will pick the decimal representation of character 0 in ascii chart and multiply it by 1.

In ascii table character 0 has a decimal representation of 48. So the above line will print 48. So if you do something like '1'-'0' That is same as 49-48. Since in ascii chart, characters 0-9 are continuous, so you can take any char from 0 to 9 and subtract 0 to get its integer value. Once you have the integer value for a character, then converting the whole string to int is straight forward.

Here is another one solution to the problem

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

Comments

1

Use this:

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

And by the way, you can handle the special case of negative integers, otherwise it will throw exception NumberFormatException.

Comments

1

You can do like this: from the string, create an array of characters for each element, keep the index saved, and multiply its ASCII value by the power of the actual reverse index. Sum the partial factors and you get it.

There is only a small cast to use Math.pow (since it returns a double), but you can avoid it by creating your own power function.

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

5 Comments

Sorry I haven't seen the answer below, I had the window kept open while I was at lunch before actually posting it :)
what does this mean? chars[j]-48. Thanks for sharing the code.
I meant that a similar solution was already posted, just I didn't notice it :)
Actually, I was asking about this: chars[j]-48. Thanks anyway :)
ops :) if you take the ASCII table asciitable.com you'll see that integers start from index 48. Since I'm using the ascii value, I need to subtract 48. Just note that there's no input check - if there are no numbers, the conversion will be wrong
1

Using Java 8 you can do the following:

public static int convert(String strNum)
{
   int result =strNum.chars().reduce(0, (a, b)->10*a +b-'0');
}
  1. Convert srtNum to char
  2. for each char (represented as 'b') -> 'b' -'0' will give the relative number
  3. sum all in a (initial value is 0) (each time we perform an opertaion on a char do -> a=a*10

1 Comment

Hi! Could you please explain step 2 and step 3? Thanks
0

Make use of the fact that Java uses char and int in the same way. Basically, do char - '0' to get the int value of the char.

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

    public static int myStringToInteger(String str) {
        int sum = 0;
        char[] array = str.toCharArray();
        int j = 0;
        for(int i = str.length() - 1 ; i >= 0 ; i--){
            sum += Math.pow(10, j)*(array[i]-'0');
            j++;
        }
        return sum;
    }
}

Comments

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

Outcome: 1) For the input "34567" the final result would be: 34567 2) For the input "-4567" the final result would be: -4567 3) For the input "-" the final result would be: java.lang.NumberFormatException: Only got - 4) For the input "12ab45" the final result would be: java.lang.NumberFormatException: for input string 12ab45

Comments

0
public static int convertToInt(String input){
        char[] ch=input.toCharArray();
        int result=0;
        for(char c : ch){
            result=(result*10)+((int)c-(int)'0');
        }
        return result;
    }

Comments

0

Maybe this way will be a little bit faster:

public static int convertStringToInt(String num) {
     int result = 0;

     for (char c: num.toCharArray()) {
        c -= 48;
        if (c <= 9) {
            result = (result << 3) + (result << 1) + c;
        } else return -1;
    }
    return result;
}

Comments

0

This is the Complete program with all conditions positive, negative without using library

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

Comments

0
Works for Positive and Negative String Using TDD

//Solution

public int convert(String string) {
    int number = 0;
    boolean isNegative = false;
    int i = 0;
    if (string.charAt(0) == '-') {
        isNegative = true;
        i++;
    }

    for (int j = i; j < string.length(); j++) {
        int value = string.charAt(j) - '0';
        number *= 10;
        number += value;
    }
    if (isNegative) {
        number = -number;
    }

    return number;
}

//Testcases

public class StringtoIntTest {
private StringtoInt stringtoInt;


@Before
public void setUp() throws Exception {
stringtoInt = new StringtoInt();
}

@Test
public void testStringtoInt() {
    int excepted = stringtoInt.convert("123456");
    assertEquals(123456,excepted);
}

@Test
public void testStringtoIntWithNegative() {
    int excepted = stringtoInt.convert("-123456");
    assertEquals(-123456,excepted);
}

}

Comments

0
    //Take one positive or negative number
    String str="-90997865";

    //Conver String into Character Array
    char arr[]=str.toCharArray();

    int no=0,asci=0,res=0;

    for(int i=0;i<arr.length;i++)
    {
       //If First Character == negative then skip iteration and i++
       if(arr[i]=='-' && i==0)
       {
           i++;
       }

           asci=(int)arr[i]; //Find Ascii value of each Character 
           no=asci-48; //Now Substract the Ascii value of 0 i.e 48  from asci
           res=res*10+no; //Conversion for final number
    }

    //If first Character is negative then result also negative
    if(arr[0]=='-')
    {
        res=-res;
    }

    System.out.println(res);

1 Comment

While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations!
-1
public class ConvertInteger {

public static int convertToInt(String numString){
    int answer = 0, factor = 1;

    for (int i = numString.length()-1; i >= 0; i--) {
        answer += (numString.charAt(i) - '0') *factor;
        factor *=10;
    }
    return answer;
}

public static void main(String[] args) {

    System.out.println(convertToInt("789"));
}

}

3 Comments

Please don't just post code as an answer, instead give an explanation of what is different and how it is a solution to the problem.
It is not always clear to either the OP or future Googlers what a code only answer is doing differently to others. To avoid this confusion, please take some time to explain why or how your code solves the problem.
This function to convert a string number an integer without using java build-on functions fro math,string manipulation ,number formatting or printing. please execute the program.
-1

A very neat way to convert strings to int- sees contract as an arraylist input and outputs either null(if not convertable) or a valid value.

package <package>;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.IntStream;

public class SO79073232 {
    public static void main(String ...args) {
        ArrayList<String> strs = new ArrayList<>(Arrays.asList("1","2","200","",null, "two"));
        strs.stream().map(SO79073232::toInt).forEach(System.out::println);
    }

    private static int getInt(char c) {
        if (Character.isDigit(c)) {
            return (int) (c - '0');
        } else {
            throw new ArithmeticException(String.format("char %c is not a digit", c));
        }
    }

    private static Integer toInt(String s) {
        try {
            return IntStream.range(0, s.length()).map(i -> (int) (Math.pow(10, s.length() - i - 1)) * (int) getInt(s.charAt(i))).sum();
        } catch (Exception e) {
           return null;
        }
    }
}

it outputs:

1
2
200
0
null
null

The beauty is how it leverages 'streams' and map/reduce of Java lambda programming.

1 Comment

why would someone downvote it? just look at how well it handles corner cases, and is way more efficient!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.