Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查字符串是否包含所有唯一字符_Java_String_Algorithm - Fatal编程技术网

Java 检查字符串是否包含所有唯一字符

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

//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);
        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;iSystem.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所说的双循环的重写,它只是试图混淆算法的双循环性质。当然,如果输入仅限于字母,复杂性会受到限制,但性能仍然比问题代码慢。如果输入不限于字母(问题代码暗示了这一点,但问题并没有规定这一点),那么性能会变得更差。当然,问题代码在这种情况下会失败,所以需要更好的解决方案