leetcode题解-8. String to Integer (atoi) && 468. Validate IP Address

今天开始刷String部分中等难度的题目,先看第一道

Implement atoi to convert a string to an integer.

Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.

Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button  to reset your code definition.

将字符串转化为int型整数,其实主要有两点需要考虑一个是数的正负号,另一个是溢出问题,此外在判断每一个字符是否为数字即可,可以写出下面的代码:

    //45%
    public static int myAtoi(String str) {
        if (str == null || str.length() == 0)
            return 0;//
        str = str.trim();
        char firstChar = str.charAt(0);
        //sign用于表示数字的正负号,start表示当前向后遍历的索引位置
        int sign = 1, start = 0, len = str.length();
        long sum = 0;
        if (firstChar == '+') {
            sign = 1;
            start++;
        } else if (firstChar == '-') {
            sign = -1;
            start++;
        }
        for (int i = start; i < len; i++) {
            if (!Character.isDigit(str.charAt(i)))
                return (int) sum * sign;
            sum = sum * 10 + str.charAt(i) - '0';
            //判断是否溢出
            if (sign == 1 && sum > Integer.MAX_VALUE)
                return Integer.MAX_VALUE;
            if (sign == -1 && (-1) * sum < Integer.MIN_VALUE)
                return Integer.MIN_VALUE;
        }

        return (int) sum * sign;
    }

上面这段代码可以击败45%的用户,我们可以通过下面的方法来提升效率进而即便72%的用户。代码如下所示:

    //72%
    public int myAtoi1(String str) {
        str = str.trim();
        if (str.isEmpty())
            return 0;
        int sign = 1; int i = 0;
        if (str.charAt(0) == '-' || str.charAt(0) == '+'){
            sign = (str.charAt(0) == '-')? -1 : 1;
            if (str.length() < 2 || !Character.isDigit(str.charAt(1))) {
                return 0;
            }
            i++;
        }
        int n = 0;
        while (i < str.length()) {
            if (Character.isDigit(str.charAt(i))) {
                int d = str.charAt(i) - '0';
                if (n > (Integer.MAX_VALUE - d) / 10) { //Detect the integer overflow.
                    n = (sign == -1)? Integer.MIN_VALUE : Integer.MAX_VALUE;
                    return n;
                }
                n = n*10 + d;
            } else {
                break;
            }
            i++;
        }
        return sign * n;
    }

接下来看第二道题目:

Write a function to check whether an input string is a valid IPv4 address or IPv6 address or neither.

IPv4 addresses are canonically represented in dot-decimal notation, which consists of four decimal numbers, each ranging from 0 to 255, separated by dots ("."), e.g.,172.16.254.1;

Besides, leading zeros in the IPv4 is invalid. For example, the address 172.16.254.01 is invalid.

IPv6 addresses are represented as eight groups of four hexadecimal digits, each group representing 16 bits. The groups are separated by colons (":"). For example, the address 2001:0db8:85a3:0000:0000:8a2e:0370:7334 is a valid one. Also, we could omit some leading zeros among four hexadecimal digits and some low-case characters in the address to upper-case ones, so 2001:db8:85a3:0:0:8A2E:0370:7334 is also a valid IPv6 address(Omit leading zeros and using upper cases).

However, we don't replace a consecutive group of zero value with a single empty group using two consecutive colons (::) to pursue simplicity. For example, 2001:0db8:85a3::8A2E:0370:7334 is an invalid IPv6 address.

Besides, extra leading zeros in the IPv6 is also invalid. For example, the address 02001:0db8:85a3:0000:0000:8a2e:0370:7334 is invalid.

Note: You may assume there is no extra space or special characters in the input string.

Example 1:
Input: "172.16.254.1"

Output: "IPv4"

Explanation: This is a valid IPv4 address, return "IPv4".
Example 2:
Input: "2001:0db8:85a3:0:0:8A2E:0370:7334"

Output: "IPv6"

Explanation: This is a valid IPv6 address, return "IPv6".
Example 3:
Input: "256.256.256.256"

Output: "Neither"

Explanation: This is neither a IPv4 address nor a IPv6 address.

这道题目是判断一个给定的字符串是否为一个有效的IPV4或者IPV6地址,其实主要是一个字符串解析的方式,注意判断切分后的每个数字是否满足条件即可。自己多试几遍,把特例都试出来即可。主要有下面几个坑,第一如果字符串开始和结尾就是.或者:,那么切分的时候依然满足,所以要先把这种情况给排出,其次是将一个字符串转化为int型数时可能存在字母导致无法转换,这时我们加一个try catch语句来捕获异常即可。最后对于IPV6地址我们要对其中的每一个字符判断其是否符合条件。同样我们可以使用自己写判断来做,也可以使用一个正则表达式来判断,但是这种方法的效率比较低而已。两种方法的代码如下所示:

    //70%
    public static String validIPAddress(String IP) {
        if(IP.contains(".")){
            String [] nums = IP.split("\\.");
            if(IP.startsWith(".") || IP.endsWith(".") || nums.length != 4)
                return "Neither";
            for(String num : nums){
                if(num.startsWith("0") && !num.equals("0"))
                    return "Neither";
                try{
                    int parseInt = Integer.parseInt(num);
                    if(parseInt < 0 || parseInt > 255) return "Neither";
                    if(parseInt==0 && num.charAt(0)!='0') return "Neither";
                }catch (NumberFormatException nfe) {
                    return "Neither";
                }
            }
            return "IPv4";
        }else if(IP.contains(":")){
            String [] nums = IP.split(":");
            if(IP.startsWith(":") || IP.endsWith(":") || nums.length != 8)
                return "Neither";
            for(String num : nums){
                if(num.length() > 4 || num.equals(""))
                    return "Neither";
                char [] chars = num.toCharArray();
                for(char c : chars){
                    boolean isDigit = c>=48 && c<=57;
                    boolean isUppercaseAF = c>=65 && c<=70;
                    boolean isLowerCaseAF = c>=97 && c<=102;
                    if(!(isDigit || isUppercaseAF || isLowerCaseAF))
                        return "Neither";
                }
            }
            return "IPv6";
        }
        return "Neither";

    }

    //15%
    public String validIPAddress1(String IP) {
        if(IP.matches("(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"))return "IPv4";
        if(IP.matches("(([0-9a-fA-F]{1,4}):){7}([0-9a-fA-F]{1,4})"))return "IPv6";
        return "Neither";
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值