java - 检查是否存在由 [cages] 包围的某些字母并替换它们的算法?

标签 java string algorithm replace

您好,我正在做以下编程练习:The Hunger Games - Foxes and Chickens 。声明如下:

Story

Old MacDingle had a farm.

To be more precise, he had a free-range chicken farm.

But Old MacDingle also had a fox problem.

Foxes F eat chickens C

At night the only guaranteed "safe" chickens are in their cages [] (unless a fox has got into the cage with them!)
Kata Task

Given the initial configuration of foxes and chickens what will the farm look like the next morning after the hungry foxes have been feasting?
Examples
Ex1 Before  

CCC[CCC]FCC[CCCCC]CFFFF[CCC]FFFF

After   

...[CCC]F..[CCCCC].FFFF[CCC]FFFF

Ex2 Before  

...[CCC]...[CCCFC].....[CCC]....

After   

...[CCC]...[...F.].....[CCC]....

Ex3 Before  

CCC[CCC]FCC[CCCFC]CFFFF[CCC]FFFF

After   

...[CCC]F..[...F.].FFFF[CCC]FFFF

Notes

    Anything not a fox, a chicken, or a cage is just dirt .
    All cages are intact (not open-ended), and there are no cages inside other cages

我编写了以下代码:

public class Dinglemouse {
  public static String hungryFoxes /*🦊🦊*/ (String farm) {
    System.out.println("farm: "+farm);
    int posCageStarted = -1;
    int posCageEnded = -1;

    //If there are not cages, and there are foxes, all chickens are cleared; otherwise we keep the farm as it is.
    if(!farm.contains("[") && !farm.contains("]")){
      if(farm.contains("F")){
        return farm.replace("C",".");
      }else{
        return farm;
      }
    }

    for(int i = 0; i < farm.length(); i++){
      System.out.println("i: "+i);
      char c = farm.charAt(i);
      if(c=='['){
        posCageStarted=i;
      }else if(c==']'){
        posCageEnded=i;
      }

      //If we are between cages ]...[
      if(posCageEnded>posCageStarted){ 
        System.out.println("posCageEnded: "+posCageEnded);
        System.out.println("posCageStarted: "+posCageStarted);
        String betweenCages = "";
        String ending = "";
        String starting = "";
        int nextCageStart;
        if(farm.substring(posCageEnded).contains("[")){
          nextCageStart = posCageEnded+farm.substring(posCageEnded).indexOf('[');
          betweenCages = farm.substring(posCageEnded+1,nextCageStart);
        }else{
          nextCageStart = farm.indexOf('[');
          ending = farm.substring(posCageEnded+1);
          starting = farm.substring(0,nextCageStart);
          betweenCages = ending+starting;
        }
          System.out.println("nextCageStart: "+nextCageStart);
          System.out.println("betweenCages: "+betweenCages);
        if(betweenCages.contains("F")){
          betweenCages = betweenCages.replace('C','.');
          System.out.println("betweenCages: "+betweenCages);
          if(nextCageStart>posCageEnded){
            farm = farm.substring(0,posCageEnded+1) + betweenCages + farm.substring(nextCageStart);
          }else{
            farm = betweenCages.substring(ending.length()) + farm.substring(farm.indexOf('['),posCageEnded+1)
                  + betweenCages.substring(0,ending.length());
          }
          System.out.println("new farm: "+farm);
        }
        i+=betweenCages.length();


      //If we are inside a cage [...]  
      }else if(posCageStarted>posCageEnded){
          System.out.println("inside cage: ");
          System.out.println("posCageStarted: "+posCageStarted);
          System.out.println("posCageEnded: "+posCageEnded);
          int cageEnd = posCageStarted+1 + farm.substring(posCageStarted+1).indexOf(']');
          System.out.println("cageEnd: "+cageEnd);
          String insideCage = farm.substring(posCageStarted+1,cageEnd);
          System.out.println("insideCage: "+insideCage);
          if(insideCage.contains("F")){
            insideCage = insideCage.replace("C",".");
            farm = farm.substring(0,posCageStarted+1) + insideCage + farm.substring(cageEnd);
            System.out.println("new farm: "+farm);
          }
        i+=insideCage.length();
      }
    }
    System.out.println("\n\nWe return farm: "+farm);
    return farm;
  }

}

我很好奇为什么随机测试失败:

