不开新数组,一串英文字符串,去除重复的字符
程序员文章站
2024-02-24 15:10:24
...
思路
英文字符,也就是a-z
,A-Z
分别对应的ascii码是 97-122
,65-90
总共加起来48个字符,如果按照平时相反,两层for循环,外面一层遍历字符串,里面一层开一个新数组,判断当前字符在数组中有没有,没有就存,有就跳过
但是不让开新数组,这时候可以考虑使用bit位。正好一个long类型有64位,我们可以让一个字符占一位,使用与
运算来判断,或
运算来保存
代码
public static void main(String[] args){
deRepeatString("aabcaAcBdACFSedfcaFdsadGhfgGFASdHFvGudfgVohjfdOdsfgGODGVBadfxcBSDFGbzZyYPpQ");
}
/**
* 给英文字符串去重
*/
public static void deRepeatString(String t){
char[] cs = t.toCharArray();
int i = 0;
//记录字符串的位,一个字符占一个bit位
long b = 0L;
for (char c : cs) {
int n;
if (c <= 'Z'){
//这里将64位拆成两半,大写从30开始,小写从0开始
n = c - 'A' + 30;
}else {
n = c -'a';
}
//这里的1记住要加L,否则就是int32位的运算,会有问题
long m = 1L << n;
System.out.println("m = " + m);
//如果与运算不等于0,那肯定某个bit位都是1,是同一个字符
if ((b & m) == 0){
//不重复
cs[i++] =c;
b |=m;
}else{
//ascii码中,0表示空字符
cs[i++] = '\0';
}
}
System.out.println(new String(cs));
}
结果:
a bc A Bd CFSe f s Gh g H v u Vo j O D x zZyYPpQ