Java:在没有内置方法 contains() 的情况下实现 String 方法 contains()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16122481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 21:58:14  来源:igfitidea点击:

Java: Implement String method contains() without built-in method contains()

javastringcontains

提问by danksim

I'm trying to implement String method contains()without using the built-in contains()method.

我试图在String method contains()不使用内置contains()方法的情况下实现。

Here is what I have so far:

这是我到目前为止所拥有的:

public static boolean containsCS(String str, CharSequence cs) {

    char[] chs = str.toCharArray();
    int i=0,j=chs.length-1,k=0,l=cs.length();

    //String      str = "Hello Java";
    //                   0123456789
    //CharSequence cs = "llo";

    while(i<j) {
        if(str.charAt(i)!=cs.charAt(k)) {
            i++;
        }
        if(str.charAt(i)==cs.charAt(k)) {

        }
    }

    return false;
}

I was just practicing my algorithm skills and got stuck.

我只是在练习我的算法技能并被卡住了。

Any advice?

有什么建议吗?

回答by Kamal Garg

Using Only 1 Loop

仅使用 1 个循环

I did some addition to Poran answer and It works totally fine:

我对 Poran 的回答做了一些补充,它完全正常:

 public static boolean contains(String main, String Substring) {
    boolean flag=false;
    if(main==null && main.trim().equals("")) {
        return flag;
    }
    if(Substring==null) {
        return flag;
    }

    char fullstring[]=main.toCharArray();
    char sub[]=Substring.toCharArray();
    int counter=0;
    if(sub.length==0) {
        flag=true;
        return flag;
    }

    for(int i=0;i<fullstring.length;i++) {

        if(fullstring[i]==sub[counter]) {
            counter++;
        } else {
            counter=0;
        }

        if(counter==sub.length) {
            flag=true;
            return flag;
        }

    }
    return flag;

}

回答by Arif Nadeem

This should work fine..I am printing execution to help understand the process.

这应该可以正常工作..我正在打印执行以帮助理解该过程。

public static boolean isSubstring(String original, String str){
    int counter = 0, oLength = original.length(), sLength = str.length();
    char[] orgArray = original.toCharArray(), sArray = str.toCharArray();
    for(int i = 0 ; i < oLength; i++){
        System.out.println("counter at start of loop " + counter);
        System.out.println(String.format("comparing %s with %s", orgArray[i], sArray[counter]));
        if(orgArray[i] == sArray[counter]){
            counter++;
            System.out.println("incrementing counter " + counter);
        }else{
            //Special case where the character preceding the i'th character is duplicate
            if(counter > 0){
                i -= counter;
            }
            counter = 0;
            System.out.println("resetting counter " + counter);
        }
        if(counter == sLength){
            return true;
        }
    }
    return false;
}

回答by 0x6C38

As JB Nizet suggested, hereis the actual code for contains():

正如 JB Nizet 所建议的,这里是实际的代码contains()

2123  public boolean contains(CharSequence s) {
2124      return indexOf(s.toString()) > -1;
2125  }

And here is the code for indexOf():

这是代码indexOf()

1732     public int indexOf(String str) {
1733         return indexOf(str, 0);
1734     }

Which leads to:

这导致:

 1752   public int indexOf(String str, int fromIndex) {
 1753       return indexOf(value, offset, count,
 1754                      str.value, str.offset, str.count, fromIndex);
 1755   }

Which finally leads to:

这最终导致:

 1770   static int indexOf(char[] source, int sourceOffset, int sourceCount,
 1771                      char[] target, int targetOffset, int targetCount,
 1772                      int fromIndex) {
 1773       if (fromIndex >= sourceCount) {
 1774           return (targetCount == 0 ? sourceCount : -1);
 1775       }
 1776       if (fromIndex < 0) {
 1777           fromIndex = 0;
 1778       }
 1779       if (targetCount == 0) {
 1780           return fromIndex;
 1781       }
 1782   
 1783       char first  = target[targetOffset];
 1784       int max = sourceOffset + (sourceCount - targetCount);
 1785   
 1786       for (int i = sourceOffset + fromIndex; i <= max; i++) {
 1787           /* Look for first character. */
 1788           if (source[i] != first) {
 1789               while (++i <= max && source[i] != first);
 1790           }
 1791   
 1792           /* Found first character, now look at the rest of v2 */
 1793           if (i <= max) {
 1794               int j = i + 1;
 1795               int end = j + targetCount - 1;
 1796               for (int k = targetOffset + 1; j < end && source[j] ==
 1797                        target[k]; j++, k++);
 1798   
 1799               if (j == end) {
 1800                   /* Found whole string. */
 1801                   return i - sourceOffset;
 1802               }
 1803           }
 1804       }
 1805       return -1;
 1806   }

