String练习题2--算法题

算法练习:

题目1:模拟一个trim方法,去除字符串两端的空格。

public String myTrim(String str) {
        if (str != null) {
            int start = 0;// 用于记录从前往后首次索引位置不是空格的位置的索引
            int end = str.length() - 1;// 用于记录从后往前首次索引位置不是空格的位置的索引

            while (start < end && str.charAt(start) == ' ') {
                start++;
            }

            while (start < end && str.charAt(end) == ' ') {
                end--;
            }
            if (str.charAt(start) == ' ') {
                return "";
            }

            return str.substring(start, end + 1);
        }
        return null;
    }

    @Test
    public void testMyTrim() {
        String str = "   a   ";
        // str = " ";
        String newStr = myTrim(str);
        System.out.println("---" + newStr + "---");
    }

题目2:将一个字符串进行反转。将字符串中指定部分进行反转。
      比如"abcdefg"反转为"abfedcg"

package chapter11_api.src.com.atguigu01.string.exer2;

import org.junit.Test;

/**
 * ClassName: StringTest2
 * Package: chapter11_api.src.com.atguigu01.string.exer2
 * Description:
 *
 *题目2:将一个字符串进行反转。将字符串中指定部分进行反转。
 *       比如"abcdefg"反转为"abfedcg"
 *
 *
 *
 * @Author 小白
 * @Create 2024/4/9 13:47
 * @Version 1.0
 */
public class StringTest2 {

    @Test
    public void test(){

         String s = "abcdefg";
       // String s1 = reverse(s, 2, 5);
        String s2 = reverse(s, 2, 5);
       // System.out.println(s1);
        System.out.println(s2);


    }

         //reverse:反转
    //reverse()方法也是自己写的 String里面没有这个方法

    //String str,int fromIndex,int toIndex 这几个形参是根据题目要求自己写的 不是哪个方法的构造器
    /*
     * 方式1:将String转为char[],针对char[]数组进行相应位置的反转,反转以后将char[]转为String
     * */
         public String reverse(String str,int fromIndex,int toIndex){

             //将String转为char[]   char[] toCharArray(): 将此字符串转换为一个新的字符数组返回
             // String s = "abcdef";
             // arr 数组的内容为 ['a', 'b', 'c', 'd', 'e', 'f'],即字符串中每个字符对应的元素。
             char[] arr = str.toCharArray();




             for(int i = fromIndex,j = toIndex;i < j;i++,j--){
                 char temp = arr[i];
                 arr[i] = arr[j];
                 arr[j] = temp;
             }

             //通过使用 String类的构造函数 String(char[] value)来实现,该构造函数会根据给定的字符数组创建一个新的字符串对象。
             //public String(char[] value):通过当前参数中的字符数组来构造新的String。
             //将char[]转为String
             return new String(arr);


         }



    /*
     * 第2种方式
     * */
    public String reverse1(String str,int fromIndex ,int toIndex){
        //String substring(int beginIndex, int endIndex) :
        // 返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
        // 创建一个空字符串用于存放反转后的结果
          String finalStr = "";
        //获取str的第1部分
        finalStr = str.substring(0,fromIndex); //ab  abcdefg---->0123456  ab----.01
        //fromIndex的位置是2
        //返回一个新字符串,它是此字符串从0开始截取到fromIndex(2)(不包含)的一个子字符串。
        //char charAt(index):返回[index]位置的字符  比如i=5 那我们就返回索引上的字符f
        //拼接上第2部分
        /*



        * */
        for(int i = toIndex;i >= fromIndex;i--){
            finalStr += str.charAt(i);
        }//abfedc

        //拼接上第3部分
        //String substring(int beginIndex) :
        //返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
        //因为 substring() 方法是左闭右开区间,即 beginIndex 是包含在内的,但 endIndex 是不包含在内的。
        //所以,当我们想要从 toIndex + 1 开始截取字符串时,我们需要传入的参数是 toIndex + 1
        //一定要加1
        finalStr += str.substring(toIndex +1 );


        return finalStr;

    }

}

解释代码:

