有一源串和一模式串,编写一个算法求源串中和模式串相同的字串的起始下标
例:String s = “bsadbsadbsadasbd”;
String p = “bsad”;
返回0,4,8
思路
方法1:哈希法
1)将模式串按照某一进制转换为一个哈希值
如将“basd”按照31进制转换:
“b” * 31^3 +“a” * 31^2+“s” * 31^1+ “d” * 31^0
2)每次从源串中取模式串同样长度的子字符串计算哈希值
3)如果子字符串的哈希值和模式串的哈希值相等,则匹配成功,否则取下一组计算
代码:
public class 字符串匹配{
final static long SEED = 31;
public static void main(String[] args) {
String s = "ASDASDASD";
String p = "ASD";
match(p,s);
}
public static void match(String p, String s) { //p为模式,s为原字符串
long hash_p = hash(p);
for (int i = 0; i <= s.length() - p.length(); i++) {
long hash_temp = hash(s.substring(i, i + p.length()));//substring(begin,end)返回下标从begin到end-1的子字符串
if(hash_temp == hash_p) {
System.out.println("Match: "+ i);
}
}
}
public static long hash(String str) {
long hash = 0;
for (int i = 0; i < str.length(); i++) {
hash = hash + str.charAt(i) * (long)Math.pow(SEED,str.length() - 1 - i);
}
return hash;
}
}
方法2:尺取法
- 1)将源串s和模式串p分别存入字符数组s_array和p_array
- 2)指针i指向待匹配的子串的开始位置(初始指向s_array的第一个元素)
- 3)指针j指向待比较的字符(初始指向p_array的第一个元素)
- 4)指针scanner向前扫描(初始指向s_array的第一个元素
- 5)scanner指向的元素如果和指针j指向的元素相等就继续向前(j也向前),不相等则j重新回起点,i向后移
- 6)如果j走到头说明找到了一个和模式串匹配的子字符串
代码:
public class 字符串匹配 {
public static void main(String[] args) {
String s = "bsadbsadbsadasbd";
String p = "bsad";
match(s,p);
}
public static void match(String s, String p) {
char[] s_array = s.toCharArray();
char[] p_array = p.toCharArray();
int i = 0;
int j = 0;
int scanner = 0;
while(i <= s_array.length - p_array.length) {
if(s_array[scanner] == p_array[j]) {
scanner++;
j++;
}
else {
j = 0;
i++;
scanner = i;
}
if(j == p_array.length) {
System.out.println(i);
i = scanner;
j = 0;
}
}
}
}