问题一:找出两串字符串是否存在相同字符。
思路一:类似两个集合找相同元素一般,以一个集合为基准便利两个集合,遇到相同元素就中断,这样的时间代价是O(n2)平方级别,效率较低,也是最容易想到的方法。
public boolean StringSearch1(String s){
boolean same=false;
char[] chSet=new char[s.length()];
s.getChars(0, s.length(), chSet, 0);
for(int i=0;i<chSet.length;i++)
{
boolean bSignal=false;
for(int j=0;j<chSet.length;j++)
{
if(j!=i)
if(chSet[i]==chSet[j])
{
same=true;
bSignal=true;
break;
}
}
if(bSignal)
break;
}
return same;
}
思路二:利用java的map映射存储字符,遇到相同的key值比较value,并设置为相同后退出。map映射与散列表的思想是一样的,需要运用空间换取时间以达到O(n)的效率,但是另需O(n)的空间来存储。这是一个比较好的方法,不过随着数据量的增大会给存储服务带来很巨大的性能损耗。
public boolean StringSearch2(String s)
{
boolean same=false;
Map<Character, Boolean> map=new HashMap<Character, Boolean>();
for(int i=0;i<s.length();i++)
{
if(map.get(s.charAt(i))==null)
map.put(s.charAt(i), true);
else
{
same=true;
break;
}
}
return same;
}
思路三:我们了解到有信息指纹这种简化信息本身存储空间的方法,并了解到通过信息指纹计算可以单独辨别一个信息,而且计算出来的指纹重复率十分之低。透过这个思想,我们想到每个字符都在系统中存在一个ASCII码,他们是互不相同的一个整形数(也可以说是二进制数),以此为基础建立A-Z,a-z的字典byte数组,然后以散列的方式存储并找出相同元素。(进一步优化就是位映射了,把一个byte=8个bit进行1变8的存储)。效率可达到O(n)。
//A-Z 65-90 a-z 97-122
public boolean StringSearch3(String s)
{
boolean same=false;
byte[] map =new byte[52];
for(int i=0;i<map.length;i++)
map[i]=0;
for(int i=0;i<s.length();i++){
char c=s.charAt(i);
int code=(int)c;
if(code<=90 && code>=65)
{
if(map[code-65]==1)
{
same=true;
break;
}else
map[code-65]=1;
}else if(code >=97 && code <=122)
{
if(map[code-97+26]==1){
same=true;
break;
}else
map[code-97+26]=1;
}
}
return same;
}
问题二:实现字符串反转
在这个问题上我并没有能想到更好的方法,只有新建一个同等长度的字符串并对位转存。
public String StringReserve1(String s) throws UnsupportedEncodingException
{
int length=s.length();
byte[] b1=s.getBytes();
byte[] b2=new byte[length];
for(int i=0;i<length;i++){
b2[i]=b1[length-i-1];
}
String reS=new String(b2,"utf-8");
return reS;
}
int LengthOfStr(const char *c){
const char *p=c;
int len=0;
while(*p!='\0'){
len++;
p++;
}
return len;
}
const char * reverseStr(const char *c){
char* reverStr;
int len=LengthOfStr(c);
reverStr=new char(len);
for(int i=0;i<len;i++)
*(reverStr+i)=*(c+len-1-i);
return reverStr;
}
问题三:两端字符串,一个重排是否能成为另一个
刚开始被传统思维束缚,第一个方案就是以一个为基准,重排另一个来判断。最后被吴军老师的书启发了,数据指纹->字符ASCII码->字符指纹恒定。所以看代码吧。
//重排字符串 --无论如何重排 字符串各元素相加是定值
public boolean reSort(String s1,String s2){
boolean enable=false;
int s1Count=0;
int s2Count=0;
if(s1.length()!=s2.length())
return enable;
else{
for(int i=0;i<s1.length();i++)
{
s1Count+=(int)s1.charAt(i);
s2Count+=(int)s2.charAt(i);
}
if(s1Count==s2Count)
enable=true;
}
return enable;
}
问题四: 替换字符串中的空格变为%20
没啥方法,检测到空格就替换的意思。
//替换字符串中的空格--空格编码 32 public String replace(String s){ String reS=""; StringBuffer sbuild=new StringBuffer(); int i=0; while(i<s.length()){ char c=s.charAt(i); if(c!=' ') sbuild.append(c); else{ sbuild.append("%20"); } i++; } reS=sbuild.toString(); return reS; }