2020年6月22日 模式匹配 patternMatching
默认格式:
class Solution {
public boolean patternMatching(String pattern, String value) {
}
}
解题思路:
首先,这两个字符串单独存在并没有任何意义,比如单独的字符串value是没办法区分出哪个属于a哪个属于b,可以认为整个value就是一个a或者b,所以我们要先借助pattern得到a,b对应的字符的长度。
那么问题就是如何计算这个长度,我们通过pattern的长度,value的长度和pattern中a,b的个数这几个可以得到的数值加上设定a对应的字符串,b对应的字符串长度A,B,可以得到下面的二元一次方程。
a*A+b*B=value.length
单单这等式我们还是没法算出A和B的值
但是我们已经可以得到A的取值范围,这样已经帮我们减去了很大一部分的计算。就这样先写一写代码能否实现。
坑1:
a和b可以代表空字符,但是不能同时代表空字符。
实际在写的过程要判断许多特殊的情况,a的长度为0,b的长度为0等。加上这些判断
public boolean patternMatching(String pattern, String value) {
//经常用到存一下,可以减少消耗
int len=value.length();
//先计算出a和b的个数
int aNum=0;
int bNum=0;
char ca='a';
char[] chars=pattern.toCharArray();
for (int i=0;i<chars.length;i++){
if (chars[i]=='a')
aNum++;
}
bNum=chars.length-aNum;
if (aNum==0&&bNum==1)
return true;
else if (bNum==0&&aNum==1)
return true;
else if ((bNum==0||aNum==0)&&len==0)
return true;
else if (bNum==0&&aNum==0)
return false;
//当b对应的长度为0时,存在a的最大长度,如果a的长度为0,ab互换位置
if (aNum==0){
aNum=bNum;
bNum=0;
ca='b';
}
int maxA=len/aNum;
for (int i=0;i<=maxA;i++){
//能够整除,说明此时的i能够作为a代表的长度
if((bNum==0&&len==i*aNum)||(bNum!=0&&(len-i*aNum)%bNum==0)){
//初始化a和b对应的字符串
String a=null;
String b=null;
//记录操作的位置
int index=0;
int bi;
//记录b对应的长度
if (bNum!=0)
bi=(len-i*aNum)/bNum;
else
bi=0;
//开始进行模式匹配
for (int j=0;j<chars.length;j++){
if(chars[j]==ca){
if (a!=null){
//如果字符串匹配,尝试下一个
if (a.equals(value.substring(index,index+i )))
{
index+=i;
}
//否则跳出循环
else
break;
}else {
a=value.substring(index,index+i);
if (b!=null&&b.equals(a))
break;
index+=i;
}
}else {
if (b!=null){
if (b.equals(value.substring(index,index+bi )))
{
index+=bi;
}else
break;
}else {
b=value.substring(index,index+bi);
if (a!=null&&a.equals(b))
break;
index+=bi;
}
}
if (index==len&&j==chars.length-1)
return true;
}
}
}
return false;
}