算法之字符串

反转字符串II

思路:将begin到begin+k-1的部分进行翻转,其中中间节点的下标值为begin+k-1,一轮结束后新的起点下标为begin=begin+2*k,判断条件为字符串长度>begin+k-1。

java基础:

  • StringBuffer中不需要将地址再传回,使用方法时会将地址作为形参传入到方法体内,在方法体中的修改将是最终结果。
  • 使用StringBuffer.setCharAt()可以修改指定位置的字符
public String reverseStr(String s, int k) {
        StringBuffer str=new StringBuffer(s);
        int begin=0;
        while (str.length()>=begin+k){
            reverse(str,begin,begin+k-1);
            begin=begin+2*k;
        }
        if (str.length()-begin>1){
            reverse(str,begin,str.length()-1);
        }
        return str.toString();
    }

    public void reverse(StringBuffer str,int begin,int end){
         while (begin<end){
             char temp=str.charAt(begin);
             str.setCharAt(begin,str.charAt(end));
             str.setCharAt(end,temp);
             begin++;
             end--;
         }
    }

 

替换数字※

此题使用了StringBuffer中的replace函数,投机了,二刷要自己构造replace函数。

使用ACM进行输入输出:

  1. 手动引入import java.util.Scanner;
  2. 类名默认写为public class Main()

要有主函数 public static void main(String[] args){}

import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String s=scanner.next();
        repalceNumber(s);
    }
    public static void repalceNumber(String s) {
        StringBuffer strB = new StringBuffer(s);
        for (int i = 0; i < strB.length(); i++) {
            char c = strB.charAt(i);
            if (c <= '9' && '1' <= c) {
                strB.replace(i, i + 1, "number");
                i = i + 5;
            }
        }
        System.out.println(strB.toString());
    }
}

 

反转字符串中的单词

基础思想:先去掉字符串的头空格和尾空格,然后将整个字符串中的字母顺序逆转,此时单词和位置皆反,再将单词逆转。

本题卡在了将单词逆转,如何获得每个单词的头位置和尾位置,只有当指向的字符不是' '时,指针才能继向下指,否则需要接收判断。

StringBuffer基操:strB.delete(int start,int end)删除StringBuffer中位置从start到end-1的字符串

public String reverseWords(String s) {

    StringBuffer strB=new StringBuffer(s);
    removespace(strB);
    reverseWord(0,strB.length()-1,strB);
    int start;
    int i = 0;
    while( i < strB.length()) {//卡住部分
        start=i;
        while (i<strB.length()&& strB.charAt(i)!=' '){
            i++;
        }

        reverseWord(start,i-1,strB);

        while (i<strB.length()&&strB.charAt(i+1)==' '){
            strB.delete(i+1,i+2);
        }
        i++;
    }
    return strB.toString();
}

 使用库函数思想:使用String.trim()去掉头和尾部空白

        再使用String.split(' ')将字符串按照空格进行拆分得到每个单词对应的字符串数组

        最后再使用方法为:StringBuffer.append(String s),倒序将字符数组插入到新建的StringBuffer对象中。

 

找出字符串中第一个匹配项的下标※

  1. 用暴力解法,两层循环遍历,则时间复杂度为O(m*n),一旦不满足,将needle数组重新返回到下标0位置
  2. 使用KMP思想,构建next数组,数组表示最长相等的前后缀长度,此时一旦不满足,needle数组就不会返回到最初位置,而是会返回到前一个位置的next值位置。

  getNext()方法为具体next的实现代码,初始化next[0]=0,且j表示前缀的末尾,i表示后缀的末尾,i初始化值为1。

  当后缀的末尾和前缀的末尾不相等时,j需要指向到前一个位置的next值,且需要循环比较.

  当后缀末尾和前缀末尾相等时,j往后移。

 public int strStr(String haystack,String needle){
        if (needle.length()==0) return 0;

        int[] next=new int[needle.length()];
        getNext(next,needle);

        int j=0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j>0 && haystack.charAt(i)!=needle.charAt(j)){
                j=next[j-1];
            }
            if (haystack.charAt(i)==needle.charAt(j)){
                j++;
            }
            if (j==needle.length()){
                return i-needle.length()+1;
            }
        }
        return -1;
    }

    private void getNext(int[] next, String needle) {
        int j=0;
        next[0]=0;
        for (int i=1;i<needle.length();i++){
            while (j>0 && needle.charAt(i) != needle.charAt(j)){
                j=next[j-1];
            }
            if (needle.charAt(i)==needle.charAt(j)){
                j++;
            }
            next[i]=j;
        }
    }

重复的子字符串

基础思想:使用简单的额暴力循环,共三层,最外层控制子字符串,中层和最里面层对子字符串和字符串进行循环对比,当不相等时,跳到最外层使子字符串增加一位。需要使用标签flag

 

posted @ 2025-01-06 09:45  Dyj07  阅读(24)  评论(0)    收藏  举报