第十四周:
代码:
16.18Pattern Matching
package cn.kobe;
public class Solution {
/*
* 都是暴力搜索啊。。。
* */
public boolean patternMatching(String pattern, String value) {
//特殊情况
if(pattern.equals("a")||pattern.equals("b")){
return true;
}
if(pattern.length()==0){
return value.length()==0;
}
//转换为字符数组
char[] pArr=pattern.toCharArray();
char[] vArr=value.toCharArray();
// value为空时,判断pattern是否只有a或只有b
if (value.length() == 0) {
boolean aExist = false,bExist = false;
for (char c: pArr) {
if (c == 'a') {
aExist = true;
}
else {
bExist = true;
}
if (aExist && bExist) {
return false;
}
}
return true;
}
int counta=0,countb=0;
for(char ch:pArr){
if(ch=='a')
counta++;
else
countb++;
}
int lenV=value.length();
if (counta * countb == 0) {
int count = counta + countb;
if (lenV % count != 0) return false;
int len = lenV / count;
String temp=value.substring(0,len);
for (int i = len; i < lenV; i += temp.length()) {
if(!value.substring(i,i+temp.length()).equals(temp)) return false;
}
return true;
}
// //lv=ca*la+cb*lb 遍历这个方程
int a=pArr[0];//用于遍历数组
for(int la=0;la*counta<=value.length();la++){
int rest=lenV-counta*la;
if(rest%countb!=0 ) continue;
int lb=rest/countb,dis=0;//取strb的长度
boolean isMatch=true;
String stra="";String strb="";
for(char ch:pArr){
if(ch==a){
String tempa=value.substring(dis,dis+=la);
if(stra.length()==0){
stra=tempa;
}else if(!stra.equals(tempa)) {
isMatch=false ; break;
}
}else{
String tempb=value.substring(dis,dis+=lb);
if(strb.length()==0){
strb=tempb;
}else if(!strb.equals(tempb)) {
isMatch=false ; break;
}
}
}
if(isMatch&&!stra.equals(strb)) return true;//提前结束
}
return false;
}
}
code_205Isomorphic Strings
package cn.kobe;
public class Solution2 {
public boolean isIsomorphic(String s, String t) {
int n = s.length();
int[] mapS = new int[128];
int[] mapT = new int[128];
for (int i = 0; i < n; i++) {
char c1 = s.charAt(i);
char c2 = t.charAt(i);
//当前的映射值是否相同
if (mapS[c1] != mapT[c2]) {
return false;
} else {
//是否已经修改过,修改过就不需要再处理
if (mapS[c1] == 0) {
mapS[c1] = i + 1;
mapT[c2] = i + 1;
}
}
}
return true;
}
}
学习:继续看了《疯狂的java讲义》50页
这周再分享下位运算的小知识
/*
* 对二进制的更加深入理解
* */
public class BitMethod {
/**-------首先是+-*÷-----*/
//加法
public int add(int a,int b){
while(b!=0){//没有进位为止
int temp=(a&b)<<1;//获取进位
a=a^b;//无进位加法
b=temp;
}
return a;
}
//减法
public int substract(int a,int b){//表示a-b
int temp=add(~b,+1);//计算-b即补码
return add(a,temp);
}
//乘法
public int multiply_01(int a,int b){
//不断累加b;同时还要考虑负数的情况
int multiplicand=a>0?a:add(~a,1);//被乘数
int multiplier=b>0?b:add(~b,1);//乘数
int res=0;
int count=0;
while(count<multiplier){
res=add(res,multiplicand);
count=add(count,1);//count++;
}
//判断结果符号,另一个位运算技巧
if((a^b)<0){
res=add(~res,1);
}
return res;
}
//这里是对上一个版本即改进
//上面的方法中b是多少就要执行多少次,现在模拟二进制乘法
public int multiply(int a,int b){
int multiplicand=a>0?a:add(~a,1);//被乘数
int multiplier=b>0?b:add(~b,1);//乘数
int res=0;
while(multiplier>0){//最前一位是0就停
//乘数当前位是1就将multiplicand*2,是0就+0
res += ((multiplier&1)==1?multiplicand:0);
multiplicand <<=1;
multiplier>>=1;
}
//判断结果符号,另一个位运算技巧
if((a^b)<0){
res=add(~res,1);
}
return res;
}
//除法,可以采用累加的方式,用累减;这里直接写优化的版本,从高倍数向下减
public int divide(int a,int b){
int dividend=a>0?a:add(~a,1);//被除数
int divisor=b>0?b:add(~b,1);//除数
int res=0;
int remianer=0;
for(int i=31;i>=0;i--){
if((dividend>>i)>=divisor){
res = add(res,1<<i);
dividend=substract(dividend,divisor<<i);//尽量不用运算符号
}
}
//判断结果符号,另一个位运算技巧
if((a^b)<0){
res=add(~res,1);
}
//确定余数的符号
remianer= (dividend>0?dividend:add(~dividend,1));
return res;
}
//位运算交换两个数
public void swap(int a,int b){
a=a^b;
b=a^b;
a=a^b;
System.out.println("a:"+a+" b:"+b);
}
//判断奇偶
public boolean isOdd(int x){//这里判断是不是偶数
if((x&1)==0){
return true;
}
return false;
}
//判断一个数是不是2的次幂,其实方法很多,因为2进制的原因,可以用位运算来
//同时可以判读a能不能被a^32整除,这个方法可以推广到判断是不是3次幂4次幂等等
public boolean isPower(int a){
return (a&(a-1))==0;
}
//在第几位上设置为1
public int setBit(int a,int k){
return a|((1)<<(k-1));
}//获取第几位上的数字
public int getBit(int a,int k){
return (a>>(k-1))&1;
}
//循环移动,比如右移
public int removeBit(int a,int k){
return (a>>k)|(a<<(32-k));
}
//取平均数
public int averageBit(int a,int b){
return (a&b)+((a^b)>>1);//就是求和方法的每一步>>1
}
//计算绝对值
public int abs(int a){
//第一种方式:上面用到过了(负数的补码为反码+1)
//return a>0?a:~a+1;
//第二种方式,就是取反的实现
int i=a>>31;
//若a是正数,i->00->0,a对i取反-0为本身
//若a是负数,i->10->-1,a就取反+1
return (a^i)-i;
}
//mod运算,只有a为正数且b=2^n;
public int bitWise(int a,int b){
if(isPower(b)){
return a&(b-1);
}
int dividend=a>0?a:add(~a,1);//被除数
int divisor=b>0?b:add(~b,1);//除数
int res=0;
int remianer=0;
for(int i=31;i>=0;i--){
if((dividend>>i)>=divisor){
res = add(res,1<<i);
dividend=substract(dividend,divisor<<i);//尽量不用运算符号
}
}
//确定余数的符号
remianer= (dividend>0?dividend:add(~dividend,1));
return remianer;
}
public int testMod(int a,int b){
return a%b;
}
public static void main(String[] args) {
BitMethod bit=new BitMethod();
//System.out.println(bit.bitWise(71,70));
long time1=System.currentTimeMillis();
int res1=0;
for (int i = 0; i < 5000000; i++) {
res1=bit.bitWise(new Random().nextInt(i+1),5);
}
long time2=System.currentTimeMillis();
System.out.println("bit.bitWise 用时:"+(time2-time1)+"s----结果是:"+res1);
long time3=System.currentTimeMillis();
int res2=0;
for (int i = 0; i < 5000000; i++) {
res2=bit.testMod(new Random().nextInt(i+1),5);
}
long time4=System.currentTimeMillis();
System.out.println("% 用时:"+(time4-time3)+"s----结果是:"+res2);
/*System.out.println(bit.isPower(256));
System.out.println(bit.abs(-123));
System.out.println(10&7);*/
/*bit.swap(10,11);
System.out.println(bit.isOdd(22));
System.out.println(bit.setBit(10,3));
System.out.println(bit.getBit(15,4));
System.out.println(bit.averageBit(10,6));*/
//System.out.println(bit.divide(120,-3));
/*System.out.println(bit.multiply_01(-12,-15));
System.out.println(bit.multiply(-12,-5));*/
/*System.out.println(bit.add(-10,20));
System.out.println(bit.substract(-10,15));*/
/*long time1=System.currentTimeMillis();
int res1=bit.add(21,2);
long time2=System.currentTimeMillis();
System.out.println("bit.add 用时:"+(time2-time1)+"----结果是:"+res1);
long time3=System.currentTimeMillis();
int res2=21+2;
long time4=System.currentTimeMillis();
System.out.println("add 用时:"+(time3-time4)+"----结果是:"+res2);*/
/** 测试效率 */
/*long time1=System.currentTimeMillis();
int res1=0;
for (int i = 0; i < 500000000; i++) {
res1 =bit.multiply_01(21,2);
}
long time2=System.currentTimeMillis();
System.out.println("bit.multiply_01 用时:"+(time2-time1)+"----结果是:"+res1);
long time3=System.currentTimeMillis();
int res2=0;
for (int i = 0; i < 500000000; i++) {
res2=bit.multiply(21,2);
}
long time4=System.currentTimeMillis();
System.out.println("add.multiply 用时:"+(time3-time4)+"----结果是:"+res2);*/
}
}