本文主要是介绍java算法day7,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
字符串篇
- java该学的字符串基础
- 反转字符串
- 反转字符串Ⅱ
- 替换数字
java该学的字符串基础。
在Java中,String 类是用来操作字符序列的。Java中的字符串是不可变的,这意味着一旦一个字符串被创建,其内容就不能改变。下面是一些关于Java字符串及其在算法题中常用技巧的详细介绍:
Java中的String类基础
创建字符串:
直接使用双引号:String s = “Hello”;
使用构造函数:String s = new String(“Hello”);
字符串常用方法:
.length() - 返回字符串的长度。
.charAt(index) - 返回指定位置的字符。
.substring(beginIndex, endIndex) - 返回子字符串。
.contains(CharSequence s) - 检查字符串是否包含序列s。
.equals(Object another) - 比较两个字符串的内容是否相等。
.equalsIgnoreCase(String another) - 同上,但忽略大小写。
.split(String regex) - 根据匹配给定的正则表达式来拆分字符串。
.indexOf(String str) - 返回指定子字符串在此字符串中第一次出现处的索引。
.toLowerCase() 和 .toUpperCase() - 转换字符串的大小写。
.trim() - 返回去除前导和尾随空格的字符串副本。
字符串比较:
使用 equals() 方法比较字符串内容,而不是使用 ==,后者比较的是引用。
一个习惯性操作:
想像c++一样,如果String能够按下标访问,修改,那很多题做起来就方便的多。但是上面String由于不可变性。所以它的任何操作并不能够修改字符串的本身。
接下来将解决这个难题。
方法1:转换为字符数组,完成操作后再转为字符串。
看一个例子就懂了。
String s = "Hello";
char[] charArray = s.toCharArray(); //通过toCharArray()方法转换
charArray[1] = 'a'; // 修改第二个字符。变成数组了就可以修改了
String newString = new String(charArray); //创建字符串可以将字符数组传入作为参数。
System.out.println(newString); // 输出 "Hallo"
方法2:使用StringBuffer或者StringBuilder。
StringBuilder
StringBuilder 是一个可变的字符序列。与不可变的 String 类不同,StringBuilder 允许你在原地修改字符串而不需要每次修改都生成新的字符串对象,这样可以大大提高效率。
StringBuilder是一个非线程安全的可变字符序列,它通常比StringBuffer更快,因为它不进行同步。
创建 StringBuilder 对象
你可以通过多种方式创建 StringBuilder 对象:
StringBuilder sb1 = new StringBuilder(); // 创建一个空的StringBuilder
StringBuilder sb2 = new StringBuilder(10); // 指定初始容量
StringBuilder sb3 = new StringBuilder("Hello"); // 从一个字符串开始
常用方法
append() - 添加文本到当前StringBuilder对象的末尾。
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb.toString()); // 输出 "Hello World"
insert() - 在指定位置插入文本
StringBuilder sb = new StringBuilder("Hello World");
sb.insert(6, "Java ");
System.out.println(sb.toString()); // 输出 "Hello Java World"
replace() - 替换StringBuilder中的一部分内容。
StringBuilder sb = new StringBuilder("Hello World");
sb.replace(6, 11, "Java");
System.out.println(sb.toString()); // 输出 "Hello Java"
delete() 和 deleteCharAt() - 删除StringBuilder中的一部分内容或特定位置的字符。
StringBuilder sb = new StringBuilder("Hello World");
sb.delete(5, 11);
System.out.println(sb.toString()); // 输出 "Hello"
sb.deleteCharAt(4);
System.out.println(sb.toString()); // 输出 "Hell"
reverse() - 将StringBuilder中的内容反转。
StringBuilder sb = new StringBuilder("Hello");
sb.reverse();
System.out.println(sb.toString()); // 输出 "olleH"
setCharAt() - 设置指定位置的字符。
StringBuilder sb = new StringBuilder("Hello");
sb.setCharAt(1, 'a');
System.out.println(sb.toString()); // 输出 "Hallo"
length(), capacity() - 获取长度和容量。
StringBuilder sb = new StringBuilder("Hello");
System.out.println("Length: " + sb.length()); // 输出 "Length: 5"
System.out.println("Capacity: " + sb.capacity()); // 输出 "Capacity: 21" (初始容量是16加上字符串长度)
最重要的就是这个sb.toString()转String类型。
使用 StringBuilder 的一个主要优点是它可以避免创建多个临时不可变字符串对象,这在循环或频繁操作字符串内容的场景中非常有用。例如,拼接字符串时,使用 StringBuilder 要比使用 String 直接拼接(使用 + 操作符)效率高得多。
StringBuffer
这两个方法都是类似的,主要区别就在于线程安全性。StringBuffer是线程安全的,而StringBuilder不是线程安全的。这意味着StringBuffer适用于多线程环境中,而StringBuilder则适用于单线程或不需要考虑线程安全的情况。
StringBuffer是一个线程安全的可变字符序列。它通过内部同步来确保多个线程可以安全地同时修改字符串缓冲区。
StringBuffer:在你需要确保字符串操作的线程安全时使用StringBuffer。例如,在web应用服务器或任何多线程应用程序中处理字符串时。
StringBuilder:在单线程环境中或不关心线程安全的情况下使用StringBuilder,因为它没有同步开销,通常会比StringBuffer更快。
总的来说,选择StringBuffer还是StringBuilder主要取决于是否需要线程安全。在性能敏感的应用中,通常推荐使用StringBuilder,除非你需要在多线程环境中操作字符串。
二者都会自动扩容
StringBuffer和StringBuilder都会在需要时自动扩容。这是通过内部机制实现的,以便这两种类型的对象可以在运行时根据需要增加存储容量,以容纳更多的字符。
扩容机制
当你向StringBuffer或StringBuilder添加内容,而当前容量不足以容纳新增的内容时,它们会自动进行扩容。扩容的过程通常涉及以下步骤:
计算新容量:新的容量通常是当前容量的两倍加上2,但这可能因JVM的实现而异。如果这个新计算的容量还不足以容纳新增的数据,那么容量会增加到必要的大小以适应新增的数据。
分配新数组:一旦计算出新的容量,就会创建一个新的字符数组,其大小等于新的容量。
复制数据:原有数组中的数据会被复制到新的数组中。
替换数组:旧的字符数组被新的字符数组替换,旧的数组将被垃圾回收。
反转字符串
这题无论是双指针往中间靠,还是凭借下标的关系都可以完成这个题。
class Solution {public void reverseString(char[] s) {for(int i = 0;i<s.length/2;i++){ //只到中间char temp; //相对的元素进行两两交换。temp = s[s.length-i-1];s[s.length-i-1] = s[i];s[i] = temp;}}
}
翻转字符串Ⅱ
也很简单,主要就是想清楚2k个元素之中的下标位置。在处理好区间的基础上。对每个区间完成翻转字符串即可。
class Solution {public String reverseStr(String s, int k) {char[] str = s.toCharArray(); //先转为字符数组for(int i = 0;i<str.length;){ //这里就没必要对i进行操作了。处理完一个区间后。i直接跳转到下一个区间的起点就可以了。一旦跳转到下一个区间起点不符合i的限制,循环会自动停止的。if(i+2*k-1<=str.length-1){ //当第2k个元素还在字符数组的有效范围。由于下标从0开始,所以第2k个字符的位置在i+2*k-1这个位置。接下来进行翻转数组的操作。//翻转前k个字符int start=i;int end = i+k-1;int goNext = i+2*k; //设置i下一个区间的跳转点。while(start<=end){ //纯纯双指针交换首尾char temp =str[end];str[end] = str[start];str[start] = temp;start++;end--;}i = goNext; //i进行跳转}else{ //这个时候第2k个元素的下标已经超了,检查里面的字符是在1k以上还是1k以下if(i+k-1>=str.length-1){ //检查1k这个地方还在有效范围没有,如果1k这个地方也超了,说明剩余不足1k,全部翻转int start = i;int end = str.length-1;while(start<=end){char temp = str[end];str[end] = str[start];str[start] = temp;start++;end--;}break; //翻转完就可以结束了。因为这种情况只在尾部。}else{//1k这个地方如果还在有效区间,那就翻转前k。int start = i;int end = i+k-1;while(start<=end){char temp = str[start];str[start] = str[end];str[end] = temp;start++;end--;}break;//翻转完就可以结束了。因为这种情况只在尾部。}}}return new String(str); //转为字符串返回}
}
替换数字
题目的意思就每遇到一个数字就改为把这个数字去掉,然后插一个字符串"number"进去。java做这个我感觉最好用的办法就是空间换时间了。用StringBuilder。
思路:遍历字符串,是数字就把number字符串插入,不是数字就把遍历的字符给插入。
我的写法:看着就是有点长了。
import java.util.Scanner;class Main{public static void main(String[] args){Scanner scanner = new Scanner(System.in);String s = scanner.nextLine();String result = replaceNum(s);System.out.println(result);}public static String replaceNum(String s){int count = 0;char[] str = s.toCharArray();for(char c : str){if(c>='0' && c <='9'){count++;}}String insertStr = "number";int numLength = 6;int sum = s.length() - count + numLength*count;StringBuilder sb = new StringBuilder(sum);for(char c:str){if(c>='0'&& c<='9'){sb.append(insertStr);}else{sb.append(c);}}return sb.toString();}}
代码随想录解法:
这个解法简短就在于直接用s.charAt()访问字符串。而我是转字符数组多此一举。
所以以后如果是这种遍历插入构造新字符串的。不涉及修改元素组来进行操作,最好还是用charAt(),如果是原数组进行处理,那么转为字符数组要好做的多。
import java.util.Scanner;class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String s = in.nextLine();StringBuilder sb = new StringBuilder();for (int i = 0; i < s.length(); i++) {if (Character.isDigit(s.charAt(i))) {sb.append("number");}else sb.append(s.charAt(i));}System.out.println(sb);}
}
这篇关于java算法day7的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!