(原)最长公共子串-引申出集合类的深拷贝和浅拷贝
今天在做一道笔试题时,题目大意就是要求最长公共子串,我当时在编码时打算用一个ArrayList<Character>加一个ArrayList<ArrayList<Character>>进行存储,但是在每次用
ArrayList<ArrayList<Character>>添加后,然后用clear清除ArrayList<Character>时,刚添加到ArrayList<ArrayList<Character>>中的元素也被清空。然后将
ArrayList<Character>用=号复制给另一个ArrayList<Character>变量,仍然不能解决问题,后来突然想到这里应该是浅拷贝,都指向了同一地址。
最终利用copy函数解决问题的,它是深拷贝。
1 //找出两个字符串中的最大子串,忽略大小写,子串须是英文字母 2 //eg:输入:abcd abc 3 //输出:result=abc 4 //输入:abcd efg 5 //输出:result= 6 7 import java.util.Scanner; 8 import java.util.ArrayList; 9 import java.util.Collections; 10 11 public class Main 12 { 13 static ArrayList<Character> al=new ArrayList<Character>(); 14 static ArrayList<Character> al1=new ArrayList<Character>(); 15 static ArrayList<ArrayList<Character>> newAl=new ArrayList<ArrayList<Character>>(); 16 17 //判断字符数组是不是全部都为字符 18 public static boolean isEnglish(char[] ch) 19 { 20 for (int i=0;i<ch.length;i++) 21 { 22 if(ch[i]<'a'||ch[i]>'z') 23 { 24 return false; 25 } 26 } 27 return true; 28 } 29 30 public static void main(String[] args) 31 { 32 Scanner scan=new Scanner(System.in); 33 34 while(scan.hasNext()) 35 { 36 String str=scan.nextLine(); 37 String newStr=str.toLowerCase();//均变为小写字母 38 String[] s=newStr.split(" "); 39 //如果原始字符串长度为空或者为0,就直接输出空 40 if (s.length<=1||newStr==null) 41 { 42 System.out.print("result"+"="+""); 43 System.out.print("\n"); 44 } 45 else 46 { 47 String str1=s[0]; 48 String str2=s[1]; 49 50 char[] chA=str1.toCharArray(); 51 char[] chB=str2.toCharArray(); 52 if(Main.isEnglish(chA)==false||Main.isEnglish(chB)==false) 53 { 54 System.out.print("result"+"="+""); 55 System.out.print("\n"); 56 } 57 else 58 { 59 //如果 60 if (chA.length==0||chA==null||chB.length==0||chB==null) 61 { 62 System.out.print("result"+"="+""); 63 System.out.print("\n"); 64 } 65 else 66 { 67 Main.getCommomLongestSubstring(chA,chB); 68 int len=0; 69 for (int i=0;i<newAl.size();i++) 70 { 71 len=len<newAl.get(i).size()?newAl.get(i).size():len;//得到其长度的最大值 72 } 73 74 if (len>0) 75 { 76 System.out.print("result"+"="); 77 for (int i=0;i<newAl.size();i++) 78 { 79 if (newAl.get(i).size()==len)//找到ArrayList中为最大值时的那一个子串 80 { 81 for (int j=0;j<len;j++) 82 { 83 if (newAl.get(i).get(j)!=null) 84 System.out.print(newAl.get(i).get(j)); 85 } 86 break; 87 } 88 } 89 System.out.print("\n"); 90 } 91 92 else 93 { 94 System.out.print("result"+"="+""); 95 System.out.print("\n"); 96 } 97 } 98 } 99 } 100 } 101 } 102 103 public static void getCommomLongestSubstring(char[] chA,char[] chB) 104 { 105 int lenA=chA.length; 106 int lenB=chB.length; 107 int startA=0; 108 int startB=0; 109 110 for (int i=0;i<lenA;i++) 111 { 112 startA=i; 113 startB=0; 114 while (startA<lenA&&startB<lenB) 115 { 116 if(chA[startA]==chB[startB]) 117 { 118 119 al.add(chA[startA]); 120 } 121 else 122 { 123 Collections.addAll(al1, new Character[al.size()]); 124 Collections.copy(al1, al); 125 newAl.add(al1); 126 al.clear(); 127 // al1.clear(); 128 } 129 startA++; 130 startB++; 131 } 132 //处理提前跳出来的值如a 和a比较 133 if(al!=null) 134 { 135 Collections.addAll(al1, new Character[al.size()]); 136 Collections.copy(al1, al); 137 newAl.add(al1); 138 al.clear(); 139 } 140 } 141 142 for (int i=0;i<lenB;i++) 143 { 144 startA=0; 145 startB=i; 146 while (startA<lenA&&startB<lenB) 147 { 148 if(chA[startA]==chB[startB]) 149 { 150 151 al.add(chA[startA]); 152 } 153 else 154 { 155 Collections.addAll(al1, new Character[al.size()]); 156 Collections.copy(al1, al); 157 newAl.add(al1); 158 al.clear(); 159 // al1.clear(); 160 } 161 startA++; 162 startB++; 163 } 164 //处理提前跳出来的值如a 和a比较 165 if(al!=null) 166 { 167 Collections.addAll(al1, new Character[al.size()]); 168 Collections.copy(al1, al); 169 newAl.add(al1); 170 al.clear(); 171 } 172 return ; 173 } 174 } 175 }
以下两个小demo都是利用copy函数来解决深拷贝的。
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.Collections; 4 import java.util.List; 5 6 public class Test 7 { 8 public static void main(String[] args) 9 { 10 List<String> src=new ArrayList<String>(); 11 src.add("xiao"); 12 src.add("heng"); 13 src.add("xhxh"); 14 src.add("hxhx"); 15 16 for (int i=0;i<src.size();i++) 17 { 18 System.out.println("src: "+src.get(i)); 19 } 20 21 List<String> des=new ArrayList<String>(Arrays.asList(new String[src.size()])); 22 Collections.copy(des, src); 23 24 for (int i=0;i<des.size();i++) 25 { 26 System.out.println("des: "+des.get(i)); 27 } 28 29 des.add("father"); 30 des.add("mather"); 31 32 33 System.out.println("des改变后: "); 34 for (int i=0;i<src.size();i++) 35 { 36 System.out.println("src: "+src.get(i)); 37 } 38 for (int i=0;i<des.size();i++) 39 { 40 System.out.println("des: "+des.get(i)); 41 } 42 } 43 }
假设不预先给des分配长度的话,会出现java.lang.indexOutOfBoundException异常。如下:
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.Collections; 4 import java.util.List; 5 6 public class Test 7 { 8 public static void main(String[] args) 9 { 10 List<String> src=new ArrayList<String>(); 11 src.add("xiao"); 12 src.add("heng"); 13 src.add("xhxh"); 14 src.add("hxhx"); 15 16 for (int i=0;i<src.size();i++) 17 { 18 System.out.println("src: "+src.get(i)); 19 } 20 21 List<String> des=new ArrayList<String>(); 22 Collections.copy(des, src); 23 24 for (int i=0;i<des.size();i++) 25 { 26 System.out.println("des: "+des.get(i)); 27 } 28 29 des.add("father"); 30 des.add("mather"); 31 32 33 System.out.println("des改变后: "); 34 for (int i=0;i<src.size();i++) 35 { 36 System.out.println("src: "+src.get(i)); 37 } 38 for (int i=0;i<des.size();i++) 39 { 40 System.out.println("des: "+des.get(i)); 41 } 42 } 43 }
另一种利用copy函数进行深拷贝的是:
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.Collections; 4 import java.util.List; 5 6 public class Test 7 { 8 public static void main(String[] args) 9 { 10 List<String> src=new ArrayList<String>(); 11 src.add("xiao"); 12 src.add("heng"); 13 src.add("xhxh"); 14 src.add("hxhx"); 15 16 for (int i=0;i<src.size();i++) 17 { 18 System.out.println("src: "+src.get(i)); 19 } 20 21 List<String> des=new ArrayList<String>(); 22 Collections.addAll(des,new String[src.size()]); 23 Collections.copy(des, src); 24 25 for (int i=0;i<des.size();i++) 26 { 27 System.out.println("des: "+des.get(i)); 28 } 29 30 des.add("father"); 31 des.add("mather"); 32 33 34 System.out.println("des改变后: "); 35 for (int i=0;i<src.size();i++) 36 { 37 System.out.println("src: "+src.get(i)); 38 } 39 for (int i=0;i<des.size();i++) 40 { 41 System.out.println("des: "+des.get(i)); 42 } 43 } 44 }
后了解,在用copy函数时,最好先指定它的capacity的大小。在进行copy()时,首先做的是将des的长度和src长度作比较,只有当des的长度大于或者等于src的长度时才进行拷贝,否则抛出IndexOutOfBoundException异常。
路漫漫其修远兮,吾将上下而求索