【问题标题】:Efficient solution to codingBat riddle starOut in JavaJava中编码蝙蝠谜语starOut的有效解决方案
【发布时间】:2021-04-22 14:50:46
【问题描述】:

我说的问题是this

问题说明:

返回给定字符串的一个版本,对于字符串中的每个星号 (),星号和紧邻其左右的字符都消失了。所以“abcd”产生“ad”,“ab**cd”也产生“ad”。

starOut("ab*cd") → "广告"

starOut("ab**cd") → "广告"

starOut("sm*eilly") → "傻"

我得到的解决方案有点混乱,我使用了大约 6 个 if 语句和一个特定情况的处理,寻找具有较少 if 的更清洁的解决方案。

请不要使用超过 1 个循环和集合或正则表达式。

以下是我的解决方案:

public String starOut(String str) {
  String result="";
  boolean currentFlag=false;
  
  if(str.length()==0)
  return result;
  
  for(int i=0;i+1<str.length();i++)
  {
    if(str.charAt(i)=='*')
    {
       i+=1;
       currentFlag=true;
       continue;
     }
     if(str.charAt(i+1)=='*')
     {
        i+=2;
        continue;
     }
     if((i>0)&&str.charAt(i-1)=='*')
     {
        continue;
     }
     result+=str.substring(i,i+1);
     currentFlag=false;

   }
   
  if(!(currentFlag)&&(str.length()==3)&&(str.charAt(1)=='*'))
      return ""; 
      
   if((str.charAt(str.length()-1)!='*')&!(currentFlag))
     return result+=str.charAt(str.length()-1);
    else
      return result;
}

【问题讨论】:

  • 你应该看看regex
  • 谢谢 我知道正则表达式,但不希望使用正则表达式来解决它。
  • 另外,如果你有工作代码,我建议你把它交给CodeReview SE。你可以自己标记这个,让模组知道你是否想要这个迁移。
  • 无意冒犯 Anirudh,但从您的代码来看,正则表达式似乎有点过头了。不要试图在你的循环中向前看;这就是循环的用途。从第一个字符开始,检查它,处理特殊情况,进行更改,继续。
  • 请发布解决方案,而不是抱怨正则表达式。问题中没有提到涉及正则表达式。谢谢!

标签: java algorithm


【解决方案1】:

伪代码:

遍历字符串中的所有字符。如果您降落在星号上,请不要记录它。向左看,如果你看到一个星号,不要记录它。如果看到星号,请向右看,不要记录下来。如果以上都没有发生,记录一下。

Java 代码:

public static String starOut(String s) {
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '*') continue;
        if (i > 0 && s.charAt(i - 1) == '*') continue;
        if (i < s.length() - 1 && s.charAt(i + 1) == '*') continue;
            
        sb.append(s.charAt(i));
    }

    return sb.toString();
}

注意:我看到很多答案都是在循环中连接String 对象,而不是使用StringBuilder。不要那样做。我是very inefficient

【讨论】:

  • 非常简洁的先生,但您也可以简单地使用 String 来代替 stringbuilder。
  • @Anirudh StringBuilder 在循环内的那种类型的 - 嗯 - 字符串构建 中有它的用法。
  • @Anirudh 为什么 StringBuilder 在这种情况下需要是线程安全的?多个线程同时访问此 StringBuilder 的可能性为零。否则我会使用 StringBuffer。
  • StringBuilder 是在字符串中进行有效连接的默认方式。应该包括它,但考虑到无 regex/collection 1 循环约束,我试图尽可能保持基本。
  • @DaveS charAt() 导致直接访问字符串的底层字符数组。即便如此,将它分配给一个变量会消除一些函数调用,并且可能会使事情稍微快一些。对字符串的 length() 方法的调用也是如此。
【解决方案2】:

这是我写的解决方案。它使用 1 个循环。

public String starOut(String str)
{
    String ret = "";
    for (int i = 0; i < str.length(); i++)
    {        
        if (!( '*' == str.charAt(i) 
        || i + 1 < str.length() && '*' == str.charAt(i+1)
        || i > 0 && '*' == str.charAt(i-1) ))
        {
            ret = ret + str.charAt(i);
        }        
    }
    return ret;
}

【讨论】:

  • 太棒了!!做工很好,看起来也很优雅。
【解决方案3】:

我认为使用正则表达式和模式匹配来解决这个问题会很简单

public String starOut(String str) {
  String pattern = "([a-zA-Z0-9]{0,1})\\*+([a-zA-Z0-9]{0,1})";
  str = str.replaceAll(pattern, "");
  return str;
}

