15

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){
      /* ... */
  }
}
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
Manu
  • 3,179
  • 23
  • 57
  • 69

16 Answers16

30

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, 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.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 1
    @Oscar.. Requirement is, should not use any wrapper classes – Manu Jan 17 '12 at 11:29
  • 1
    You don't need to convert the string to a char array. Use `str.charAt` instead. – dogbane Jan 17 '12 at 11:35
  • @dogbane but doing so will call a method each time, I prefer to do the conversion once and direct array accesses afterwards – Óscar López Jan 17 '12 at 11:40
  • 1
    `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: http://stackoverflow.com/questions/196830/what-is-the-easiest-best-most-correct-way-to-iterate-through-the-characters-of-a – dogbane Jan 17 '12 at 11:47
  • 1
    @Manu Where are those wrapper classes? I can't see them in this solution. – MockerTim Jan 17 '12 at 11:50
  • @dogbane right, but the link you posted doesn't mention which one is faster. Sure, `toCharArray` copies the string's internal char[] to a new char[], but afterward the direct array access will be faster than repeatedly calling `charAt`. A benchmark would be interesting, for different problem sizes. – Óscar López Jan 17 '12 at 11:53
  • @ÓscarLópez one of the answers on that question does have a benchmark which shows that `charAt` took 3138msec and `toCharArray` took 9568msec – dogbane Jan 17 '12 at 12:01
  • Why is it necessary to do the "-'0'" part? What purpose does that have? – superdemongob Sep 03 '13 at 13:18
  • @superdemongob That's necessary for converting a digit represented as a `char` into an `int` – Óscar López Sep 03 '13 at 13:58
  • Is the check for overflow condition forgotten or m I missing something? – Shilpa Aug 09 '16 at 13:40
  • @Shilpa it says in the answer: the check is not done, it's up to you – Óscar López Aug 09 '16 at 14:37
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!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
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;
}
user1559897
  • 1,454
  • 2
  • 14
  • 27
  • 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 Sep 18 '15 at 02:58
  • 2
    @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'. – Mohanasundaram Veeramuthu Sep 26 '15 at 16:24
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);
}
Sandy
  • 226
  • 2
  • 4
  • 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. – Hengameh Sep 18 '15 at 02:59
  • 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 – Sandy Oct 01 '15 at 21:56
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;
}
Arcturus
  • 2,902
  • 2
  • 19
  • 11
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
user1386966
  • 3,302
  • 13
  • 43
  • 72
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
maress
  • 3,533
  • 1
  • 19
  • 37
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;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rohi
  • 385
  • 6
  • 22
  • Sorry I haven't seen the answer below, I had the window kept open while I was at lunch before actually posting it :) – Rohi Jan 17 '12 at 12:43
  • what does this mean? `chars[j]-48`. Thanks for sharing the code. – Hengameh Sep 18 '15 at 03:01
  • I meant that a similar solution was already posted, just I didn't notice it :) – Rohi Sep 18 '15 at 09:19
  • Actually, I was asking about this: `chars[j]-48`. Thanks anyway :) – Hengameh Sep 18 '15 at 11:43
  • ops :) if you take the ASCII table http://www.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 – Rohi Oct 11 '15 at 08:21
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

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;
    }
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;
}
Marcin Petrów
  • 1,447
  • 5
  • 24
  • 39
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;
 }
}
Anup Gupta
  • 1,993
  • 2
  • 25
  • 40
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);
}

}

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);
  • While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) 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! – Waqar UlHaq Feb 25 '20 at 16:37
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;
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-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"));
}

}

  • 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. – Studocwho Nov 26 '18 at 22:09
  • 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. – Studocwho Nov 28 '18 at 02:15
  • 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. – Mahendra Sri Dayarathna Dec 01 '18 at 01:36