给定一个字符串,“xyz”是否出现在字符串的中间?

时间:2013-12-05 14:27:08

标签: java

  

给定一个字符串,“xyz”是否出现在字符串的中间?至   定义中间,我们会说左边的字符数和   “xyz”的权利必须至多相差一个。这个问题更难   比它看起来。

我的解决方案在没有第二行的情况下工作,除了一个条件:if str =“xyx” 是否有可能修改for循环以考虑到这一点......我正在努力理解它为什么不这样做。

我的解决方案确实有效我只是想更好地了解我正在做的事情。我知道我可以将它添加到第一个if语句中,但我想知道为什么没有它就无法工作。

public boolean xyzMiddle(String str) {
  for (int i=0;i<str.length()-3;i++) {
    if (str.substring(i,i+3).equals("xyz")) {
      String front =str.substring(0,i);
      String end = str.substring(i+3);
      int a =Math.abs(front.length() -end.length());
      if (a<=1) return true;
    }    
  }
  if (str.equals("xyz")) return true;
  return false;

8 个答案:

答案 0 :(得分:9)

我想我记得这个问题 - 我相信它是this question from Codingbat。优秀的网站,当我开始编程时,从该网站学到了很多东西。但是,绝对没有理由使用循环。

public boolean xyzMiddle(String str) {
  boolean result = false; 
  int i = str.length()/2 -1;

  if (str.length() >= 3 && (str.substring(i, i+3).equals("xyz") || (str.length()%2 == 0 && str.substring(i-1, i+2).equals("xyz"))  )) {
      result = true;
  }
  return result;
}

所以,让我们来看看这个以及它为何起作用。首先,str.length() >= 3,因为如果字符串不至少与“xyz”一样长,那么它就无法包含“xyz”。

这个问题有两个主要案例,我们需要考虑。弦可以具有均匀或不均匀的长度。在不平衡的情况下,很容易:

不平衡的案例

AAAxyzAAA // length = 9
012345678 // the indexes
    ^     // that's the middle, which can be calculated by length/2
          // (since this is an integer divison, we disregard whatever comes after the decimal point)

所以为了得到xyz - substring的开头,我们只需从这个数字中减去一个 - 这正是i正在做的事情:

AAAxyzAAA // length = 9
012345678 // the indexes
   i      // i = length/2-1 = 3

因此,如果str.substring(i, i+3)xyz,我们可以返回true!

偶数案例 现在,这可能有点棘手,因为字符串没有真正的“中间”。实际上,两个索引可以称为中间,因此我们有两个子案例:

AAAAAAAA // length = 8
01234567 // the indexes
   ^^    // Which one is the true middle character?

实际上,中间位于索引3和4之间。但是,我们执行整数除法,长度/ 2始终是两个可能的“中间”中最大的(最右边)。由于我们使用中间值计算i,因此适用于不均匀的情况 - str.substring(i, i+3)可以被视为字符串的中间部分。

AAAxyzAA 
01234567 
   ^^^     // str.substring(i, i+3)
   i

但假设我们的字符串为AAxyzAAA - 可以被认为是字符串的中间部分。所以我们需要将子字符串检查“移到左侧” - 所以我们从中减去1。

AAxyzAAA 
01234567 
  ^^^      // str.substring(i-1, i+2)
   i       // i is still at "the old" location

它是否均匀?

要检查字符串是偶数还是不均匀,我们使用 modulo 运算符%。想到它的作用的最简单方法是“在用这个数字划分后会留下什么?”。因此3 % 2将为1.在我们的情况下,我们希望确保该数字可以被2整除而没有剩余 - 因为这意味着它是偶数。因此,在进行“向左移动”检查之前,我们需要检查是否str.length() % 2 == 0。如果没有,我们可能冒险超出字符串的界限。如果字符串是3个字符长,我们向左移动一个...我们将检查从索引-1开始的子字符串,这没有多大意义。

把它们放在一起,然后你去!

答案 1 :(得分:2)

我会说一些简单的事情:

public void test() {
  test("Hello", "ll");
  test("Hello", "He");
  test("Hello", "el");
  test("Hello", "lo");
  test("Hello", "Hell");
  test("Hello", "ello");
  test("Hello", "Hello");
  test("Hell", "He");
  test("Hell", "el");
  test("Hell", "ll");
}

private void test(String s, String p) {
  System.out.println(p + (inMiddle(s, p) ? " in " : " not in ") + s);
}

// Is the pattern in the middle of the string.
public static boolean inMiddle(String s, String p) {
  int d = s.length() - p.length();
  return at(s, p, d / 2) || ((d & 1) == 1 && at(s, p, (d / 2) + 1));
}

private static boolean at(String s, String p, int i) {
  return i >= 0 && i < s.length() && s.substring(i).startsWith(p);
}

结果对我来说是正确的:

ll in Hello
He not in Hello
el in Hello
lo not in Hello
Hell in Hello
ello in Hello
Hello in Hello
He not in Hell
el in Hell
ll not in Hell

我已经确认,这恰好与p =“xyz”时的Tobias解决方案相符。

答案 2 :(得分:1)

最简单的我可以想出:

public boolean xyzMiddle(String str) {
    str = "  " + str + "  ";
    int even = (str.length()+1)%2;
    int mid = (str.length())/2;
    str = str.substring(mid-1-even, mid+2);
    return str.contains("xyz");
}

答案 3 :(得分:1)

@run
  image    : you_code_image
  name     : you_code_image
  cmd      : mocha test/
  daemon   : false

@run
  image    : you_code_image
  name     : you_code_image
  cmd      : node app.js
  daemon   : true

答案 4 :(得分:0)

public boolean xyzMiddle(String str) {

   int len = str.length();
   if(len < 3) {return false;}
   if(len==3 && str.equals("xyz")) {return true;}

    int index = middleIndex(str);

   String left = str.substring(0,index) ;
   String right= str.substring(index+3) ; 

  //Return based on the difference by at most 1
  return (Math.abs(left.length()-right.length()) <=1);
}

public int middleIndex(String str) {

   int middleLen  = (str.length())/2;
   int index= 0;

   //Find an index that could be in the middle of the string with 
   // "xyz" 
   for(int i=middleLen-2; i < middleLen; i++ ) {
      if(str.substring(i, i+3).equals("xyz") ) {
       index= i;
     }
   }
  return index;
}

答案 5 :(得分:0)

public boolean xyzMiddle(String str) {
  if (str.length() >= 3)
  {
    // if odd
    if (str.length() % 2 == 1)
    {
      //axyzb
      //01234
      //length = 5; 5 is odd.
      //length / 2 = 2;
      //2 minus 1 = 1
      //1 is where xyz starts

      //aaxyzbb
      //0123456
      //length = 7; 7 is odd.
      //length / 2 = 3;
      //3 minus 1 = 2
      //2 is where xyz starts.

      //....

      //This pattern works with all odd numbers.
      if (str.substring((str.length() / 2) - 1, ((str.length() / 2) - 1) + 3).equals("xyz"))
      {
        return true;
      }
      else
      {
        return false;
      }
    }
    //if even
    else
    {


      //for evens that occur with a larger amount before "xyz" than after

      //axyz
      //0123
      //length = 4; 4 is even;
      //4 - 1 = 3;
      //3 / 2 = 1
      //1 is where xyz starts.

      //aaxyzb
      //012345
      //length = 6; 6 is even;
      //6 - 1 = 5;
      //5 / 2 = 2
      //2 is where xyz starts.

      //...

      //This pattern works for all even numbers where there is a larger amount of characters before the xyz.

      if (str.substring((str.length() - 1) / 2, ((str.length() - 1) / 2) + 3).equals("xyz"))
      {
        return true;
      }

      //For the cases where there are more characters after "xyz" than before.

      //xyzb
      //0123
      //length = 4; 4 is even;
      //4 - 1 = 3;
      //3 / 2 = 1
      //1 - 1 = 0;
      //xyz starts at 0;

      //axyzbb
      //012345
      //length = 6; 6 is even;
      //6 - 1 = 5;
      //5 / 2 = 3;
      //2 - 1 = 1;
      //xyz starts at 1;

      //...

      //The pattern continues onwards for all cases where there are more characters after xyz than before.

      else if (str.substring((((str.length() - 1) / 2) - 1), (((str.length() - 1) / 2) -1) + 3).equals("xyz"))
      {
        return true;
      }

      //If there is no instance of xyz in these areas.
      else
      {
        return false;
      }
    }
  }
  // If our string is less than 3 in length.
  else
  {
    return false;
  }
}

答案 6 :(得分:0)

public boolean xyzMiddle(String str) {

  return str.length()>2 && str.length()%2==1 && str.substring((str.length()-1)/2-1,(str.length()/2+1)+1).contains("xyz") || str.length()>2 && str.length()%2==0 && (str.substring(str.length()/2-2,str.length()/2+1).contains("xyz") || str.substring(str.length()/2-1,str.length()/2+2).contains("xyz"));

}

答案 7 :(得分:0)

    public boolean xyzMiddle(String str) {
  int index = str.indexOf("x");
  if(index < 0)
    return false;
  while(index >=0 && (index+3 <= str.length()) ){
    if(str.substring(index,index+3).equals("xyz") && Math.abs(str.substring(0,index).length() - str.substring(index+3).length()) <=1)
    return true;
    index = str.indexOf("x",index+1);
  }
  return false;
}