检查字符串是否是另一个字符串的子字符串

ACz*_*ACz 6 java substring

我读了很好的练习关于检查字符串是另一个的子字符串.

练习的内容是:

编写一个从命令行获取2个字符串参数的程序.程序必须验证第二个字符串是否是第一个字符串的子字符串(您不能使用substr,substring或任何其他标准函数,包括正则表达式库).

第二个子字符串中每次出现*表示它可以匹配第一个字符串的零个或多个字符.

考虑以下示例:输入字符串1:abcd输入字符串2:a*c程序应评估字符串2是字符串1的子字符串.

此外,如果星号(*)前面有反斜杠(\),则可将其视为常规字符.反斜杠(\)在除星号(*)之前的所有情况下都被视为常规字符.

我写了一个简单的应用程序,它首先检查第二个字符串是否不长于第一个(但有一个问题,当测试("ab","a*b")这是正确的测试,但方法失败):

public static boolean checkCharactersCount(String firstString, String secondString) {
    return (firstString.length() > 0 && secondString.length() > 0) &&
            (firstString.length() > secondString.length());
Run Code Online (Sandbox Code Playgroud)

...而下一个验证是一个子字符串:

public static boolean checkSubstring(String firstString, String secondString) {
    int correctCharCounter = 0;
    int lastCorrectCharAtIndex = -1;

    for (int i = 0; i < secondString.length(); i++) {
        for (int j = 0; j < firstString.length(); j++) {
            if (j > lastCorrectCharAtIndex) {

                if ((secondString.charAt(i) == firstString.charAt(j)) || secondString.charAt(i) == '*') {
                    correctCharCounter++;
                    lastCorrectCharAtIndex = j;
                }

                if (correctCharCounter >= secondString.length())
                    return true;
            }
        }
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

但是有两个问题:

  1. 我上面的代码不支持字符连续性(例如test:checkSubstring("abacd","bcd")返回true,但是它错了! - 应该返回false)
  2. 知道如何验证特殊符号为"\*"吗?要测试的样本(checkSubstring("a bc","\ b"))

您对解决方案的看法如何?:)

Abh*_*Oza 3

试试这个:(添加注释以进行解释)

// only for non empty Strings
public boolean isSubString(String string1,String string2)
{
    // step 1: split by *, but not by \*
    List<String>list1 = new ArrayList<String>();
    char[]cs = string2.toCharArray();
    int lastIndex = 0 ;
    char lastChar = 0 ;
    int i = 0 ;
    for(; i < cs.length ; ++i)
    {
        if(cs[i]=='*' && lastChar!='\\')
        {
            list1.add(new String(cs,lastIndex,i-lastIndex).replace("\\*", "*"));
            //earlier buggy line:
            //list1.add(new String(cs,lastIndex,i-lastIndex));
            lastIndex = i + 1 ;
        }
        lastChar = cs[i];
    }
    if(lastIndex < i )
    {
        list1.add(new String(cs,lastIndex,i-lastIndex).replace("\\*", "*"));
    }
    // step 2: check indices of each string in the list
    // Note: all indices should be in proper order.
    lastIndex = 0;
    for(String str : list1)
    {
        int newIndex = string1.indexOf(str,lastIndex);
        if(newIndex < 0)
        {
            return false;
        }
        lastIndex = newIndex+str.length();
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

如果不允许使用String.indexOf(),则编写一个函数public int indexOf(String string1,String string2, int index2)并替换此语句

int newIndex = string1.indexOf(str,lastInxdex);
Run Code Online (Sandbox Code Playgroud)

有了这个声明:

int newIndex = indexOf(string1, str,lastInxdex);
Run Code Online (Sandbox Code Playgroud)

=================================================== ======

附录A:我测试的代码:

package jdk.conf;

import java.util.ArrayList;
import java.util.List;

public class Test01 {
    public static void main(String[] args)
    {
        Test01 test01 = new Test01();
        System.out.println(test01.isSubString("abcd", "a*c"));
        System.out.println(test01.isSubString("abcd", "bcd"));
        System.out.println(test01.isSubString("abcd", "*b"));
        System.out.println(test01.isSubString("abcd", "ac"));
        System.out.println(test01.isSubString("abcd", "bd"));
        System.out.println(test01.isSubString("abcd", "b*d"));
        System.out.println(test01.isSubString("abcd", "b\\*d"));
        System.out.println(test01.isSubString("abcd", "\\*d"));
        System.out.println(test01.isSubString("abcd", "b\\*"));

        System.out.println(test01.isSubString("a*cd", "\\*b"));
        System.out.println(test01.isSubString("", "b\\*"));
        System.out.println(test01.isSubString("abcd", ""));

        System.out.println(test01.isSubString("a*bd", "\\*b"));
    }
    // only for non empty Strings
    public boolean isSubString(String string1,String string2)
    {
        // step 1: split by *, but not by \*
        List<String>list1 = new ArrayList<String>();
        char[]cs = string2.toCharArray();
        int lastIndex = 0 ;
        char lastChar = 0 ;
        int i = 0 ;
        for(; i < cs.length ; ++i)
        {
            if(cs[i]=='*' && lastChar!='\\')
            {
                list1.add(new String(cs,lastIndex,i-lastIndex).replace("\\*", "*"));
                lastIndex = i + 1 ;
            }
            lastChar = cs[i];
        }
        if(lastIndex < i )
        {
            list1.add(new String(cs,lastIndex,i-lastIndex).replace("\\*", "*"));
        }
        // step 2: check indices of each string in the list
        // Note: all indices should be in proper order.
        lastIndex = 0;
        for(String str : list1)
        {
            int newIndex = string1.indexOf(str,lastIndex);
            if(newIndex < 0)
            {
                return false;
            }
            lastIndex = newIndex+str.length();
        }
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

true
true
true
false
false
true
false
false
false
false
false
true
true
Run Code Online (Sandbox Code Playgroud)