0
点赞
收藏
分享

微信扫一扫

字符串相关(Java)

本专栏目录

​​蓝桥杯算法竞赛大纲​​​​数论相关(Java)​​

​​枚举相关(Java)​​

​​​对象排序(Java)​​​

字符串相关(Java)
​​​排序相关算法(Java)​​​​​​

​​记忆化搜索(Java)​​

​​​树论相关(Java)​​

​​​图论相关(Java)​​

​​​堆(Java)​​​​​​

​​贪心(Java)​​


文章目录

  • ​​内置方法​​
  • ​​最长对称字符串​​
  • ​​最长回文子串​​
  • ​​KMP​​
  • ​​马拉车算法​​

内置方法

package 字符串;

public class _内置方法 {

public static void main(String[] args) {

String s = "abcdefghijklmnopq...";

int ind = s.indexOf("gh");
ind = s.lastIndexOf("gh");
boolean flag = s.contains("def");
int f = s.compareTo("abcde");
String newS = s.substring(3);
String s2 = s.replace("d","");
flag = s.startsWith("abc");
flag = s.endsWith("...");
String[] split = s.split(" ");
ind = s.charAt('i');
s.toCharArray();
s.equals("....");
s.concat("123");
s.strip();
s.trim();
s.toLowerCase();
s.toUpperCase();
}
}

最长对称字符串

package 字符串;

import java.util.Scanner;

public class _最长对称字符串 {

public static void main(String[] args) {

Scanner scan = new Scanner(System.in);

String line = scan.nextLine();

// 可能的长度
for (int k = line.length(); k >= 2; k--) {
// 对称字符串开始的位置
for (int st = 0; st + k - 1 <= line.length() - 1; st++) {
int i=st,j = st+k-1; // 一个从头向后,一个从后向前。
for (; i <= j; i++,j--) { // 对称检测
if (line.charAt(i)!=line.charAt(j)){
break;
}
}
if (i>=j){ // 如果在k长度字符串存在对称,则输出。
System.out.println(k);
return;
}
}
}

System.out.println(1);
}
}

最长回文子串

package 字符串;

import java.util.Scanner;

public class _最长回文子串 {

public static void main(String[] args) {

Scanner scan = new Scanner(System.in);
String s = scan.nextLine();

s = longestPalindrome(s);

System.out.println(s);

}

public static String longestPalindrome(String s) {

int len = s.length();

if (len==1){
return s;
}

char[] dest = insertChar(s, '#');
int slen = dest.length;

int[] p = new int[slen];

int maxRight = 0;
int center = 0;
// 这里的maxlen在s中是总的回文字符串的长度,在dest里面是右半径的长度
int maxlen = 1;
//原字符串中回文起始的位置
int begin = 0;

for (int i = 0; i < slen; i++) {

// 更新p[i] 状态转移方程
if (i<maxRight){
int mirror = 2 * center - i;
p[i] = Math.min(p[mirror], maxRight - i);
}

// 中心扩散
int left = i - p[i] - 1;
int right = i + p[i] + 1;
while (left>=0 && right<=slen-1 && dest[left]== dest[right]){
left--;
right++;
p[i]++;
}

// 更新maxRight
if (i + p[i] > maxRight){
maxRight = i + p[i];
center = i;
}

// 更新begin和maxlen
if (p[i] > maxlen){
maxlen = p[i];
begin = (i - maxlen) / 2;
}
}

return s.substring(begin, begin + maxlen);
}

public static char[] insertChar(String s, char c){

char[] src = s.toCharArray();
char[] dest = new char[src.length * 2 + 1];


for (int i = 0; i < dest.length; i++) {
if ((i&1)==0){
dest[i] = c;
}else {
dest[i] = src[i/2];
}
}

return dest;
}
}

KMP

package 字符串;

public class _KMP {

public static void main(String[] args) {

String s1 = "abadcdacdba";
String s2 = "dacd";

// 获取s2的next数组
int[] next = getNextArr(s2);

// s2在s1中的位置
int index = kmp(s1,s2,next);

}

// kmp
public static int kmp(String s1, String s2, int[] next){

char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();

int j = 0;

for (int i = 0; i < c1.length; i++) {

while (j>0 && c1[i]!=c2[j]){
j = next[j-1];
}

if (c1[i]==c2[j]){
j++;
}

if (j==c2.length){
return i-j+1;
}
}

return -1;
}

// 获取next数组
public static int[] getNextArr(String s) {

char[] chs = s.toCharArray();
int[] next = new int[s.length()];

next[0] = 0;

int j = 0;

for (int i = 1; i < next.length; i++) {

while (j>0 && chs[i]!=chs[j]){
j = next[j-1];
}

if (chs[i]==chs[j]){
j++;
next[i] = j;
}

}

return next;
}
}

马拉车算法

字符串相关(Java)_i++
字符串相关(Java)_java_02
字符串相关(Java)_字符串_03
字符串相关(Java)_字符串_04
字符串相关(Java)_算法_05

package 字符串;

// https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/

public class _马拉车算法 {

public static void main(String[] args) {
String s = "abba";
longestPailndrome(s);
}

public static String longestPailndrome(String s){

int len = s.length();
if (len<2){
return s;
}

String str = addDividers(s, '#');

int slen = str.length();

// p[i]: 以预处理字符串下标i为中心的回文半径(奇数长度时不包括中心)
int[] p = new int[slen];

// 通过中心扩散的方式能够扩散的最右边的下标
int maxRight = 0;
// 与maxRight对应的中心字符的下标
int center = 0;

int maxLen = 1;
int begin = 0;

char[] charArray = str.toCharArray();

for (int i = 0; i < slen; i++) {

if (i<maxRight){
int mirror = 2 * center - i;
p[i] = Math.min(maxRight-i, p[mirror]);
}

// 尝试使用中心扩散法,更新p[i]的值
int left = i - (1 + p[i]);
int right = i + (1 + p[i]);
while (left >= 0 && right < slen && charArray[left]==charArray[right]){
p[i]++;
left--;
right++;
}

// 更新maxRight,它是遍历过的 i 的 i+p[i] 的最大者
if (i + p[i] > maxRight){
maxRight = i + p[i];
center = i;
}

// 更新begin 和 maxLen
if (p[i] > maxLen){
maxLen = p[i];
begin = (i - maxLen) / 2;
}

}

return s.substring(begin, begin + maxLen);
}

private static String addDividers(String s, char c) {

char[] src = s.toCharArray();
char[] dest = new char[src.length*2+1];

for (int i = 0; i < dest.length; i++) {
if ((i&1)==0){
dest[i] = c;
}else {
dest[i] = src[i/2];
}
}

return new String(dest);
}
}


举报

相关推荐

0 条评论