在Java中查找字符串中的子字符串

时间:2015-01-28 06:42:38

标签: java

我正在编写一个程序来在Java中查找字符串中的子字符串,而不使用任何Java库。

我写了一个函数subString(String str1, String str2),如下所示。

它适用于以下输入:

  1. str1="rahul" str2="My name is rahul"
  2. str1="rahul" str2="rahul sah"
  3. str3="rahul" str2="sah rahul"
  4. 当我输入以下内容时会出现问题:

    1. str1="rahul" str2="rararahul"
    2. str1="rahul" str2="My name is sunil"
    3. 它进入无限循环。任何人都可以查看我的代码片段并帮助我。

          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;
          }
      }
      

5 个答案:

答案 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;
    }