/* * 方式1:将String转为char[],针对char[]数组进行相应位置的反转,反转以后将char[]转为String * */

 for(int i = fromIndex,j = toIndex;i < j;i++,j--){

char temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

解释:

/*当遍历字符数组时,我们需要交换指定范围内的字符,即从索引 `fromIndex` 到索引 `toIndex` 的字符。在这个例子中,指定的范围是从索引 `2` 到索引 `5`。让我们详细说明如何遍历并交换字符数组中的元素:

1. 首先,我们需要定义两个指针或索引变量,一个从头开始,一个从尾部开始。在这个例子中,`fromIndex` 的值为 `2`,`toIndex` 的值为 `5`。

2. 然后,我们使用一个 `for` 循环来遍历字符数组。在循环中,第一个指针从 `fromIndex` 开始递增,第二个指针从 `toIndex` 开始递减。在每次迭代中,我们交换这两个指针位置上的字符。

3. 在第一次迭代中,我们交换索引为 `2` 和 `5` 的元素;在第二次迭代中,交换索引为 `3` 和 `4` 的元素;然后依次类推,直到两个指针相遇为止。

让我们根据例子 `"abcdef"` 来详细说明: - 我们有一个字符数组 `arr`,其中包含了字符 `'a'`、`'b'`、`'c'`、`'d'`、`'e'` 和 `'f'`,索引从 `0` 到 `5`。

- 现在,我们有两个指针,一个从索引 `2` 开始,一个从索引 `5` 开始。

- 在第一次迭代中,我们交换索引为 `2` 和 `5` 的元素,即 `'c'` 和 `'f'`。此时,字符数组变为 `['a', 'b', 'f', 'd', 'e', 'c']`。

- 在第二次迭代中,我们交换索引为 `3` 和 `4` 的元素,即 `'d'` 和 `'e'`。此时,字符数组变为 `['a', 'b', 'f', 'e', 'd', 'c']`。

- 在第三次迭代中,由于指针相遇,循环结束。 通过以上步骤,我们完成了指定范围内字符的交换,即完成了字符数组的反转操作。最后,我们将反转后的字符数组转换为字符串,并返回结果。

/* * 第2种方式 * */

解释以下代码:

for(int i = toIndex;i >= fromIndex;i--){

finalStr += str.charAt(i);

}//abfedc

解释:

1. 当 `toIndex` 为 5 时,意味着我们应该包括索引 5 的字符,即字符 "f"。而 `fromIndex` 为 2,意味着我们应该包括索引 2 的字符,即字符 "c"。这段代码旨在将从 "c" 到 "f" 的部分进行反转。

2. 我们进入 `for` 循环,`i` 从 5 开始递减,直到 2。

3. 在循环的每一步中,我们从原始字符串的索引位置 `i`(初始为 5)提取字符,并将其添加到 `finalStr` 中。

4. 循环的第一步,我们添加 "f" 到 `finalStr`,因为原始字符串中索引为 5 的位置是 "f"。

5. 循环的第二步,我们添加 "e" 到 `finalStr`,因为原始字符串中索引为 4 的位置是 "e"。

6. 循环的第三步,我们添加 "d" 到 `finalStr`,因为原始字符串中索引为 3 的位置是 "d"。

7. 循环的第四步,我们添加 "c" 到 `finalStr`,因为原始字符串中索引为 2 的位置是 "c"。

8. 当 `i` 等于 `fromIndex`,即 2 时,我们完成了需要反转的部分,因此停止循环。

9. 最终,`finalStr` 变成了 "fedc",这是 "abcdef" 中索引为 2 到 5 的部分反转后的结果。

题目3:获取一个字符串在另一个字符串中出现的次数。
      比如:获取"ab"在 "abkkcadkabkebfkabkskab" 中出现的次数

package chapter11_api.src.com.atguigu01.string.exer2;

import org.junit.Test;

/**
 * ClassName: StringTest3
 * Package: chapter11_api.src.com.atguigu01.string.exer2
 * Description:
 *
 * 题目3:获取一个字符串在另一个字符串中出现的次数。
 *       比如:获取"ab"在 "abkkcadkabkebfkabkskab" 中出现的次数
 *
 * @Author 小白
 * @Create 2024/4/9 13:48
 * @Version 1.0
 */
public class StringTest3 {


@Test
public void test(){

    String subStr = "ab";
    String str = "abkkcadkabkebfkabkskab";

    int count = getSubStringCount(str,subStr);
    System.out.println(count);
}

///获取子字符串的次数


    /**
     * 判断subStr在str中出现的次数
     * @param str
     * @param subStr
     * @return 返回次数
     */
    
    /*让我们逐步解释 `"ab"` 在原始字符串 `"abkkcadkabkebfkabkskab"` 中的出现次数:
1. 首先,我们定义了原始字符串 `str = "abkkcadkabkebfkabkskab"` 和子字符串 `subStr = "ab"`。
2. 我们开始搜索子字符串 `"ab"` 在原始字符串中的出现位置。
3. 首先,我们使用 `indexOf()` 方法找到第一次出现 `"ab"` 的位置。在整个字符串中,第一次出现 `"ab"` 的位置是索引 0。
4. 然后,我们将计数器 `count` 加一,并更新查找索引,使其指向下一个潜在的出现位置。由于我们已经在索引 0 处找到了一个子字符串,因此我们将索引更新为 `0 + 2 = 2`(即当前索引加上子字符串的长度),从这个位置继续搜索下一个可能的出现位置。
5. 在索引 2 处,我们找到了第二个子字符串 `"ab"`。我们再次将计数器 `count` 加一,并更新查找索引为 `2 + 2 = 4`。
6. 在索引 4 处,我们找到了第三个子字符串 `"ab"`。我们再次将计数器 `count` 加一,并更新查找索引为 `4 + 2 = 6`。
7. 在索引 6 处,我们找到了第四个子字符串 `"ab"`。我们再次将计数器 `count` 加一,并更新查找索引为 `6 + 2 = 8`。
8. 在索引 8 处,我们没有找到子字符串 `"ab"`,因此 `indexOf()` 方法返回 -1。
9. 循环结束,我们得到了子字符串 `"ab"` 在原始字符串中出现的总次数,即 4。
所以,根据上述步骤,程序会打印出子字符串 `"ab"` 在原始字符串 `"abkkcadkabkebfkabkskab"` 中出现的次数,即 4。*/
     public int getSubStringCount(String str,String subStr){
         int count = 0;//记录出现的次数

         if(str.length() >= subStr.length()){
             //int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1
             int index = str.indexOf(subStr);
             while(index >= 0){
                 count++;
                 //int indexOf(String str, int fromIndex):
                 // 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始

                 /*当我们使用 `indexOf()` 方法来查找子字符串在原始字符串中的出现位置时,我们传递了两个参数:
1. 第一个参数是要查找的子字符串 `subStr`。
2. 第二个参数是开始查找的位置,我们希望从当前位置的下一个位置开始查找。
在这种情况下,`index + subStr.length()` 计算出的是下一个潜在的出现位置。因为我们已经找到了一个子字符串的位置,所以我们希望从当前位置的下一个位置继续搜索,而不是重叠查找之前找到的子字符串。
例如,如果我们在索引 0 找到了子字符串 `"ab"`,则下一个潜在的出现位置应该从索引 `0 + 2 = 2` 开始查找,以避免重复计数。
因此,`index = str.indexOf(subStr, index + subStr.length())` 这行代码的作用是更新 `index` 的值,使其指向下一个潜在的出现位置。*/
                 index = str.indexOf(subStr,index + subStr.length());
             }

         }
         return count;
     }
     }

题目4:获取两个字符串中最大相同子串。比如:
      str1 = "abcwerthelloyuiodef";
      str2 = "cvhellobnm"
      提示:将短的那个串进行长度依次递减的子串与较长的串比较。

    // 第4题
    // 如果只存在一个最大长度的相同子串
    public String getMaxSameSubString(String str1, String str2) {
        if (str1 != null && str2 != null) {
            String maxStr = (str1.length() > str2.length()) ? str1 : str2;
            String minStr = (str1.length() > str2.length()) ? str2 : str1;

            int len = minStr.length();

            for (int i = 0; i < len; i++) {// 0 1 2 3 4 此层循环决定要去几个字符

                for (int x = 0, y = len - i; y <= len; x++, y++) {

                    if (maxStr.contains(minStr.substring(x, y))) {

                        return minStr.substring(x, y);
                    }

                }

            }
        }
        return null;
    }

    // 如果存在多个长度相同的最大相同子串
    // 此时先返回String[],后面可以用集合中的ArrayList替换,较方便
    public String[] getMaxSameSubString1(String str1, String str2) {
        if (str1 != null && str2 != null) {
            StringBuffer sBuffer = new StringBuffer();
            String maxString = (str1.length() > str2.length()) ? str1 : str2;
            String minString = (str1.length() > str2.length()) ? str2 : str1;

            int len = minString.length();
            for (int i = 0; i < len; i++) {
                for (int x = 0, y = len - i; y <= len; x++, y++) {
                    String subString = minString.substring(x, y);
                    if (maxString.contains(subString)) {
                        sBuffer.append(subString + ",");
                    }
                }
                System.out.println(sBuffer);
                if (sBuffer.length() != 0) {
                    break;
                }
            }
            String[] split = sBuffer.toString().replaceAll(",$", "").split("\\,");
            return split;
        }

        return null;
    }
    // 如果存在多个长度相同的最大相同子串:使用ArrayList
//    public List<String> getMaxSameSubString1(String str1, String str2) {
//        if (str1 != null && str2 != null) {
//            List<String> list = new ArrayList<String>();
//            String maxString = (str1.length() > str2.length()) ? str1 : str2;
//            String minString = (str1.length() > str2.length()) ? str2 : str1;
//
//            int len = minString.length();
//            for (int i = 0; i < len; i++) {
//                for (int x = 0, y = len - i; y <= len; x++, y++) {
//                    String subString = minString.substring(x, y);
//                    if (maxString.contains(subString)) {
//                        list.add(subString);
//                    }
//                }
//                if (list.size() != 0) {
//                    break;
//                }
//            }
//            return list;
//        }
//
//        return null;
//    }

    @Test
    public void testGetMaxSameSubString() {
        String str1 = "abcwerthelloyuiodef";
        String str2 = "cvhellobnmiodef";
        String[] strs = getMaxSameSubString1(str1, str2);
        System.out.println(Arrays.toString(strs));
    }

题目5:对字符串中字符进行自然顺序排序。
      提示:
      1)字符串变成字符数组。
      2)对数组排序,选择,冒泡,Arrays.sort();
      3)将排序后的数组变成字符串。

    // 第5题
    @Test
    public void testSort() {
        String str = "abcwerthelloyuiodef";
        char[] arr = str.toCharArray();
        Arrays.sort(arr);

        String newStr = new String(arr);
        System.out.println(newStr);
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值