import org.junit.*;
import static org.junit.Assert.assertEquals;

public class ExampleTests {

  @Test
  public void ex1() {
    final String before = "CCC[CCC]FCC[CCCCC]CFFFF[CCC]FFFF";
    final String after  = "...[CCC]F..[CCCCC].FFFF[CCC]FFFF";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void ex2() {
    final String before = "...[CCC]...[CCCFC].....[CCC]....";
    final String after  = "...[CCC]...[...F.].....[CCC]....";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void ex3() {
    final String before = "CCC[CCC]FCC[CCCFC]CFFFF[CCC]FFFF";
    final String after  = "...[CCC]F..[...F.].FFFF[CCC]FFFF";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void noCagesTest(){
    final String before = "CCCCCF.CC..C..CC.CF.";
    final String after  = ".....F............F.";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void randomTest3(){
    final String before = ".C......C.F.[...F.]C..CC.....CC.CC[..CFCCC..CCCCCFC....CC...]C[.....C.....C...]";
    final String after  = "..........F.[...F.]...............[...F..........F..........].[.....C.....C...]";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }

  @Test
  public void randomTest1(){
    final String before = "..CCCF....[.CC.CCC.CFFC...C.........C..C.CF..CC]CCCC....[.]";
    final String after  = ".....F....[.........FF....................F....]........[.]";
    assertEquals(after, Dinglemouse.hungryFoxes(before));
  }


}

如果我们密切关注测试 random1,它会期望我们替换结尾的 Chickens。我的意思是之前的代码输出:

.....F....[.........FF....................F....]CCCC....[.]

它应该输出:

.....F....[.........FF....................F....]........[.]

此外,当我们执行 randomTest3 时,我们的代码输出:

..........F.[...F.]C..CC.....CC.CC[...F..........F..........]C[.....C.....C...]

它应该输出:

..........F.[...F.]...............[...F..........F..........].[.....C.....C...]

这怎么可能?

最佳答案

At night the only guaranteed "safe" chickens are in their cages [] (unless a fox has got into the cage with them!)

据我所知,如果没有笼子,那么所有的鸡都会死,无论狐狸与否,所以

//If there are not cages, and there are foxes, all chickens are cleared; otherwise we keep the farm as it is.
if(!farm.contains("[") && !farm.contains("]")){
  if(farm.contains("F")){
     return farm.replace("C",".");
  }else{
    return farm;
  }
}

应替换为

//If there are not cages all chickens are cleared
if(!farm.contains("[") && !farm.contains("]")){
  return farm.replace("C",".");
}

您的代码的另一个问题是当我们在笼子内和不在笼子内时无法检测到情况。维护一个 boolean 变量 isInsideCage 会更容易,每次传递 '[' 时将其设置为 true,每次传递 ']' 时将其设置为 false。

而不是 someIndex + farm.substring(someIndex).indexOf(']')您可以使用farm.indexOf(']', someIndex) .

但是,您的代码不起作用的原因是您正在检查笼子之间是否存在狐狸以消灭鸡,而笼子外的鸡无论如何都应该死了。具体来说,您在 if-branch //If we are between cages ]...[ 中有这一行:

       if(betweenCages.contains("F")){

删除狐狸的此项检查。

现在你的代码正确地删除了第一个笼子之前的所有鸡,因为然后 posCageEndedposCageStarted都是 -1,所以 posCageStarted>posCageEnded 都不是也不posCageEnded>posCageStarted ,但在第一个笼子之后,它会停止将鸡移出笼子,除非狐狸也在那里。

PS。在第 2 行的评论中为 2 个狐狸脸投票:)

关于java - 检查是否存在由 [cages] 包围的某些字母并替换它们的算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60398371/

相关文章:

c++ - 无法从 istringstream (C++) 获取 line()

c++ - 为什么需要在新字符(str.length())上添加一个?

java - 如何选择特定日期(当 : type = "date") in Selenium WebDriver?

java - 如何重新加载 JSF 使用的 ResourceBundle?

java - StaxEventItemWriter - 文件不可写问题

c++ - 在 double 列表中找到最大的数字,需要关心精度吗?

algorithm - 使用 ControllerMate 循环 LED 模式

java - 如何在 MethodEntry 回调中获取参数值

python - 使用新的 Python 格式函数舍入小数

xml - 如何使用 XSLT 创建一组元素的子集(其中元素名称很复杂)?