今天开始刷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";
}