算法笔记_024:字符串的包含(Java)
2017-02-12 18:52
183 查看
1 问题描述
给定一长字符串A和一短字符串B。请问,如何最快地判断出短字符串B中的所有字符是否都在长字符串A中?请编写一个判断函数实现此功能。为简单起见,假设输入的字符串只包含小写英文字母。下面举几个例子。
(1)如果字符串A是”abcd”,字符串B是”bad”,答案是包含,因为字符串B中的字母都在字符串A中,或者说B是A的真子集。
(2)如果字符串A是”abcd”,字符串B是”bce”,答案是不包含,因为字符串B中的字母e不在字符串A中。
(3)如果字符串A是”abcd”,字符串B是”aab”,答案是包含,因为字符串B中的字母a包含在字符串A中。
2 解决方案
2.1 蛮力轮询法
判断字符串B中的字符是否都在长字符串A中,最直观的思路则是:轮询B中每一个字符,逐个与A中每个字符进行比较,看是否都在字符串A中。具体代码如下:
package com.liuzhen.string_1; public class StringContain { //方法1:蛮力轮询 /* * 参数A:给定的长字符串A * 参数B:给定的短字符串B * 函数功能:如果B中所有字符在A中均出现过,则返回true,否则返回false */ public boolean bruteContain(String A,String B){ boolean result = false; char[] arrayA = A.toCharArray(); char[] arrayB = B.toCharArray(); int testLen = 0; //用于计算B中与A匹配字符个数 for(int i = 0;i < arrayB.length;i++){ for(int j = 0;j < arrayA.length;j++){ if(arrayB[i] == arrayA[j]){ testLen++; break; } } } if(testLen == arrayB.length) //当B个所有字符均和A中字符匹配时 result = true; return result; } public static void main(String[] args){ StringContain test = new StringContain(); String A = "abcd"; String B = "aab"; if(test.bruteContain(A, B)) System.out.println("使用蛮力轮询法得到结果:A字符串包含B字符串"); else System.out.println("使用蛮力轮询法得到结果:A字符串不包含B字符串"); } }
[b]运行结果:[/b]
使用蛮力轮询法得到结果:A字符串包含B字符串
2.2 素数相乘法
思路如下:(1)按照从小到大的顺序,用26个素数分别代替长字符串A中的所有字母。
(2)遍历字符串A,求得A中所有字母对于的素数的乘积。
(3)遍历短字符串B,判断上一步得到的乘积能否被B中的字母对于的素数整除。
(4)输出结果。
具体代码如下:
package com.liuzhen.string_1; public class StringContain { //方法2:素数相乘 /* * 参数A:给定的长字符串A * 参数B:给定的短字符串B * 函数功能:如果B中所有单个字符对应素数能被A中所有字符对应素数之积整除,则返回true,否则返回false */ public boolean primeContain(String A,String B){ boolean result = true; int[] primes = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101}; long mulSum = 1; char[] arrayA = A.toCharArray(); char[] arrayB = B.toCharArray(); for(int i = 0;i < arrayA.length;i++) mulSum *= primes[arrayA[i] - 'a']; for(int j = 0;j < arrayB.length;j++){ int temp = (int) (mulSum % primes[arrayB[j] - 'a']); if(temp != 0){ //此时,A中不包含arrayB[j]字符 result = false; return result; } } return result; } public static void main(String[] args){ StringContain test = new StringContain(); String A = "abcd"; String B = "aab"; if(test.placeContain(A, B)) System.out.println("使用素数相乘法得到结果:A字符串包含B字符串"); else System.out.println("使用素数相乘法得到结果:A字符串不包含B字符串"); } }
[b]运行结果:[/b]
使用素数相乘法得到结果:A字符串包含B字符串
2.3 位运算法
用位运算(26位整数表示)为长字符串A计算出一个“签名”(利用位或运算),再逐一将短字符串B中的字符放到A中进行查找(PS:利用位与运算)。具体代码如下:
package com.liuzhen.string_1; public class StringContain { //方法3:位运算法 /* * 参数A:给定的长字符串A * 参数B:给定的短字符串B * 函数功能:如果B中每个字符进行处理后的对应二进制值与A中所有字符进行处理对应二进制值的求或运算 * ,在单独进行求与运算,一旦出现0,则返回false,否则返回true */ public boolean placeContain(String A,String B){ boolean result = true; char[] arrayA = A.toCharArray(); char[] arrayB = B.toCharArray(); int hash = 0; for(int i = 0;i < arrayA.length;i++) hash |= (1 << (arrayA[i] - 'a')); //|=意思是位或运行,即将hash的二进制与|=后数字进行或运算结果赋值给hash for(int j = 0;j < arrayB.length;j++){ if((hash & (1 << (arrayB[j] - 'a'))) == 0){ //进行与运算,即当A中不包含arrayB[j]字符时 result = false; return result; } } return result; } public static void main(String[] args){ StringContain test = new StringContain(); String A = "abcd"; String B = "aab"; if(test.placeContain(A, B)) System.out.println("使用位运算法得到结果:A字符串包含B字符串"); else System.out.println("使用位运算法得到结果:A字符串不包含B字符串"); } }
[b]运行结果:[/b]
使用位运算法得到结果:A字符串包含B字符串
相关文章推荐
- 算法笔记_028:字符串转换成整数(Java)
- 算法笔记_136:交替字符串(Java)
- 算法笔记_028-字符串转换成整数(Java)
- 算法笔记_028-字符串转换成整数(Java)
- 算法笔记_022:字符串的旋转(Java)
- 算法笔记_134:字符串编辑距离(Java)
- java 截取一个包含汉字的字符串的前n个字节的算法
- 算法笔记_025:字符串的全排列(Java)
- [算法 笔记]字符串移位包含问题
- 算法笔记_028-字符串转换成整数(Java)
- JAVA 数据结构与算法学习笔记一(转载)
- java一个算法题:输出一个字符串中出现次数最多的字符,以及次数
- J2SE学习笔记3 — Java基本语法(5)字符串和构建字符串
- java实现编辑距离算法,计算字符串相似度
- java 学习笔记(二) 字符串分割
- Java程序练习-判断字符串包含
- 算法题:给定一字符串,求其包含给定字符集中所有字符的最短子串
- Java字符串反转算法实现
- 每天学习一算法系列(30)(给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str 里包含{a,b,c}的最短子串。要求O(n).)
- Java学习笔记-字符串