【讨论】:

    【解决方案4】:

    这就是我的想法

    public String starOut(String str)
    {
      boolean lastIsStar = false;
      String result = "";
      for(int i = 0; i < str.length(); i++)
      {
         char c = str.charAt(i);
         if(lastIsStar)
         {
            if(c != '*')
            {
                lastIsStar = false;
            }
         }
         else if(c == '*')
         {
            lastIsStar = true;
            if(i-1 > -1)
            {
               result = result.substring(0, result.length()-1);
            }
         }
         else
         {
            result += c;
            lastIsStar = false;
         }
      }
      return result;
    }
    

    【讨论】:

    • 那肯定是更好的。谢谢
    【解决方案5】:

    一个小时后写了这篇……还是不喜欢

    String result = "";
    boolean toDelete = false;
    boolean deleted = true;
    
    for(int i=0; i < str.length(); i++){
       if (str.charAt(i) != '*'){
           if(toDelete == false) result += str.charAt(i);
           toDelete = false;
           deleted = false;
           continue;
       }
       if(deleted == false){
          result = result.substring(0,result.length()-1);
          deleted = true;
       }
    
       toDelete = true;      
    }
    
    return result.toString();
    

    【讨论】:

      【解决方案6】:

      简单有效。 if 可以与 || 结合使用但这看起来更干净。

      public String starOut(String str) {
      
        int i = 0 ;
        for (int i = 0; i <str.length(); i++) {
      
          if (str.charAt(i) == '*') continue;
          if (i+1<str.length() && str.charAt(i+1) =='*') continue;
          if (i>0 && str.charAt(i-1) !='*') continue;
          ret += str.charAt(i);
        }  
        return ret;  
      
      }
      

      【讨论】:

        【解决方案7】:

        这是根据 Andrew 的回答稍作修改的代码:

        public String starOut(String str) {
            String pattern = "([^*]{0,1})\\*+([^*]{0,1})";
            return str.replaceAll(pattern, "");
        }
        

        【讨论】:

          【解决方案8】:

          这是我的解决方案 -

            public String starOut(String str) {
          boolean prevWasStar = false;
          String ans = "";
          for (int i=0; i<str.length();i++){
            int l = ans.length();
              if (str.charAt(i)=='*'){
                  if (!prevWasStar){
                    if(i==0) l = l+1;
                      ans=ans.substring(0, l-1);
                  } 
                  prevWasStar=true;
          } else{
            if(!prevWasStar) ans = ans + str.charAt(i);
            prevWasStar = false;
          }
          }return ans;
          }
          

          【讨论】:

            【解决方案9】:

            这是我的代码:

            public String starOut(String str) {
              String result = "";
              for (int i=0; i<str.length(); i++) {
                if (!(str.substring(Math.max(0, i-1), Math.min(str.length(), i+2)).contains("*"))) result += str.charAt(i);
              }
              return result;
            }
            

            【讨论】:

              【解决方案10】:

              虽然这篇文章太老了,已经有很多很好的答案,而且由于我在这个练习上投入了很多时间,但我也想通过提供我的答案来做出贡献。

              public String starOut(String str) 
              {
                String b = "";
                if(str.length() == 1 && !str.equals("*"))
                {
                  b = str;
                }
                for(int i=0; i<str.length()-1;i++)
                {
                   if(str.charAt(i) != '*' && str.charAt(i+1) != '*')
                   {
                      b = b + str.charAt(i);
                   }
                   if(str.charAt(i) == '*' && str.charAt(i+1) != '*')
                   {
                      i = i+1;
                   }
                }
                if(str.length() > 1 && str.charAt(str.length()-2) != '*' && str.charAt(str.length()-1) != '*')
                {
                  b = b + str.substring(str.length()-1);
                }
                return b;
              }
              

              【讨论】:

                【解决方案11】:
                public String starOut(String str)
                {
                  String ret = "";
                  int i;
                
                  if (str.length() == 0 || str.equals("*")) return "";
                
                  for (i = 0; str.charAt(i) == '*'; ++i)
                    ;
                  if (i > 0 && str.charAt(i-1) == '*')
                    ++i;
                  while (i < str.length()) {
                    if (i == str.length()-1 || i < str.length()-1 && str.charAt(i+1) != '*')
                      ret += str.charAt(i++);
                    else {
                      ++i;
                      while (i < str.length() && str.charAt(i) == '*')
                        ++i;
                      ++i;
                    }
                  }
                  return ret;
                }
                

                【讨论】:

                  【解决方案12】:

                  这是我的解决方案...

                  public String starOut(String str) {
                    String result = "";
                    int i = 0;
                    
                    while(i<str.length()){
                      if(i==0 && str.charAt(i)!='*') result = result + str.charAt(i);
                      
                      if(i>0 && str.charAt(i-1)!='*' && str.charAt(i)!='*'){
                        result = result + str.charAt(i);
                      } 
                      if(i>0 && str.charAt(i)=='*' && str.charAt(i-1)!='*'){
                        result = result.substring(0, result.length()-1);
                      }
                  
                      i++;
                    }
                    
                    return result;
                    
                  }
                  

                  【讨论】:

                  • 虽然这可能会回答 OP 的问题,但如果您在已添加的代码中添加说明会有所帮助。
                  【解决方案13】:

                  如果先反转条件检查,则可以减少代码行数。

                  public static String starOut(String str) {
                      String answer = "";
                      for (int i = 0; i < str.length(); i++) {
                          if (!((i > 0 && str.charAt(i - 1) == '*') ||
                                  (str.charAt(i) == '*') ||
                                  (i < str.length() - 1 && str.charAt(i + 1) == '*'))) {
                              answer += str.charAt(i);
                          }
                      }
                      return answer;
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    您可以在 startOut 方法中使用正则表达式来完成要求。

                    public static String starOut(String str) {
                       return str.replaceAll ( ".?[/*]+.?", "");
                    }
                    

                    正则表达式解释:

                    表达式开头和结尾的.? 匹配任何单个字符(如果它位于一行的开头或结尾,则不匹配任何字符)。表达式中间的[/*]+ 匹配一颗或多颗星。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2013-05-01
                      • 1970-01-01
                      • 2017-06-19
                      • 1970-01-01
                      • 2020-05-14
                      相关资源
                      最近更新 更多