【题目】
Chapter 1 | Arrays and Strings
原文:
1.1 Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?
译文:
实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).不能使用额外的数据结构。 (即只使用基本的数据结构)
【分析】
【思路一】首先,我们要搞清楚构成字符串的字符个数到底有多大?是ASCII字符,还是只是26个字母? 还是有更大的字符个数,对于不同的情况,我们可能会有不同的解决方案。如果我们假设字符集是ASCII字符,那么我们可以开一个大小为256的bool数组来表征每个字 符的出现。数组初始化为false,遍历一遍字符串中的字符,当bool数组对应位置的值为真, 表明该字符在之前已经出现过,即可得出该字符串中有重复字符。否则将该位置的bool数组 值置为true。该算法的时间复杂度为O(n)。
【思路二】
我们还可以通过位运算来减少空间的使用量。其实就是用所谓的Bit-map的原理来存储。就是用一个bit位来标记某个元素对应的Value,在这就是该元素是否出现的bool值,而Key即是该元素。用每一位表征相应位置字符是否出现。对于ASCII字符,我们需要256位,即一个长度为8的int数组map即可(8*4*8)。
这里的关键是要把字符对应的ASCII,映射到正确的位上去。
举个例子:
字符'a'对应的ASCII是97,那么我们应该将数组中的哪一位置为1呢?
用97除以32,得到对应数组map的下标:3。97对32取模得到相应的位:1。
【代码】
/*********************************
* 日期:2014-05-04
* 作者:SJF0115
* 题目: 字符串中字符判重
* 来源:CareerCup
**********************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
bool IsUnique(string str){
bool visited[256];
//初始化
memset(visited,false,sizeof(visited));
int len = str.length();
for(int i = 0;i < len;i++){
int index = (int)str[i];
//判断是否有重复
if(!visited[index]){
visited[index] = true;
}
else{
//有重复直接返回
return true;
}
}
return false;
}
int main(){
string str = "i am xiaosi";
bool result = IsUnique(str);
cout<<result<<endl;
return 0;
}
【代码2】
/*********************************
* 日期:2014-05-04
* 作者:SJF0115
* 题目: 字符串中字符判重
* 来源:CareerCup
**********************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
//判断字符串中字符是否重复
bool IsUnique(string str){
//8*4*8 共256位可以表示256个元素
int map[8];
//初始化
memset(map,0,sizeof(map));
int len = str.length();
for(int i = 0;i < len;i++){
int value = (int)str[i];
int index = value / 32, offset = value % 32;
//判断是否已经存储过
if(map[index] & (1 << offset)) {
//重复
return false;
}
map[index] |= (1 << offset);
}
return true;
}
int main(){
string str = "i amxos ";
bool result = IsUnique(str);
cout<<result<<endl;
return 0;
}