算法之字符串
反转字符串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进行输入输出:
- 手动引入import java.util.Scanner;
- 类名默认写为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对象中。
找出字符串中第一个匹配项的下标※
- 用暴力解法,两层循环遍历,则时间复杂度为O(m*n),一旦不满足,将needle数组重新返回到下标0位置
- 使用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


浙公网安备 33010602011771号