字符串基础2

本文探讨了字符串处理的两种策略,包括去除连续k个0的动态方法及回文串的API解法,并详细阐述了KMP算法和Rabin-Karp算法在模式匹配中的应用,同时分析了它们的时间复杂度和优化方案。此外,还介绍了滚动哈希在提高匹配效率上的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

去掉字符串连续的k个0,k为动态输入。
思路1:用replaceAll的正则是替换k个0为空,正则表达式0{k}
思路2:进行count计数,出现的0,
伪代码如下:
    repalcek(string s,int k):
        int count=0;
        Stringbuiler sb = new 
        for(int i=0;i<s.length;i++)
            char c = s.charAt(i)
            if(c=='0')
               count++;
            else   //要加上所有的0
               for(int j=0;j<count%k;j++)
                  sb.append('0')
               sb.append(c)
               count=0;
        最后全是0还需要加入sb里面
        for(int j=0;j<count%k;j++)
            sb.append('0')
        return sb.toString
          
回文串的解法:            
用java的api解法,stringbuilder.reverse().equals(src)
输出所有是回文数的四位数字
对于数字ijji的特点,不用进行上述api的调用打印特别繁琐
void polindromNumber()
    for(int i=1;i<10;i++)
       for(int j=0;i<10;j++)
           system.out.print i*1000+j*100+j*10+i


字符串匹配的模式匹配
思路1:运用rabbinkarp算法,首先构造hash函数
和进制类似求出每个字符的数目。

void hash(string s) 
    int seed=31
    int hash=0
    for(int i=0;i<s.length;i++)
       hash = hash*seed+charAt(i)
    return hash
void match(string s,string p)
    int p_hash = hash(p)
    int p_length = p.length;
    for(int i=0;i+p_length<s.length;i++)m
        int s_hash=hash(i,i+p_length) //n
        if(s_hash==p_hash)
           system.out.print("match"+i)
但是上面的算法复杂度是o(m*n)所以还需要优化

思路2:运用滚动hash算法,滚动hash,是防止每次都计算
重复位的hash。比如我们计算过了123位的,再次计算234的时候
可以不用再重复计算23,直接通过整体123*seed+4-1*seed的3次方
返回一个hash数组
伪代码如下:
n代表的是匹配串长度
long[] hash2(string s, int n)
    long[] res = new long[s.length-n+1]
    res[0] = hash(s.substring(0,n))
    for(i =n;i<s.length;i++)
       charnew = s.charAt(i)
       charold = s.charAt(i-n)
       long v = (res[i-n]*seed+charnew-charold*seed的n次方)%long.MAX_VALUE//为了防止越界
       res[i-n+1]=v
    return res;

总结:这种匹配出来的hash每10万个冲突3个,每100万大概冲突100个,所以在比较的时候可以进行优化
     例如在比较完hash的时候再比较字符串。。。。这里的冲突是指不同的字符串得到了相同的hash值


KMP的暴力解法的匹配字符串算法
void match(string s, string p)
    i指针指向s
    j指针指向p
    如果si=sp,则i++,j++
    if j>=p.length; return true
    if si!=sp
       j=0
       i
   for(int i=0;i<s.length;i++)
       for(int j=0;j<p.length;j++)
           if(s[i]==p[j])
               i++;
               j++;
              if(j>=length)
                  system.out.print p
              break;
           else
               break

参考伪代码
    match(string s, string p)
        int i=0;
        int sc=i; 扫描指针
        int j=0
        while(sc<.length) 
           if(s.chartAt(sc)==p.charAt(j))
              sc++;
              j++;
              if(j==p.length)
                 return i //这里只匹配一次吗?为啥不是打印
            else 
               i++;
               sc=i; 扫描指针以i为起点
               j=0
         return -1;
       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值