判断一个字符串中的字符是否唯一(只用基本数据结构)

本文介绍了一种检查字符串中字符是否唯一的五种方法,包括数组方法、位运算方法、布尔运算方法及排序比较方法等,并提供了每种方法的实现代码与时间、空间复杂度分析。

package cglib;

import java.util.Arrays;

public class StringNumber {
    
    public static void main(String args[]) throws Exception{
        
        String str0="123qw&()";
        System.out.println("数组方法一:"+Array(str0));
        String str1="qwerABC";
        System.out.println("只有字母的位运算方法二:"+Bit(str1));
        String str2="q123";
        System.out.println("位运算方法三:"+Biter(str2));
        String str4="qwqewwr@#¥123";
        System.out.println("布尔运算方法四:"+Bool(str4));
        String str5="125asd";
        System.out.println("排序比较运算方法五:"+Sort(str5));
    }
    //时间复杂度为O(n*n),空间复杂度为O(1)
    public static boolean Array(String str){
        
        if(str==null||str==""){
            return true;
        }
        else if(str.length()>256){
            return false;
        }
        
        for(int i=0;i<str.length();i++){
            for(int j=i+1;j<str.length();j++){
                if(str.charAt(i)==str.charAt(j)){
                    return false;
                }
            }
            
        }
        return true;
        
        
    }
    
    public static boolean Bit(String str) throws Exception{
        if(str==null||str==""){
            return true;
        }
        else if(str.length()>26){
            return false;
        }
        int checkchar = 0;  //首先是26个0,也即是一个都没有出现过  
         for(int i = 0; i < str.length(); i++)  
         {  
             if((str.charAt(i) < 'a' || str.charAt(i) > 'z')&&(str.charAt(i) < 'A' || str.charAt(i) > 'Z')) {
                 throw new Exception("字符串不符合要求");
           }
             int v = (int) str.charAt(i);
             //我们判断checkchar中是否含有这个字符的位置  
             
             int b=checkchar&(1 << v);
             if (b!=0){//判断,如果是1&1的话,结果就是1,就是存在重复  
                 return false;
             }
             checkchar|=(1 << v); //把这个位置设置为1
            
         }
        
        return true;
        
        
    }
    /**
     * 通过位运算来减少空间的使用量。
     * 用每一位表征相应位置字符的出现。
     * 对于ASCII字符,我们需要256位,即一个大小为8的int 数组a即可。
     * 这里的关键是要把字符对应的数字,映射到正确的位上去。
     * 比如字符'b'对应的 代码是98.
     * 用98除以32,得到对应数组a的下标:3。
     * 98对32取模得到相应的位:2。
     * 该算法的时间复杂度为O(n),需要的内存空间更小
     *
     */
    public static boolean Biter(String str){
        if(str==null||str==""){
            return true;
        }
        else if(str.length()>256){
            return false;
        }
        final int[] a = new int[8];//位运算时,256个字符需要8个整型数来表征存储位:256/32=8
        for (int i=0;i<str.length();++i) {
            int v = (int) str.charAt(i);
            int idx=v/32,shift=v%32;
            int b=a[idx]&(1 << shift);
            if (b!=0){
                return false;
            }
            a[idx]|=(1 << shift);
        }
        
        return true;
        
    }
    public static boolean Bool(String str){
        if(str==null||str==""){
            return true;
        }
        else if(str.length()>256){
            return false;
        }
        boolean[] bole=new boolean[256];//默认都为false
        for(int i=0;i<str.length();++i){
            int a=(int)str.charAt(i);
            System.out.println(str.charAt(i));
            System.out.println("a="+a);
            if(bole[a]==true){//如果a对应的数组里面是true,说明已经存在,参考用map判断存在值的逻辑
                return false;
            }
            bole[a]=true;//相当于该值已经判断了,做存在一次的标识。回头再碰到相同的值,相当于索引一致,则数组里面的值是固定的
        }
        
        return true;
        
        
    }
    
    public static boolean Sort(String str){
        if(str==null||str==""){
            return true;
        }
        else if(str.length()>26){
            return false;
        }
        char[] character =new char[str.length()];
        for(int i=0;i<str.length();i++){
            
            character[i]=str.charAt(i);
        }
        Arrays.sort(character);
         for (int i = 0; i < character.length - 1; i++) {
             if (character[i] == character[i + 1]) {
                 return false;
             }
            
            
        }
        return true;
        
    }
    }
    

    
   输出:

数组方法一:true
只有字母的位运算方法二:true
位运算方法三:true
q
a=113
w
a=119
q
a=113
布尔运算方法四:false
排序比较运算方法五:true

 

    

 

转载于:https://my.oschina.net/u/2822116/blog/781269

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值