字符串能否由子串循环得到(substring,replaceAll)-java

该博客探讨了如何判断一个非空字符串是否能由其子串循环得到。通过分析思路,指出最长可能的子串是字符串的一半,并使用substring截取和replaceAll进行正则替换来验证子串是否能循环构成原字符串。如果可以,输出最长子串;否则,输出“false”。涉及的主要方法包括substring和replaceAll。
题目

给出一个非空的字符串,判断这个字符串是否是由它的一个子串进行多次首尾拼接构成的。输出满足条件的最长子串,否则输出false。
例如,“abcabcabc"满足条件,因为它是由"abc"首尾拼接而成的,则输出"abc”,而"abcab"则不满足条件,则输出 “false”。

思路

子串最长不过是字符串的一半,每次使用substring()截取子串,循环去掉末位,用replaceAll()和正则表达式判断子串是否可以循环得到字符串。

知识点
  1. public String substring(int beginIndex, int endIndex):返回字符串的子字符串。第二个参数可选,两个参数分别表示起始位和末位。
  2. public String replaceAll(String regex, String replacement):使用给定的参数 replacement 替换字符串所有匹配给定的正则表达式的子字符串。第一个参数表示匹配此字符串的正则表达式。第二个参数表示用来替换每个匹配项的字符串。成功则返回替换的字符串,失败则返回原始字符串。
import java.util.Scanner;

public class Main {
 
    public static void main(String[] args){
 
        Scanner sc = new Scanner(System.in); 
 
        String str = sc.nextLine(); // 这里只给一个字符串,所以不需要用while循环接收字符串。
        // 如果需要使用while,则注意:采用has xxxx的话,后面也要用next xxxx。比如前面用hasNextLine,那么后面要用 nextLine 来处理输入。
 
        int i = str.length() / 2; // 最长也不过是原字符串长度的一半
 
        for(; i >= 0; i--) {
 
            String sub = str.substring(0,i); // 每次截取前i个字符串
 
            if(str.replaceAll(sub,"").length() == 0) { // 利用正则表达式,替换原字符串的内容,如果最后为空,说明可以被完全替换,所以是最长字串
 
                System.out.println(sub);
 
                return;
 
            }
 
        }
 
        System.out.println(false);
 
    }
 
}
Java中,获取字符串子串可以通过`String`类的`substring()`方法实现。以下是详细说明和示例: --- ### **1. `substring()` 方法的基本用法** #### **(1) 方法签名** ```java public String substring(int beginIndex) // 从beginIndex到字符串末尾 public String substring(int beginIndex, int endIndex) // 从beginIndex到endIndex-1 ``` - **参数**: - `beginIndex`:起始索引(包含,从0开始)。 - `endIndex`:结束索引(不包含)。 - **返回值**:新的子字符串(原字符串不变,String不可变)。 #### **(2) 示例代码** ```java String str = "Hello, World!"; // 获取从索引7到末尾的子串 String sub1 = str.substring(7); // "World!" // 获取索引0到5的子串(不包含5) String sub2 = str.substring(0, 5); // "Hello" System.out.println(sub1); // 输出: World! System.out.println(sub2); // 输出: Hello ``` --- ### **2. 注意事项** #### **(1) 索引越界异常** - 如果`beginIndex`或`endIndex`超出范围(`<0`或`>str.length()`),或`beginIndex > endIndex`,会抛出`StringIndexOutOfBoundsException`。 - **示例**: ```java String str = "Java"; String sub = str.substring(2, 10); // 抛出异常 ``` #### **(2)字符串处理** - 如果`beginIndex == endIndex`,返回空字符串`""`。 ```java String str = "Java"; String sub = str.substring(2, 2); // 返回 "" ``` #### **(3) 性能考虑** - `substring()`在Java 7及以后版本中会创建新字符串对象并复制字符数据(早期版本可能共享原字符串的字符数组,存在内存泄漏风险)。 --- ### **3. 实际应用场景** #### **(1) 提取文件名后缀** ```java String fileName = "example.txt"; String extension = fileName.substring(fileName.lastIndexOf(".") + 1); // "txt" ``` #### **(2) 分割字符串** ```java String data = "2023-01-01"; String year = data.substring(0, 4); // "2023" String month = data.substring(5, 7); // "01" ``` #### **(3) 结合其他方法(如`indexOf()`)动态截取** ```java String url = "https://example.com/path?query=123"; int start = url.indexOf("com/") + 4; int end = url.indexOf("?"); String path = url.substring(start, end); // "/path" ``` --- ### **4. 替代方案** #### **(1) 使用`StringBuilder`或`StringBuffer`** - 适用于需要多次修改字符串的场景(但直接截取子串仍推荐`substring()`)。 #### **(2) 正则表达式** - 复杂模式匹配时可用`Pattern`和`Matcher`: ```java String text = "Date: 2023-01-01"; String date = text.replaceAll(".*(\\d{4}-\\d{2}-\\d{2}).*", "$1"); // "2023-01-01" ``` --- ### **5. 完整代码示例** ```java public class SubstringExample { public static void main(String[] args) { String str = "Java Programming"; // 基本用法 System.out.println(str.substring(5)); // "Programming" System.out.println(str.substring(0, 4)); // "Java" // 动态截取 int spaceIndex = str.indexOf(" "); String lastName = str.substring(spaceIndex + 1); // "Programming" // 错误处理 try { System.out.println(str.substring(10, 5)); // 抛出异常 } catch (StringIndexOutOfBoundsException e) { System.out.println("索引越界!"); } } } ``` --- ### **6. 关键总结** | 方法 | 作用 | 示例输入 | 输出 | |---------------------|-----------------------------|---------------|-------------| | `substring(begin)` | 从begin到末尾 | `"Java", 2` | `"va"` | | `substring(b, e)` | 从b到e-1 | `"Java", 0,4` | `"Java"` | | 异常情况 | 索引越界时抛出异常 | `"Java", 5,10`| 抛出异常 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值