Java 检查字符串是否包含所有唯一字符
//O(N)-没有额外的数据结构Java 检查字符串是否包含所有唯一字符,java,string,algorithm,Java,String,Algorithm,//O(N)-没有额外的数据结构 private boolean isUniqueWithoutDS(String str){ boolean value = true; int checker = 0; for (int i = 0; i < str.length(); i++) { int c = str.charAt(i) - 'a'; System.out.println("checker is : " + checker
private boolean isUniqueWithoutDS(String str){
boolean value = true;
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int c = str.charAt(i) - 'a';
System.out.println("checker is : " + checker);
System.out.println("1<<c is " + (1<<c));
if((checker & (1 << c))>0){
value = false;
break;
}
checker = checker | 1<<c;
}
return value;
}
private boolean是唯一的,不带字符串(String str){
布尔值=真;
int-checker=0;
对于(int i=0;i System.out.println(“1嗯,答案可能取决于语言,但在Java(JLS)中):
如果左侧操作数的提升类型为int
,则仅将右侧操作数的五个最低阶位用作移位距离。这就好像右侧操作数使用了位逻辑AND运算符&
(§15.22.1),掩码值0x1f
(0b11111
)因此,实际使用的换档距离始终在0
到31
的范围内
因此,这就像执行
c=c&0x1f
,或c=c%32
,因此大写A
和小写A
都变成c
值0
,对于而言,答案可能取决于语言,但在Java(JLS)中:
如果左侧操作数的提升类型为int
,则仅将右侧操作数的五个最低阶位用作移位距离。这就好像右侧操作数使用了位逻辑AND运算符&
(§15.22.1),掩码值0x1f
(0b11111
)因此,实际使用的换档距离始终在0
到31
的范围内
因此,这就像执行
c=c&0x1f
,或c=c%32
,因此大写A
和小写A
都变成c
值0
,目的是检查字符串是否包含所有唯一字符的另一种方法--O(N):
使用无限循环
使用两个变量i(i=0)和j=(n-1[其中n-是字符串长度])
检查每个第i个字符是否等于第j个字符
3.1如果[i-th char==j-th&&i!=j char],则中断循环,因为字符串包含重复的字符。(i!=j表示与相同的字符进行比较)
3.2当j=0时,减小j并将j设置为n-1和i+=1[这部分很棘手]
重复步骤3,除非i变为n-1号尺寸
代码
String s = "abcde";
int i = 0;
int j = s.length()-1;
boolean flag = true;
while(true) {
if(i == s.length()-1)
break;
// DUPLICATE FOUND
if(i != j && s.charAt(i) == s.charAt(j)) {
flag = false;
break;
}else {
j--;
// COMPARING DONE AGAINST i-TH CHAR TO ALL OTHER CHARS, INCREMENT i NOW
if(j == 0) {
j = s.length()-1;
i += 1;
}
}
}
if(flag)
System.out.println("unique");
else
System.out.println("non-unique");
检查字符串是否包含所有唯一字符的另一种方法——在O(N)中:
使用无限循环
使用两个变量i(i=0)和j=(n-1[其中n-是字符串长度])
检查每个第i个字符是否等于第j个字符
3.1如果[i-th char==j-th&&i!=j char],则中断循环,因为字符串包含重复的字符。(i!=j表示与相同的字符进行比较)
3.2当j=0时,减小j并将j设置为n-1和i+=1[这部分很棘手]
重复步骤3,除非i变为n-1号尺寸
代码
String s = "abcde";
int i = 0;
int j = s.length()-1;
boolean flag = true;
while(true) {
if(i == s.length()-1)
break;
// DUPLICATE FOUND
if(i != j && s.charAt(i) == s.charAt(j)) {
flag = false;
break;
}else {
j--;
// COMPARING DONE AGAINST i-TH CHAR TO ALL OTHER CHARS, INCREMENT i NOW
if(j == 0) {
j = s.length()-1;
i += 1;
}
}
}
if(flag)
System.out.println("unique");
else
System.out.println("non-unique");
我建议使用256大小的数组来存储每个字符的计数(假设有256个可能的字符),在循环开始时将其设置为0。然后,在获取下一个字符时,只需简单地增加每个位置。最后,有一个快速破解,检查位置中的值是0还是1(例如,freq[i]=!!freq[i])
。此if语句[freq[i]=!!freq[i]]
应适用于数组中的所有256项
更新:
unsigned int isDistinctStr(char *str);
unsigned int isDistinctStr(char *str) {
unsigned int ct, freq[256], i, j;
char ch;
for (i = 0; i < 256; i++) {freq[i] = 0;}
for (ct = 0; ch = *str; str++) {
j = (unsigned int) (ch & 0xffu);
freq[j]++;
}
for (j = 0; j < 256; j++) {
if (freq[j] == !!freq[j]) {ct++;}
}
return (ct == 256) ? 1 : 0;
}
无符号整数isDistinctStr(char*str);
无符号整数isDistinctStr(字符*str){
无符号整数ct,频率[256],i,j;
char ch;
对于(i=0;i<256;i++){freq[i]=0;}
对于(ct=0;ch=*str;str++){
j=(无符号整数)(ch&0xffu);
频率[j]++;
}
对于(j=0;j<256;j++){
如果(freq[j]=!!freq[j]){ct++;}
}
返回值(ct==256)?1:0;
}
我建议使用256大小的数组来存储每个字符(假设有256个可能的字符)的计数,该计数在循环开始时设置为0。然后,在获取下一个字符时,只需简单地增加每个位置。最后,有一个快速破解,检查位置中的值是0还是1(例如,freq[i]=!!freq[i])
。此if语句[freq[i]=!!freq[i]]
应适用于数组中的所有256项
更新:
unsigned int isDistinctStr(char *str);
unsigned int isDistinctStr(char *str) {
unsigned int ct, freq[256], i, j;
char ch;
for (i = 0; i < 256; i++) {freq[i] = 0;}
for (ct = 0; ch = *str; str++) {
j = (unsigned int) (ch & 0xffu);
freq[j]++;
}
for (j = 0; j < 256; j++) {
if (freq[j] == !!freq[j]) {ct++;}
}
return (ct == 256) ? 1 : 0;
}
无符号整数isDistinctStr(char*str);
无符号整数isDistinctStr(字符*str){
无符号整数ct,频率[256],i,j;
char ch;
对于(i=0;i<256;i++){freq[i]=0;}
对于(ct=0;ch=*str;str++){
j=(无符号整数)(ch&0xffu);
频率[j]++;
}
对于(j=0;j<256;j++){
如果(freq[j]=!!freq[j]){ct++;}
}
返回值(ct==256)?1:0;
}
那么,它对大写和小写字母同样有效?回答很好。谢谢。那么,它对大写和小写字母同样有效?回答很好。谢谢。这里的代码是O(N^2)。它模拟了一个双for循环,比如“for(i=0;i=0;j--)“使用一段时间,但处理量是相同的。等待有人反对我!是的,你是对的。这只是将O(n^2)扩展到O(n):D,但解决方案是O(n):P:)你是对的,因为字母表中只有O(1)个字符(所以无限循环中断不会花太长时间),投票结果是向上的。它仍然是一个O(n):P:)(n^2)风格的算法,是对qwertyman所说的双循环的重写,它只是试图混淆算法的双循环性质。当然,如果输入仅限于字母,复杂性会受到限制,但性能仍然比问题代码慢。如果输入不限于字母(问题代码暗示了这一点,但问题并没有规定这一点),那么性能会变得更差。当然,问题代码在这种情况下会失败,所以需要更好的解决方案