目录
substring的范围问题:前闭后开
substring(0, 4) —> [0, 4)
计算两个字符串的汉明距离
v1 : 大数字case不通过
- 字符串(数字)补0用String.format
- 字符串转整数,用Integer.parseInt(需要考虑字符串范围)
public int hammingDistance1(int x, int y) {
int count = 0;
String a = Integer.toBinaryString(x);
String b = Integer.toBinaryString(y);
int maxLen = Math.max(a.length(), b.length());
String c = String.format("%0"+maxLen+"d", Integer.parseInt(a));
String d = String.format("%0"+maxLen+"d", Integer.parseInt(b));
for (int i = 0; i < maxLen; i++) {
if (c.charAt(i) != d.charAt(i)) {
count ++;
}
}
return count;
}
v2 : 速度太慢
- 字符串补0用String.format(“%10s”, “”).replace(‘’, ‘0’)
这里先让它占满10位,右对齐,然后在前面补0;如果"%-10s"则是左对齐,尾部补0
public int hammingDistance2(int x, int y) {
int count = 0;
String a = Integer.toBinaryString(x);
String b = Integer.toBinaryString(y);
int maxLen = Math.max(a.length(), b.length());
String c = String.format("%"+maxLen+"s", a).replace(' ', '0');
String d = String.format("%"+maxLen+"s", b).replace(' ', '0');
for (int i = 0; i < maxLen; i++) {
if (c.charAt(i) != d.charAt(i)) {
count ++;
}
}
return count;
}
v3 :使用异或^,调用系统函数就很慢
- x^y自动计算x和y转为二进制的异或值,然后再统计里面1的个数
public int hammingDistance3(int x, int y) {
String a = Integer.toBinaryString(x^y);
return a.length() - a.replaceAll("1", "").length();
}
v4 :位运算
当两个数字都为0时停止,跟1比较,如果值不同就count++,然后右移
public int hammingDistance(int x, int y) {
int count = 0;
while (x!=0 || y!=0) {
if ((x&1) != (y&1)) {
count ++;
}
x >>= 1;
y >>= 1;
}
return count;
}
寻找字符串数组公共前缀
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0)
return "";
String common = "";
int minLen = Integer.MAX_VALUE;
// 寻找数组中最短的字符串的长度值
for (String s : strs) {
minLen = Math.min(minLen, s.length());
}
for (int i = minLen-1; i >= 0; i--) {
Boolean flag = true;
// 取substring时,取不到end
String prefix = strs[0].substring(0, i+1);
for (String s : strs) {
if (!s.startsWith(prefix)) {
flag = false;
break;
}
}
if (!flag) {
continue;
} else {
common = prefix;
// 找到了要及时跳出
break;
}
}
return common;
}
字符串数组初始化:
String[] s = {“flower”,“flow”,“flight”};
字符串比较:equals和==的区别
equals比较的是值本身,==比较的是两个对象的内存地址
gene_name.equals(name)
计算某个字符出现的次数
public String getGC(String seq) {
String s1 = seq.replaceAll("G", "").replaceAll("C", "");
double num = (seq.length()-s1.length())*1.0 / seq.length() * 100;
return String.valueOf(new DecimalFormat("#").format(num)) + "%";
}
原长度-replaceAll之后的长度
“#”.split(“#”)后长度是0,可能是jvm自己删掉了空串
replace使用注意
replaces是不会改变对象的,并不是in-place的,所以输出仍然是
hello
beauty
good
morning
数字与字符串转换
String s = 12304 + "";
字符数组与字符串转换
String S;
char[] c = S.toCharArray();
String t = new String(c);
StringBuffer常用函数
删除指定范围的字符:
StringBuffer a = new StringBuffer("Runoob");
StringBuffer b = new StringBuffer("Google");
a.delete(1,3); //删除范围[1.3)
a.append(b); //字符串连接
StringBuilder
-
StringBuffer和StringBuilder类的对象可以被多次修改且不产生新的未使用对象。
-
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
-
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
-
如果没有循环的情况下,单行用加号拼接字符串是没有性能损失的,java 编译器会隐式的替换成 stringbuilder,但在有循环的情况下,编译器没法做到足够智能的替换,仍然会有不必要的性能损耗,因此,用循环拼接字符串的时候,还是老老实实的用 stringbuilder 吧。
-
操作少量的数据使用 String。
-
单线程操作大量数据使用 StringBuilder。
-
多线程操作大量数据使用 StringBuffer。
-
StringBuffer(int size)指定了初始化的容量,如果超过初始容量,就按照当前容量*2+2来扩容。