字符串同源异构
相同字符组成的,顺序不一样的字符串。从一个源字符串中查询子字符串。要满足子字符串的字符,在源字符中顺序存在,不能分割存在。如一个是源string: caabcb 目标string: acabb 。源字符中aabcb就是目标字符串(acabb )的同源异构体
构造窗口模式查询
1、需要构建目标string: acabb的字符串个数表。如欠债表:a=2,c=1,b=2
2、定义一个目标窗口和目标字符串一样大小 以及是否找到了同源异构的flag,默认flag=0,可以找到满足的同源异构体
2、第一个窗口个数遍历:从源来字符串里从头遍历,如果一个字符串出现在欠债表里,则欠债表里的相应字符串的个数减一,如果该字符个数小于0,则flag加1。标示此时窗口中的该字符的个数比目标串的该字符个数多。第一个窗口都是入窗的数据。
3、当第一1个遍历完窗口[0…M-1]的大小的数据后,下一个窗口遍历是[1…M],
这是需要处理逻辑和第一次遍历窗口的逻辑不一样
第二次以及以后窗口向左边移动的时候,如果进入窗口的字符,如果在欠债表里该字符个数已经小于等于0了,那么再进入窗口中,flag++(ps:标示比目标串中该字符又多1个)。欠债表里的相应字符串的个数减一。
从左边出去的窗口数据[R-M] ,如果该字符的个数已经小于0,则flag–(ps:标示比目标串中该字符的个数可以少了一个),欠债表里该字符串的个数+1.(ps:我已经出窗口了,不再比较了,原来减少的字符可以还原了)
代码实现*
public class CommpareString {
/**
* 有2个string,一个是源string: caabcb 目标string: acabb
* 从源string里找到 目标的同源异构
* 返回同源异构的起始位置
*/
/**
* 根据目标串新建欠债表,每个字符出现次数
* a=2
* c=1
* b=2
*/
public static void main(String [] args){
CommpareString commpareString = new CommpareString();
int a= commpareString.commpareStr("acabb","caabcb");
System.out.println(a);
}
public int commpareStr(String tarskStr,String orgStr ){
// String tarskStr="acabb";
char tar [] = tarskStr.toCharArray();
int count []= new int[256];
for(int i=0;i<tar.length;i++){
count[tar[i]]++;
}
//count[a]=2 count[c]=1 count[b]=2
//定义一个目标窗口和目标字符串一样大小 以及是否找到了同源异构的flag,flag=0代表找到了,flag=整数则表示多余字符,为负数,则缺少字符
//什么叫欠债表呢
//从源来字符串里从头遍历,如果一个字符串出现在欠债表里,则欠债表里的相应字符串的个数减一,如果个数小于0,则flag--
//当第一次遍历完窗口[0...M-1]的大小的数据后,下一个窗口遍历是[1...M],
//这是需要处理逻辑和第一次遍历窗口的逻辑不一样
//第二次以及以后窗口向左边移动的时候,如果进入窗口的字符,如果在欠债表里已经<=0,那么flag++,且欠债表里的相应字符串的个数减一
//从左边出去的窗口数据[R-M] 以及<0,则flag--,则欠债表里响应字符串的个数+1
//进入窗口的字符,在欠债表里个数-1,出去窗口的字符,在欠债表里个数+1(ps:还给欠债表)
int M=tarskStr.length();
char org[] =orgStr.toCharArray();
int R=0;
int flag=0;
for(;R<M;R++){
System.out.println(org[R] +"="+count[org[R]]);
if(count[org[R]]--<=0){//在-1之前已经是0了,如果再次-1必然是负数,flag+1(我欠表里字符一个)
flag++;
}
}
for(;R<org.length;R++){
if(flag==0)
return R-M;
if(count[org[R]]--<=0){
flag++;
}
if(count[org[R-M]]++ <0){
flag--;
}
}
return flag==0?R-M:-1;
}
}
窗口的作用
窗口的大小和目标串一致。进入窗口的字符,从cout中减1,出去窗口的字符,从cout中加1。flag是比较器,如果flag++,标识欠目标串的。flag–,标识还给目标串的。最后如果flag==0,标识匹配到了。