【问题标题】:JAVA: comparing a String with a SubStringJAVA:将字符串与子字符串进行比较
【发布时间】:2017-02-20 15:31:22
【问题描述】:

这就是我想要完成的任务。我正在尝试编写一个从 2 个给定字符串执行以下操作的代码:targetsource

//  Determines whether the string TARGET occurs as a substring of string SOURCE where "gaps" are allowed between characters of target.`
//  That is, the characters in TARGET occur in SOURCE in their given order but do not have to be adjacent.`
//  (Pictured another way, this method returns true if TARGET could be obtained from SOURCE by removing some of the letters of SOURCE.)`
//  This method is case sensitive. For example,`
//  containsWithGaps("hamburgers", "mug") returns true`
//  containsWithGaps("hamburgers", "burrs") returns true`
//  containsWithGaps("hamburgers", "hamburgers") returns true`
//  containsWithGaps("hamburgers", "gum") returns false`
//  containsWithGaps("hamburgers", "hamm") returns false`
//  containsWithGaps("hamburgers", "") returns true`
//  Parameters:`
//  SOURCE - the given string in which to find the target characters`
//  TARGET - the characters to be found`

//  Returns:`
//  true if the characters in TARGET can be found as a subsequence in SOURCE, false otherwise`

这是我编写的代码。对于我认为不应该是一项艰巨的任务来说,这似乎过于复杂,但无论如何,我仍然会不断收到错误,如果给定一个源字符串hamburgers 和一个目标字符串burr,它就不起作用:

    public static boolean substringWithGaps(String source, String target) {

    boolean substring = false;
    int[] target_index;
    target_index = new int [target.length()];

    if (target.length() > source.length()) {
        substring = false;
    }
    else {
        for (int i = 0; i < target.length(); i++) {
            if (source.contains("" + target.charAt(i))) {           
                target_index[i] = target.indexOf(i);
                i++;
            }
            else {
                target_index[i] = target.indexOf(i);
                i++;
            }
        }
        for (int i = 0; i < target_index.length; i++) {
            if (target_index[i] == -1) {
                substring = false;
                break;
            }
            else if (target_index[i] >= target_index[i+1]) {
                substring = false;
                break;
            }
            else {
                substring = true;
            }
        if (target_index.length != target.length()) {
            substring = false;
            }
        }   
    }
    return substring;
}

有什么想法吗?

【问题讨论】:

  • 伪代码:String foo = source.replace(/\s+/, "", g); if (-1 != foo.indexOf(target) { hooray() }
  • 只是这个source.contains(target),在Java中可以正常工作。
  • @Jorge Campos 不,这将不满足要求 - 只有当目标完全在源中时它才会返回 true。要求是可以有中间字母,

标签: java string loops substring


【解决方案1】:

应该很简单:

public static boolean substringWithGaps(String source, String target) {
    int targetIndex = 0;
    for (int i = 0; i < source.length(); i++) {
        if (source.charAt(i) == target.charAt(targetIndex)) {
            targetIndex = targetIndex + 1;
            if (targetIndex == target.length()) {
                return true;
            }
        }
    }
    return false;
}

我们保留了在target 中需要找到的下一个字母的索引。然后我们遍历source 寻找那个字母,当我们找到它时,我们将target 中的索引向前移动一个。如果target 的索引等于target 的长度,这意味着我们找到了所有需要的字符。如果我们遍历所有源代码但没有找到所有 target,我们返回 false。

【讨论】:

  • StringIndexOutOfBoundsException 当 target=""
  • 是的,但这就是我似乎不明白的。取 source = "hamburger"target = "burr" 在代码的第 4 行,` if (source.charAt(i) == target.charAt(targetIndex)) {` targetIndex 将保持为 0,直到循环遍历 b hamburger,其 index# 为 3,但 targetIndex 仍应为 0,因此它们永远不会相等。
  • @saka1029 我在顶部添加了if (target == ""){return true; },之后它似乎工作正常
  • 天哪,我是个白痴。好的,我现在明白了,哈哈谢谢!
  • @Muldawg2020 你问为什么targetIndex 在这段代码中保持为0。 targetIndex 指的是字符串target 的索引。所以targetIndex的值在搜索“b”时应该为0,而source的索引是允许向前移动的。如果您认为它不起作用,请下载代码并自行运行。我已经对其进行了测试并得到了正确的结果。
【解决方案2】:

以下应该这样做。

public static boolean containsWithGaps(String a, String b){
    if(b.length() > a.length())
    {
      return false;
    }
    char[] targetChars = new char[b.length()];
    b.getChars(0,b.length(),targetChars, 0);
    int pos = 0;
    for(char myChar : targetChars)
    {
      pos = a.indexOf(myChar, pos);
      if(pos == -1)
      {
        return false;
      }
    }
    return true;
  }

【讨论】:

    【解决方案3】:

    轻微优化,一旦字符无法匹配就返回(如果目标长度为零,则不会崩溃)

    public static boolean substringWithGaps(String source, String target) {
        for (int i = 0, last = -1; i < target.length(); i++) {
            if (-1 == (last = source.indexOf(target.charAt(i), last + 1)))
                return false;
        }
        return true;
    }
    

    【讨论】: