算法理论实践大比拼

来源:互联网 发布:如何清除淘宝聊天记录 编辑:程序博客网 时间:2024/05/22 21:41

2014年4月份,参加了金山网络的笔试题,其中有一道题有点意思。

题目:

两个字符串或字符数组的字符种类,个数相同,则判断两个字符串或者字符数组相等。不考虑字符出现的顺序。
如str1 = “aaab”
  str2 = "aaba"
则str1跟str2相等
编写一个判断两个字符串或者字符数组是否相同。

看到这里是否觉得题目很简单?当然这里讲的是理论跟实践的结果比对下。

思路1:先判断长度,若相等,将str1与str2排序下,遍历str1或str2,若有字符不相等,则两个字符串不相等。

分析:排序算法若采用快排,则实践复杂度为平均时间复杂度log2(n)*n。时间呈线性增长

思路2:先判断长度,若相等,则遍历str1,str2,存储str1与str2中的字符出现的个数,判断字符的种类,出现的个数是否一致。

分析:这里我们用hashmap来存储str1与str2中的字符,时间复杂度为O(1),遍历hashmap判断


从理论上将,思路2比思路1要好,时间复杂度思路2要小一点。实践一下,真的是这样吗?你真的确定思路2运算时间比思路1要快?那就让我们时间下吧。

为了更好地突显思路2的优势,往txt中存放着10W个随机出现的字符,存储在str1,str2数组中。上代码

import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.lang.reflect.Array;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.charset.Charset;import java.util.Arrays;import java.util.HashMap;import java.util.Iterator;import java.util.Map;public class Main {public static HashMap<Character, Integer> map1=new HashMap<Character, Integer>();public static HashMap<Character, Integer> map2=new HashMap<Character, Integer>();public static char ch1[];public static char ch2[];public static void main(String[] args) {long startTime=System.currentTimeMillis();   //获取开始时间ch1 = readToString("E:/javacode/字符串对比/string100000A.txt");ch2 = ch1.clone();if(judge1()){System.out.println("ture");}else{System.out.println("false");}long endTime=System.currentTimeMillis(); //获取结束时间 System.out.println(endTime-startTime);}public static boolean judge(){    Arrays.sort(ch1);    Arrays.sort(ch2);    for(int i=0; i<ch1.length; ++i){    if(ch1[i] != ch2[i]){    return false;    }    }return true;}public static void initHashmap(char ch1[],char ch2[]){for(int i=0; i<ch1.length; ++i){Integer count = map1.get(ch1[i]);if(count == null){count = 0;}map1.put(ch1[i], count+1);}map2 = (HashMap<Character, Integer>) map1.clone();}public static boolean judge1(){initHashmap(ch1, ch2);Iterator iter = map1.entrySet().iterator();while (iter.hasNext()) {     Map.Entry entry1 = (Map.Entry) iter.next();    Character key =  (Character) entry1.getKey();    Integer count1 = map1.get(key);    Integer count2 = map2.get(key);    if(count1 != count2){    return false;    }} return true;}public static char[] readToString(String fileName) {File file = new File(fileName);Long filelength = file.length();byte[] filecontent = new byte[filelength.intValue()];try {FileInputStream in = new FileInputStream(file);in.read(filecontent);in.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}Charset cs = Charset.forName ("UTF-8");ByteBuffer bb = ByteBuffer.allocate (filecontent.length);bb.put (filecontent);             bb.flip ();    CharBuffer cb = cs.decode (bb);          return cb.array();//return new String(filecontent, encoding);}}

运行下,

思路一:

ture
6

思路二:

ture
18

是的,你没看错,思路一的运行时间为6ms,思路二的运行时间为18ms。

总结下:

理论跟实践总是有差距,但这并不代表着我上面思路二的实践是正确的。

平时编程时注意以下几个习惯

1、查找排序号的数组时,记得用二分。

2、乱序的数组排序时,记得用快排。

3、千万不要挑战STL,或者封装好的类库,血淋淋的教训

把它们养成一个习惯。形成一个良好的编程习惯能少走很多弯路


0 0
原创粉丝点击