Algorithm and data structure face questions (23)-converting strings to plastic __java

Source: Internet
Author: User
Tags benchmark bitwise comparison
Topic


Enter a string representing an integer that converts the string to an integer and outputs it. For example, the input string "345" outputs an integer 345.

Personal Understanding


This side of the question does not involve algorithms and data structure, mainly to investigate your programming habits, there is no awareness to do some validation, the input of the checksum. Small problem verification in large areas. Let's take a look at the handling of this problem in the Java API


Code


public static int parseint (String s) throws NumberFormatException {        return
parseint (s,10);
           } public static int parseint (String s, int radix) throws NumberFormatException { /* Warning:this method invoked early during VM initialization * before Integercache Initialized.
         Care must is taken to not with the valueof method.
        */if (s = = null) {throw new NumberFormatException ("null");
                                            } if (Radix < Character.min_radix) {throw new NumberFormatException ("radix" + Radix +
        "Less than Character.min_radix");
                                            } if (Radix > Character.max_radix) {throw new NumberFormatException ("radix" + Radix +
        "Greater than Character.max_radix");
        int result = 0; Boolean NegatIve = false;
        int i = 0, Len = s.length ();
        int limit =-integer.max_value;
        int multmin;

        int digit;
            if (Len > 0) {char firstchar = s.charat (0); if (Firstchar < ' 0 ') {//Possible leading ' + ' or '-' if (firstchar = = ') {Negat
                    Ive = true;
                Limit = Integer.min_value;

                else if (firstchar!= ' + ') throw numberformatexception.forinputstring (s);
                if (len = = 1)//cannot have lone "+" or "-" throw numberformatexception.forinputstring (s);
            i++;
            } multmin = Limit/radix; while (I < len) {//accumulating negatively avoids surprises near max_value digit = Ch
                Aracter.digit (S.charat (i++), radix);
                if (Digit < 0) {throw numberformatexception.forinputstring (s);
    }            if (Result < Multmin) {throw numberformatexception.forinputstring (s);
                Result *= Radix;
                if (Result < limit + digit) {throw numberformatexception.forinputstring (s);
            Result-= digit;
        } else {throw numberformatexception.forinputstring (s); return negative?
    Result:-result; }

Understanding the following knowledge is good for understanding the above code.


In Java, the difference between >, >>, >>> is
in Java:

> indicates greater than, such as: if (a>b) ... The result is a Boolean type

>> a right shift, such as: int i=15; i>>2 The result is 3, and the removed portion is discarded. The

transition to binary may be better understood, with the result that 0000 1111 (15) to the right 2 digits is 0000 0011 (3), 0001 1010 (18) and the result of right shift 3 is 0000 0011 (3).

J>>>i is the same as the result of j/(int) (Math.pow (2,i)), where I and J are shaping.


Let's take a step-by-step debug to look at the processing code


1. Enter


public static void Main (string[] args) {
        //10
        integer.parseint ("235";

    }

Above is the entry function.



The string passed in is "235". When you enter a method body, the first step is to determine whether it is null. If empty, throws an exception. Then it is to determine whether the cardinality is within the permissible range [2-32], and we are passing in 10. Within the permissible


2. Initialization Operation




Result: The results we need

Negative: is a negative number. Default to False

I: A cursor that points to the current index of the string, traversing the characters in the string.

Len: String size

Limit: A negative value for the maximum size of the shaping. than the minimum size of the plastic-2147483648 1.

Multmin:

Digit: Preserving the transformed value of a character after conversion


3. Determine whether the first character of the string is a sign bit (+,-)


Char firstchar = s.charat (0);
            if (Firstchar < ' 0 ') {//Possible leading ' + ' or '-'
                if (firstchar = = ') {
                    negative = true;
                    Limit = Integer.min_value;
                } else if (firstchar!= ' + ')
                    throw numberformatexception.forinputstring (s);

                if (len = = 1)//cannot have lone "+" or "-"
                    throw numberformatexception.forinputstring (s);
                i++;
            }

If the first character is '-', set the value of negative to true, and set limit to the minimum value for the shape: Integer. Min_value.

If the first character is not '-' and then append to determine if it is a plus, if not the plus sign, throw an exception

And then determine whether the string size is 1, if 1, does not meet the requirements, because only the sign bit is definitely not copied the definition of integers.

The final string traversal of the cursor has been increased by 1. Indicates that the traversal is to start with the second character, because the first character we have judged is a sign bit.


4. Traverse String




First we assign a value to the value of the multmin, what does the value have to do with it, and why is it divided by the benchmark value. It's not clear yet. Let's just leave it there.


Multmin = Limit/radix;

Then start looping to get the value of each character in the string


while (I < len) {
                //accumulating negatively avoids surprises near max_value digit
                = character.digit (S.charat (i + +), radix);
                if (Digit < 0) {
                    throw numberformatexception.forinputstring (s);
                }
                if (Result < Multmin) {
                    throw numberformatexception.forinputstring (s);
                }
                Result *= Radix;
                if (Result < limit + digit) {
                    throw numberformatexception.forinputstring (s);
                }
                Result-= digit;
            }

First understand the first statement block


digit = Character.digit (S.charat (i++), radix);



You can see the ASCII code for the character ' 2 ' is 50, and we're actually 50.




In the above method, you first convert the character to ASCII, and then call the Overwrite function digit.



This time it will be found that the 50, which is the ASCII value of ' 2 '. After entering the function, the Characterdata.of method is first used to get the range of the code set to which the character belongs.


Static final characterdata of (int ch) {
        if (ch >>> 8 = 0) {     //Fast-path return
            CharacterDataLatin1. instance;
        } else {
            switch (ch >>>) {  //plane 00-16 case
            (0): return
                characterdata00.instance;
            Case (1): Return
                characterdata01.instance;
            Case (2): return
                characterdata02.instance;
            Case (a): return
                characterdata0e.instance;
            Case (M)://Private Use Case
            (a):   //Private use return
                characterdataprivateuse.instance;
            Default: Return
                characterdataundefined.instance}
            }
    

First ch>>>8 the bitwise operation. It means CH/2 8 times. The main is to determine whether the Latin character range of values can be expressed. Obviously we can use the Latin character encoding to denote the range of characters. So the method returns.


Digit method of entering CharacterDataLatin1 class


int digit (int ch, int radix) {
        int value =-1;
        if (radix >= character.min_radix && radix <= character.max_radix) {
            int val = getProperties (ch);
            int kind = val & 0x1F;
            if (kind = = Character.decimal_digit_number) {
                value = ch + ((val & 0x3e0) >> 5) & 0x1F;
            }
            else if ((val & 0xc00) = = 0x00000c00) {
                //Java supradecimal digit
                value = (ch + ((val & 0x3e0) >> 5 ) & 0x1F) +
            }
        }
        Return (value < radix)? Value:-1;
    }

The first thing to judge is whether the benchmark is in line with the requirements, and this is already over, no need to say. Then enter the GetProperties method.


int getProperties (int ch) {
        char offset = (char) ch;
        int props = A[offset];
        return props;
    }

Returns a large number, which is a Unicode value; for the moment, the number of the Unicode code converted to 10, followed by a 0x1f of 16. bit andOperation.




Why do bits and operations, first look at what is in the operation.


& is by binary bitwise with, that is 1 & 1 = 1   1 & 0 = 0   3 & 1→11 (binary) & 1 = 1

The 0x1f above indicates that the binary number is: 00011111. If you follow the above algorithm, then only the 5 digits of 1 will be retained.


10 binary number 402667017 into binary number


11000000000000011011000001001

Then the latter 5 digits are 01001&11111 = 01001, so we know that it is actually the second 5 digit binary code, the other position is changed to 0. The resulting 10 number is 9.



According to this code we know, and 0x1f is located to calculate the category it is in. 9 represents the general category "Nd" in the Unicode specification. And then do the following bit operations


Value = ch + ((val & 0x3e0) >> 5) & 0x1F;

0X3E0 = 1111 0000 &10 0000 1001 = 10 0000 0000 Then right shift 5 bit to get 10 000 due to priority + greater than &. So first the addition operation 50+16 = 66 (1000010)

1000010&11111 = 10 =,10 is 2, so the last value = 2;


So the method returns to Integer.parseint and gets digit = 2;


while (I < len) {
                //accumulating negatively avoids surprises near max_value digit
                = character.digit (S.charat (i + +), radix);
                if (Digit < 0) {
                    throw numberformatexception.forinputstring (s);
                }
                if (Result < Multmin) {
                    throw numberformatexception.forinputstring (s);
                }
                Result *= Radix;
                if (Result < limit + digit) {
                    throw numberformatexception.forinputstring (s);
                }
                Result-= digit;
            }

Then there are 2 if judgments. It is easy to understand that you cannot be negative because the number of digits calculated at this time is not symbolic.

What do you mean by the latter one to Judge Result<multmin? Because result is about to *10. If Result<multmin, then the *10 words certainly exceed the minimum range. Why this place can not directly after the comparison, first multiply after comparison is meaningless, if beyond the scope of the error has been, the subsequent judgment will not be carried out. The next sentence is also true, since result is about to be subtracted from digit, but the subtraction is based on the premise that it cannot be crossed. So there's a predetermined judgment.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.