我正在编写一个程序来在Java中查找字符串中的子字符串,而不使用任何Java库。
我写了一个函数subString(String str1, String str2)
,如下所示。
它适用于以下输入:
str1="rahul"
str2="My name is rahul"
str1="rahul"
str2="rahul sah"
str3="rahul"
str2="sah rahul"
当我输入以下内容时会出现问题:
str1="rahul"
str2="rararahul"
str1="rahul"
str2="My name is sunil"
它进入无限循环。任何人都可以查看我的代码片段并帮助我。
public static boolean subString(String str1, String str2) {
boolean found = false;
int len1 = str1.length();
int len2 = str2.length();
int status = 0;
char[] arr1 = new char[len1];
char[] arr2 = new char[len2];
for (int ii = 0; ii < len1; ii++) {
arr1[ii] = str1.charAt(ii);
}
for (int jj = 0; jj < len2; jj++) {
arr2[jj] = str2.charAt(jj);
}
for (int ii = 0; ii < len1; ii++) {
for (int jj = 0; jj < len2; jj++) {
if (arr1[ii] == arr2[jj]) {
if (ii < len1 - 1) {
System.out.println("Found1::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = true;
ii++;
} else if (arr1[ii] == arr2[jj] && ii == len1 - 1) {
System.out.println("Found2::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = true;
break;
}
} else if (found == false && arr1[ii] != arr2[jj]) {
System.out.println("Found3::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = false;
} else if (found == true && arr1[ii] != arr2[jj]) {
System.out.println("Found4::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = false;
ii = 0;
}
}
}
return found;
}
}
答案 0 :(得分:11)
其他人建议使用String.contains()
- 这是java.lang代码,而不是Java库。但是,你显然想要探索如何自己做到这一点。一种方法是查看String.contains()
的OpenJDK 7源代码,其中使用String.indexOf()
。你可以看到他们在那里使用的(相当基本的)算法。
有趣的是,当我将代码粘贴到我的开发环境中时,您的代码适用于“rahul”和“rararahul”。但是,存在非匹配的无限循环。对于包含str2
的任何字符的任何str1
,都会发生这种情况。这是因为一旦在str2中找到str1中任何字符的匹配项,就会重置变量以重新开始。如果你查看它通过每个字符串的序列,你的输出实际上足以调试它。
如果您想要追求自己的方法并从中学习,那么请考虑使用自己的方法停止并在纸上进行一些设计。您正在寻找str1
str2
中出现的str2
。所以你可能想换掉你的循环。那么你可以更有效率。您可以在外部循环中逐个字符地查看字符串(str1
)。如果较短字符串(str2
)的第一个字符与您在 boolean retFound = false;
for (int jj = 0; jj < len2; jj++) {
if (arr1[0] == arr2[jj]) {
boolean tempFound = true;
int foundIndex = jj;
for (int ii = 0; ii < len1; ii++) {
if (arr1[ii] != arr2[jj+ii]) {
tempFound = false;
break;
}
}
if (tempFound) {
System.out.println("Found substring " + str1 + " in " + str2 + " at index " + foundIndex);
System.out.println("Carrying on to look for further matches...");
tempFound = false;
retFound = true;
}
}
}
return retFound;
中处理的字符匹配,那么您只需要进入内部循环。
e.g。代码的循环位
{{1}}
注意,这不会很快,但它应该有效。我已经测试了你提供的所有字符串样本。你也得到奖金 - 它会找到多个匹配。如果你不想要那个(只是想要真假),当它说“继续寻找......”时会爆发。
正如其他人所说,如果你想继续使用原始代码,当然不要试图在内循环中改变循环变量(即ii)。这是不好的做法,难以阅读并容易出现大量错误。
答案 1 :(得分:3)
} else if (found == true && arr1[ii] != arr2[jj]) {
你将ii设置为零。这就是为什么我永远不会更大或等于len1
答案 2 :(得分:2)
你需要把外部循环用于jj和内部循环用于ii:
int ii=0;
for (int jj = 0; jj < len2; jj++) {
if (arr1[ii] == arr2[jj]) {
if (ii < len1 - 1) {
System.out.println("Found1::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = true;
ii++;
} else if (arr1[ii] == arr2[jj] && ii == len1 - 1) {
System.out.println("Found2::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = true;
break;
}
} else if (found == false && arr1[ii] != arr2[jj]) {
System.out.println("Found3::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = false;
} else if (found == true && arr1[ii] != arr2[jj]) {
System.out.println("Found4::" + "arr1::" + arr1[ii]
+ "and arr2::" + arr2[jj]);
found = false;
ii = 0;
}
}
编辑: 您还要为较大字符串中的每个字符初始化内部for循环。你根本不需要两个循环。我已经适当地改变了它。这应该有用。
答案 3 :(得分:2)
您可以使用一个循环和匹配条件,在完整字符串中找到第一个字符时将开始搜索。然后,搜索将继续从列表中逐一进行匹配。好吧,我在这里举一个例子来解释。
public static boolean subString2(String smallString, String fullString)
{
int k = 0;
for (int i = 0; i < fullString.length(); i++)
{
System.out.println("fullStringCharArray[i]: " + fullString.charAt(i));
if (smallString.charAt(k) == fullString.charAt(i))
{
System.out.println("Found: " + smallString.charAt(k));
k++;
if (k == smallString.length())
return true;
}
else
{
k = 0;
}
}
return false;
}
在这里,发生了什么,我们将在fullString中搜索。如果你的smallString&#39; rahul&#39;是&#39; r&#39;然后直到找到它,字符串的另一部分(&#39; ahul&#39;)将不匹配。所以,当&#39; r&#39;匹配然后它会尝试搜索&#39; a&#39;然后&#39; h&#39;和更多。因此,如果搜索的计数true(k)等于smallString长度,则子串存在。我希望,我能够正确解释。抱歉我的英文。
答案 4 :(得分:2)
使用此代码。 这将对您有所帮助,并且非常简短明了
public static boolean subString(String str1, String str2) {
int str1Len = str2 == null ? 0 : str1.length();
int str2Len = str2 == null ? 0 : str2.length();
for (int i = 0; i < str2Len; i++) {
if (str1.charAt(0) == str2.charAt(i)) {
int count = 0;
for (int j = 0; j < str1Len; j++) {
if (str1.charAt(j) == str2.charAt(i)) {
i++;
count++;
}
}
if (count == str1Len) {
return true;
}
}
}
return false;
}