我读了很好的练习关于检查字符串是另一个的子字符串.
练习的内容是:
编写一个从命令行获取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)
但是有两个问题:
您对解决方案的看法如何?:)
试试这个:(添加注释以进行解释)
// 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)