字符串字符互异判断

来源:互联网 发布:类似淘宝联盟的网站 编辑:程序博客网 时间:2024/06/06 03:27

字符串字符互异判断

实现一个算法,确定一个字符串的所有字符是否全都不同, 要求不允许使用额外的存储结构。
解答:

1

如果允许使用额外的存储结构,则使用长度为256的bool数组,初始值为false, 遇到一个字符判断该字符在bool数组中的值是否为false, 若为false则令数组中的值为true(因为现在已经遇到了),若为true,则该字符串不互异,直接返回true (表示字符串中存在重复字符);
代码十分简单,如下:

    bool checkDifferent(string iniString) {        bool isDuplicate = false;        //求字符串长度        int len = iniString.size();        //如果字符串的长度大于256,则必定有重复字符(所有字符种类的数量为256个)        if(len > 256){            isDuplicate = true;            return isDuplicate;        }             bool checked[256] = false;        for(int i = 0; i < len; ++i){            //判断是否已经遇到过字符 iniString[i],若遇到过则跳出,返回            if(checked[iniString[i]] == true){                isDuplicate = true;                break;            }            else               checked[iniString[i]] = true;         }        return isDuplicate;    }

2

不使用额外的数据结构,若字符串中仅有a~z 26个字符,有个很巧妙的解法,来自《程序员面试金典》。
代码如下:

    bool checkDifferent(string iniString) {        bool isDuplicate = false;        //求字符串长度        int len = iniString.size();        //如果字符串的长度大于256,则必定有重复字符(所有字符种类的数量为256个)        if(len > 256){            isDuplicate = true;            return isDuplicate;        }          int check = 0;        for(int i = 1; i < len; ++i){            //val 为字符与 字符'a'的距离            int val = iniString[i] - 'a';            if((check & (1 << val)) > 0){                isDuplicate = true;                break;               }             check |= (1 << val);                   }        return isDuplicate;    }

上述算法核心代码为

    if((check & (1 << val)) > 0){         isDuplicate = true;         break;     }    check |= (1 << val);    

这里假设输入字符串为 “abcfc”, 来看下程序运行情况:
第一个字符 ‘a’, val = 0, 1 << val 表示1左移val个单位, 这里 1 << val = 1;
check & 1 == 0, 因此 执行 check |= (1 << val), 此时 check = 1;
第二个字符 ‘b’, val = 1, 1 << val 表示1左移val个单位, 这里 1 << val = 10 (二进制表示);
check & 1 == 0, 因此 执行 check |= (1 << val), 此时 check = 11;
第三个字符 ‘c’, val = 2, 1 << val 表示1左移val个单位, 这里 1 << val = 100 (二进制表示);
check & 1 == 0, 因此 执行 check |= (1 << val), 此时 check = 111;
第四个字符 ‘f’, val = 5, 1 << val 表示1左移val个单位, 这里 1 << val = 100000 (二进制表示);
check & 1 == 0, 因此 执行 check |= (1 << val), 此时 check = 100111;
第五个字符 ‘c’, val = 2, 1 << val 表示1左移val个单位, 这里 1 << val = 100 (二进制表示);
check & 1 == 100, 大于0 ,表示重复了 直接返回。

3

若字符中不止有 a~z 字符,若允许修改字符串,可以对字符串进行排序,然后依次比较字符串中字符前后字符是否相同。
代码如下:

    bool checkDifferent(string iniString) {        bool isDuplicate = false;        //求字符串长度        int len = iniString.size();        //如果字符串的长度大于256,则必定有重复字符(所有字符种类的数量为256个)        if(len > 256){            isDuplicate = true;            return isDuplicate;        }         //对字符串排序,时间复杂度为O(nlogn)        sort(iniString.begin(), iniString.end());        for(int i = 1; i < len; ++i){            //将每个字符与前一个字符比较,若相同,则返回该字符串重复            if(iniString[i] == iniString[i - 1]){                isDuplicate = true;                break;            }        }        return isDuplicate;    }

4

若不允许修改字符串,则可以将每个字符与后面所有字符进行比较,时间复杂度为O(n^2);
代码如下:

    bool checkDifferent(string iniString) {        bool isDuplicate = false;        //求字符串长度        int len = iniString.size();        //如果字符串的长度大于256,则必定有重复字符(所有字符种类的数量为256个)        if(len > 256){            isDuplicate = true;            return isDuplicate;        }         for(int i = 0; i < len - 1; ++i){            //将iniString[i]与后面所有的字符比较            for(int j = i + 1; j < len; ++j){                if(iniString[i] == iniString[j]){                    isDuplicate = true;                    break;                }                           }        }        return isDuplicate;    }
0 0