字符串最短子串

 

package com.java.ly2011.Semptember;

/**
 * 最短子串
 * 串src中,包含串dest的 最短
 * @author Acer
 *
 */
public class MinSubStr {
 
 public static void main(String[] args) {
  char[] src = new char[]{'a','d','b','c','d','a','c','b','d','c','d','a'};
  
  char[] dest = new char[]{'a','b','c'};
  
  getMinSubStr(src, dest);
  
 }
 
 /**
  * 复杂度的话应该是O(n*k) n src的长度    k是dest的长度    
  * 因为n应该远远大于k  所以应该可以算做O(n)
    * @param src 
  * @param dest
  */
 public static void getMinSubStr(char[] src, char[] dest){
  
  int[] num = new int[26];
  
  int resultA=0;
  int resultB=src.length-1;
  
  int begin =-1;
  
  
  for(int end = 0; end< src.length ;end++ ){
   
   num[src[end]-'a']+=1;
   if(findAll(num, dest)){
    while(findAll(num, dest)){
     begin++;
     num[src[begin]-'a']-=1;
     
    }
    //begin指向的字符不能再被去掉,begin就是子串开始的地方
    //此时begin就是一个子串的开始位置 ,end就是该子串的结尾位置,然后判断是否比当前最短的还短
    if((end-begin)<(resultB-resultA)){//比当前最短的还短
     resultA = begin;
     resultB = end;
    }
    
    
   }

   
   
  }
  
  for(int i = resultA ; i<=resultB;i++)
   System.out.print(src[i]);
  
  
  
  
 }
 
 /**
  * 检查待查字符对应的num数组中位置是否都不为0,有为0的返回false,意义为没有全部找到
  * @param num
  * @param dest
  * @return
  */
 public static boolean findAll(int[] num , char[] dest){
  
  for(int i =0 ;i<dest.length;i++){
   
   if(num[dest[i]-'a']==0)
    return false;
   
  }
  
  return true;
  
  
 }
}

### 关于字符串循环子串问题 对于字符串循环子串问题,可以采用多种方法来解决。一种高效的方法是基于 KMP 算法的前缀函数计算得出的结果来进行处理[^2]。 #### 方法概述 通过构建一个新的字符串 `s+s`(即原始字符串与其自身的连接),并去除第一个和后一个字符,可以在新形成的字符串中查找是否存在与原字符串相等的子串。如果存在,则说明该字符串具有周期性;否则不具周期性。具体实现如下: 1. 构建辅助字符串 `concatenatedStr = s + s` 并去掉首尾字符。 2. 使用KMP算法中的部分匹配表(PMT)求解公共前后缀长度数组 next[]。 3. 判断条件:设原字符串长度为len(s),若next[len(s)-1]!=-1且 len(s)%(len(s)-(next[len(s)]+1))==0 成立,则表明有循环节。 这种方法的时间复杂度主要取决于构造PMT的过程以及后续的一次遍历操作,整体上能够保持在线性时间内完成。 ```python def shortest_cyclic_substring(s): concatenated_str = (s * 2)[1:-1] def compute_pmt(pattern): pmt = [-1] * len(pattern) i, j = 0, -1 while i < len(pattern) - 1: if j == -1 or pattern[i] == pattern[j]: i += 1 j += 1 pmt[i] = j else: j = pmt[j] return pmt pmt_result = compute_pmt(concatenated_str) length_s = len(s) if pmt_result[length_s - 1] != -1 and \ length_s % (length_s - (pmt_result[length_s - 1]+1)) == 0: cyclic_length = length_s // ((length_s - (pmt_result[length_s - 1]+1))) return s[:cyclic_length], True return s, False print(shortest_cyclic_substring("abcabc")) # 输出 ("abc", True), 表明 "abc" 是循环子串 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值