问题一:找出两串字符串是否存在相同字符。
思路一:类似两个集合找相同元素一般,以一个集合为基准便利两个集合,遇到相同元素就中断,这样的时间代价是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!=' '){ 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; }