回答by Stephen C

Hints:

提示:

  • Use a nested loop.
  • Extracting the chars to an array is probably a bad idea. But if you are going to do it, you ought to use it!
  • Ignore the suggestion to use fast string search algorithms. They are only fast for large scale searches. (If you look at the code for String.indexOf, it just does a simple search ...)
  • 使用嵌套循环。
  • 将字符提取到数组可能是一个坏主意。但如果你要这样做,你应该使用它!
  • 忽略使用快速字符串搜索算法的建议。它们仅适用于大规模搜索。(如果您查看 的代码String.indexOf,它只会进行简单的搜索...)

回答by Mo Beigi

I came up with this:

我想出了这个:

public static boolean isSubString(String s1, String s2) {
    if (s1.length() > s2.length())
        return false;

    int count = 0;

    //Loop until count matches needle length (indicating match) or until we exhaust haystack
    for (int j = 0; j < s2.length() && count < s1.length(); ++j) {
        if (s1.charAt(count) == s2.charAt(j)) {
            ++count;
        }
        else {
            //Redo iteration to handle adjacent duplicate char case
            if (count > 0)
                --j;

            //Reset counter
            count = 0;
        }
    }

    return (count == s1.length());
}

回答by Peter V

I have recently stumbled upon this problem, and though I would share an alternative solution. I generate all the sub strings with length of the string we looking for, then push them into a hash set and check if that contains it.

我最近偶然发现了这个问题,尽管我会分享一个替代解决方案。我生成所有具有我们要查找的字符串长度的子字符串,然后将它们推入一个哈希集并检查其中是否包含它。

 static boolean contains(String a, String b) {
    if(a.equalsIgnoreCase(b)) {
        return true;
    }
    Set<String> allSubStrings = new HashSet<>();
    int length = b.length();
    for(int i=0; i<a.length(); ++i) {
        if(i+length <= a.length()) {
            String sub = a.substring(i, i + length);
            allSubStrings.add(sub);
        }
    }
    return allSubStrings.contains(b);
}

回答by Shishir


    public static boolean contains(String large, String small) {

        char[] largeArr = large.toCharArray();
        char[] smallArr = small.toCharArray();

        if (smallArr.length > largeArr.length)
           return false;

        for(int i = 0 ; i <= largeArr.length - smallArr.length ; i++) {
            boolean result = true ;
            for(int j = 0 ; j < smallArr.length ; j++) {
                 if(largeArr[i+j] != smallArr[j]) {
                     result = false;
                     break;
                 }
                 result = result && (largeArr[i+j]==smallArr[j]); 
            }
            if(result==true) {return true;}
        }

        return false;
    }


回答by Anil M

Certainly not the most efficient solution due to the nested loop, but it seems to work pretty well.

由于嵌套循环,当然不是最有效的解决方案,但它似乎工作得很好。

private static boolean contains(String s1, String s2) {
    if (s1.equals(s2)) return true;
    if (s2.length() > s1.length()) return false;

    boolean found = false;
    for (int i = 0; i < s1.length() - s2.length(); i++) {
        found = true;
        for (int k = 0; k < s2.length(); k++)
            if (i + k < s1.length() && s1.charAt(i + k) != s2.charAt(k)) {
                found = false;
                break;
            }
        if (found) return true;
    }
    return false;
}

回答by Poran

It can be done using a single loop.

它可以使用单个循环来完成。

public boolean StringContains(String full, String part) {
    long st = System.currentTimeMillis();
    if(full == null || full.trim().equals("")){
        return false;
    }
    if(part == null ){
        return false;
    }
    char[] fullChars = full.toCharArray();
    char[] partChars = part.toCharArray();
    int fs = fullChars.length;
    int ps = partChars.length;
    int psi = 0;
    if(ps == 0) return true;
    for(int i=0; i< fs-1; i++){
        if(fullChars[i] == partChars[psi]){
            psi++; //Once you encounter the first match, start increasing the counter
        }
        if(psi == ps) return true;
    }
    long et = System.currentTimeMillis()- st;
    System.out.println("StringContains time taken =" + et);
    return false;
}