【algorithm】字符串操作

包含子串问题

案例一:子串问题 KMP

private static void example1() {
  String str = " aaxaababaaaba";
  String sub = " ababaaaba";
  int index = JudgeStrContainsSub(str, sub);
  System.out.println("index = " + index);
}

private static int JudgeStrContainsSub(String str, String sub) {
  char[] strChar = str.toCharArray();
  char[] subChar = sub.toCharArray();
  int[] subNext = next(subChar);
  int i = 1, j = 1;
  while ((i <= strChar.length - 1) && (j <= subChar.length - 1)) {
    if (j == 0 || strChar[i] == subChar[j]) {
      i ++;
      j ++;
    } else {
      j = subNext[j];
    }
  }
  if (j > subChar.length - 1) {
    return i - (subChar.length - 1);
  }
  return 0;
}

private static int[] next(char[] subChar) {
  //i前缀, j后缀
  int i = 1, j = 0;
  int[] next = new int[subChar.length];
  next[1] = 0;
  while (i < subChar.length - 1) {
    if (j == 0 || subChar[i] == subChar[j]) {
      i ++;
      j ++;
      next[i] = j;
    } else {
      j = next[j];
    }
  }
  return next;
}

旋转词问题

案例二:旋转词
eg:1234 的旋转词:1234、2341、3412、4123
解决:将1234 拼接 12341234,子串(用KMP)就是旋转词

private static void example2() {
  String rotateSource = "1234";
  String rotateDest = "3421";
  String rotate = rotateSource + rotateSource;
  if (JudgeStrContainsSub(rotate, rotateDest) != 0) {
    System.out.println("是旋转词。");
  } else {
    System.out.println("不是旋转词");
  }
}

以空格位置逆序字符串

案例三:dog loves cat —-> cat loves dog
思路:将所有逆序: tac sevol god,再将每个单词逆序

private static void example3() {
  String reverseSource = "dog loves cat";
  String reverse1 = reverseStr(reverseSource, 0, reverseSource.length() -1);
  int s = 0 , d = 0;
  while(d != -1) {          
    d = reverse1.indexOf(" ", s);
    if (d != -1) {              
      reverse1 = reverseStr(reverse1, s, d - 1);
    } else {
      reverse1 = reverseStr(reverse1, s, reverse1.length() -1);
    }
    s = d + 1;
  }
  System.out.println(reverse1);
}

private static String reverseStr(String reverseSource, int s, int d) {
  char[] ch = reverseSource.toCharArray();
  char temp;
  while (s < d) {
    temp = ch[s];
    ch[s] = ch[d];
    ch[d] = temp;
    s ++;
    d --;
  }
  StringBuilder sb = new StringBuilder();
  for (char c : ch) {
    sb.append(c+"");
  }
  return sb.toString();
}

根据给定位置逆序字符串

案例四:o(n)

  • 问题:
    这里写图片描述

  • 思路:
    这里写图片描述

private static void example4() {
  String selectReverse = "ABCDE";
  int i = 2;
  selectReverse = reverseStr(selectReverse, 0, i);
  selectReverse = reverseStr(selectReverse, i + 1, selectReverse.length() - 1);
  selectReverse = reverseStr(selectReverse, 0, selectReverse.length() - 1);
  System.out.println(selectReverse);
}

拼接字符串字典顺序最小

案例五:o(n*logn)

思路:str1 + str2 < str2 + str1,则是str1放在前面。
这里写图片描述

private static void example5() {
  String[] str1 = {"ba", "b"};
  String[] str2 = {"abc", "ddf", "de"};
  System.out.println(findSmallest(str1, str1.length));
  System.out.println(findSmallest(str2, str2.length));
}

private static String findSmallest(String[] str, int length) {
  if (str == null || length == 0) {
    return null;
  }
  Arrays.sort(str, new Comparator<String>() {

    @Override
    public int compare(String o1, String o2) {
      return (o1 + o2).compareTo(o2 + o1);
    }
  });
  StringBuilder stitch = new StringBuilder();
  for (String s : str) {
    stitch.append(s);
  }
  return stitch.toString();
}

把空格替换成其他字符串

案例六:将空格替换成%20
从后往前

private static void example6() {
  String str = "a b c";
  String repl = "%20";
  int count= 0, from = 0, index = -1;
  while ((index = str.indexOf(" ", from)) > 0) {
    count++;
    from = index + 1; 
  }
  char[] chs = new char[str.length() + count * (repl.length() - 1)];
  int i = str.length() - 1, j = repl.length() - 1, k = chs.length - 1;
  while(i >= 0) {
    if (str.charAt(i) != ' ') {
      chs[k] = str.charAt(i);
      k --;
    } else {
      while (j >= 0) {
        chs[k] = repl.charAt(j);
        j --;
        k --;
      }
      j = repl.length() - 1;
    }
    i --;
  }
  for (char c : chs) {
    System.out.print(c);
  }
}

最长无重复子串

案例七:最长无重复子串
思路:需要一个set,从左往右遍历字符串,
如果不包含,添加到set、并计算现在的子串长度
如果包含,就移除到出现这个字符之后的位置。
这里写图片描述

private static void example7() {
  String str = "ababcdbe";
  int n = str.length();
  Set<Character> set = new HashSet<Character>();
  int ans = 0, i = 0, j = 0;
  while (i < n && j < n) {
    if (!set.contains(str.charAt(j))){
      set.add(str.charAt(j++));
      //System.out.println("i:" + i +",j:" + (j - 1));
      //System.out.println("add:" + str.charAt(j - 1));
      ans = Math.max(ans, j - i);
      //System.out.println("ans:" + ans);
    }
    else {
      set.remove(str.charAt(i++));
      //System.out.println("i:" + (i - 1) +",j:" + j);
      //System.out.println("remove:" + str.charAt(i - 1));
    }
  }
  System.out.println(ans);
}

左右括号匹配

这里写图片描述
思路:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值