(原)最长公共子串-引申出集合类的深拷贝和浅拷贝

今天在做一道笔试题时,题目大意就是要求最长公共子串,我当时在编码时打算用一个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("
");
 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("
");
 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("
");
 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("
");
 90         }
 91         
 92         else
 93         {
 94             System.out.print("result"+"="+"");
 95             System.out.print("
");
 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异常。

原文地址:https://www.cnblogs.com/xh0102/p/5890202.html