【问题标题】:Given a string, does "xyz" appear in the middle of the string?给定一个字符串,“xyz”是否出现在字符串的中间?
【发布时间】:2013-12-05 14:27:07
【问题描述】:

给定一个字符串,“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;

【问题讨论】:

  • 问题是什么?代码应该做什么?
  • 好的,现在你已经合并了一个问题。现在我的问题是,你为什么要使用循环?您已经知道在字符串中查找的位置。
  • 问题来自的编码蝙蝠部分是关于使用循环......所以这就是我自动这样做的原因......
  • 我认为他们希望您使用循环来检查字符而不是子字符串,而不是查找子字符串的位置。

标签: java


【解决方案1】:
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;
}

【讨论】:

    【解决方案2】:
    public boolean xyzMiddle(String str) {
      int len = str.length();
      if (len < 3){ return false; }
      int even = (len+1)%2;
      int mid = len/2;
      return str.substring(mid-1-even, mid+2).contains("xyz");
    }
    

    【讨论】:

      【解决方案3】:

      我想我记得这个问题 - 我相信是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() &gt;= 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
      

      是不是这样?

      要检查字符串是偶数还是不偶数,我们使用 运算符%。想到它的作用的最简单方法是“我除以这个数字后会剩下什么?”。所以3 % 2 将是 1。在我们的例子中,我们要确保这个数字可以被 2 整除,并且没有任何剩余——因为这意味着它是一个偶数。因此,在我们进行“向左移动”检查之前,我们需要检查是否str.length() % 2 == 0。如果没有,我们可能会冒着超出字符串范围的风险。如果字符串有 3 个字符长,并且我们向左移动了一个字符......我们将检查从索引 -1 开始的子字符串,这没有多大意义。

      将所有内容放在一起,然后就可以了!

      【讨论】:

      • str.length()%2==0 部分 - 这怎么告诉你它在中间?
      • @JerryMurphy 它给出了字符串是否是偶数长度。虽然他真的应该用括号括住最后一个条件。
      • 嗯,有道理,谢谢
      • 我已经扩展并解释了解决方案 - 它非常彻底,很抱歉文字墙。
      • 完美地解释了一切!这里的答案速度和质量令人难以置信..感谢您的帮助 Tobias
      【解决方案4】:

      我会说一些简单的话:

      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 的解决方案。

      【讨论】:

      • @JerryMurphy 是关于算法的,而不是方法的名称。这也是问题的一般解决方案。
      • 感谢 OldCurmudgeon 和李宗政
      【解决方案5】:

      我能想到的最简单的:

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

      【讨论】:

        【解决方案6】:
        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;
          }
        }
        

        【讨论】:

        • 没有循环,只有数学。
        • 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        【解决方案7】:
        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"));
        
        }
        

        【讨论】:

          【解决方案8】:
              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;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-12-14
            • 2021-04-30
            • 1970-01-01
            • 2011-06-15
            • 2013-05-07
            • 2022-12-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多