素数的定义
素数(质数,prime number)是一种只能被1和本身整除的数。
鼎鼎大名的RSA就是用了素数的基本特性发明的。RSA太难,不容易理解,下面的这个素数的例子就比较容易理解了。
给出两个字符串A和B,写出程序判断B串里面的字符是否都在A串中。例如
A="hssawonderfulwo"
B="who"
这个问题可以有多种解法,比如说把A,B排序,然后比较;或者把A中的每个字符放到Set中,然后在把B的字符依次放到Set中,如果B中字符不能放进去,那么B中的字符A也有。
还有一种方法...
将A和B字符串中的每个字符做素数的映射,比如T=2,h=3,...,
A的所有映射后的素数相乘得到一个很大的数 除于 B的所有映射后的素数相乘得到一个数,根据素数只能被1和本身整除的特点,如果能够整除说明B中的字符A都有。
当然我觉得这种算法可以作为一种“奇技淫巧”来聊聊,现实中如果字符串很长,这种方法可能不适合,因为映射成素数后相乘的值太大了,int 或者long都装不下了。但这并不妨碍我们通过这个例子来学习,素数以及素数的求法。
求素数的一个方法
由于任何一个非素数都可以表示成一些素数的乘积,比如12 = 2*2*3, 15 = 3*5,根据这个特性,我们每找出一个素数,就把这个素数记录下来,添加到一个列表里面,像这样
2,3,5,7,11,13...
算法如下
初始化素数列表里面只有一个数,就是2
当素数列表中的总数 < 你想要的素数的个数
把素数列表中最后数 + 1 除于 素数列表中的每个数,如果不能整除,那么这个数就是素数,
否则继续 + 1,然后类似判断
如果是素数,就添加到素数列表中
Java程序如下
package art.programming.algorithm;
import java.util.ArrayList;
import java.util.List;
public class PrimeNumberFinder {
private List<Integer> primeNumbers = new ArrayList<Integer>();
public PrimeNumberFinder(){
//Initially this list has one prime number 2
primeNumbers.add(2);
}
public List<Integer> findPrimeNumbers(int count){
for (int number = 3; primeNumbers.size() < count ;number++){
for (int i = 0; i< primeNumbers.size(); i++){
int primeNumber = primeNumbers.get(i);
//number如果能够被整除,那么直接跳出循环
if ((number % primeNumber) == 0){
break;
}
if (i== (primeNumbers.size() - 1)){
primeNumbers.add(number);
break;
}
}
}
return primeNumbers;
}
}
接下来,求两个字符串A中是否包括字符串B中的所有字符
package art.programming.algorithm;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class StringMatch {
public static boolean contains(String a, String b){
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (char c : a.toCharArray()){
map.put(c, 0);
}
for (char c : b.toCharArray()){
map.put(c, 0);
}
int noOfChars = map.keySet().size();
List<Integer> primeNumbers = new PrimeNumberFinder().findPrimeNumbers(noOfChars);
int i =0;
for (char key : map.keySet()){
map.put(key, primeNumbers.get(i));
i++;
}
long aResult = 1;
for (char c : a.toCharArray()){
aResult = aResult * map.get(c);
System.out.println(aResult);
}
long bResult = 1;
for (char c : b.toCharArray()){
bResult = bResult * map.get(c);
}
for (char key : map.keySet()){
System.out.println(key + " " + map.get(key));
}
System.out.println("a result " + aResult + " b result " + bResult + " result " + (aResult % bResult));
return (aResult % bResult) == 0;
}
}
测试一下
package art.programming.algorithm;
import org.junit.Test;
public class StringMatchTest {
@Test
public void contains(){
String a = "hssawonderfulwo";
String b = "who";
System.out.println(StringMatch.contains(a, b));
}
}