java算法day7

2024-04-28 00:04
文章标签 java 算法 day7

本文主要是介绍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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/941846

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2