2.TDD实现字符串排列组合

  题目地址:http://cyber-dojo.org/setup_default_start_point/show/?from=individual , 第二题。题目如下:
Write a program to generate all potential anagrams of an input string.For example, the potential anagrams of “biro” are
biro bior brio broi boir bori
ibro ibor irbo irob iobr iorb
rbio rboi ribo riob roib robi
obir obri oibr oirb orbi orib
  说白了就是给定一个字符串进行排列组合。咋一看确实很难做,有点难度。**这里我们一步步剖析TDD的实现。让你清清楚楚明白TDD。**TDD实现这个题目是水到渠成的。
  
一、TDD之前我们先建立两个类:test和要解决上述问题的答案代码
  我们先建立测试类,也建立调用的方法。
  
测试类AnagramsTest框架:

public class AnagramsTest {
    @Test
    public void testOnlyOneLetter() {
        //given

        //when

        //then
    }
}

业务类AnagramsProblem 框架:

public class AnagramsProblem {
    public List<String> getAnagrams(String givenString) {
        return null;
    }
}

二、当只有一个字母的时候
  当传入的字符串只有一个字符时,代码如下:
测试类:

public class AnagramsProblemTest {
    @Test
    public void testOnlyOneLetter() {
        //given(入参)
        String strGiven = "b";
        //引用anagramsProblem指向新AnagramsProblem对象,使用引用调用 排列组合 的实现方法
        AnagramsProblem anagramsProblem = new AnagramsProblem();

        //when(调用方法)
        List<String> strReturn = anagramsProblem.getAnagrams(strGiven);

        //then(验证)
        Assert.assertEquals(Arrays.asList("b"), strReturn);
    }
}

业务类:

public class AnagramsProblem {
    public List<String> getAnagrams(String givenString) {
        List<String> strList = new ArrayList<>();//java 1.8 新特性
        strList.add(givenString);
        return strList;
    }
}

  运行测试代码,成功,说明返回值跟预期的一样。
这里写图片描述

三、当有两个字母的时候
测试类:

public class AnagramsProblemTest {
    @Test
    public void testOnlyOneLetter() {
        //given(入参)
        String strGiven = "b";
        AnagramsProblem anagramsProblem = new AnagramsProblem();

        //when(调用方法)
        List<String> strReturn = anagramsProblem.getAnagrams(strGiven);

        //then(验证)
        Assert.assertEquals(Arrays.asList("b"), strReturn);
    }

    @Test
    public void testTwoLetters() {
        //given
        String strGiven = "bi";
        AnagramsProblem anagramsProblem = new AnagramsProblem();

        //when
        List<String> strReturn = anagramsProblem.getAnagrams(strGiven);

        //then
        Assert.assertEquals(Arrays.asList("bi", "ib"), strReturn);
    }
}

业务类:

public class AnagramsProblem {
    public List<String> getAnagrams(String givenString) {
        List<String> strList = new ArrayList<>();//java 1.8 新特性
        if(givenString.length() == 1) {
            strList.add(givenString);
            return strList;
        }

        if(givenString.length() == 2) {
            strList.add("" + givenString.charAt(0) + givenString.charAt(1));
            strList.add("" + givenString.charAt(1) + givenString.charAt(0));
            return strList;
        }
        return null;
    }
}

三、当有三个字母的时候
测试类:

package cs.anagrams;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

public class AnagramsProblemTest {
    @Test
    public void testOnlyOneLetter() {
        //given(入参)
        String strGiven = "b";
        AnagramsProblem anagramsProblem = new AnagramsProblem();

        //when(调用方法)
        List<String> strReturn = anagramsProblem.getAnagrams(strGiven);

        //then(验证)
        Assert.assertEquals(Arrays.asList("b"), strReturn);
    }

    @Test
    public void testTwoLetters() {
        //given
        String strGiven = "bi";
        AnagramsProblem anagramsProblem = new AnagramsProblem();

        //when
        List<String> strReturn = anagramsProblem.getAnagrams(strGiven);

        //then
        Assert.assertEquals(Arrays.asList("bi", "ib"), strReturn);
    }

    @Test
    public void testThreeLetters() {
        //given
        String strGiven = "bir";
        AnagramsProblem anagramsProblem = new AnagramsProblem();
        /** 这里需要排序,不然他会按顺序比较指定位置的字符串,可能会出错    */
        List<String> strExpect = Arrays.asList("bir", "bri", "ibr", "irb", "rbi", "rib");
        Collections.sort(strExpect);

        //when
        List<String> strReturn = anagramsProblem.getAnagrams(strGiven);
        Collections.sort(strReturn);

        //then
        Assert.assertEquals(strExpect, strReturn);
    }
}

业务类:

package cs.anagrams;

import java.util.ArrayList;
import java.util.List;

public class AnagramsProblem {
    public List<String> getAnagrams(String givenString) {
        List<String> strList = new ArrayList<>();//java 1.8 新特性
        if(givenString.length() == 1) {
            strList.add(givenString);
            return strList;
        }

        if(givenString.length() == 2) {
            //重复代码
            strList.add("" + givenString.charAt(0) + givenString.charAt(1));
            strList.add("" + givenString.charAt(1) + givenString.charAt(0));
            return strList;
        }

        if(givenString.length() == 3) {
            //重复代码
            strList.add("" + givenString.charAt(0) + givenString.charAt(1) + givenString.charAt(2));
            strList.add("" + givenString.charAt(0) + givenString.charAt(2) + givenString.charAt(1));
            strList.add("" + givenString.charAt(1) + givenString.charAt(0) + givenString.charAt(2));
            strList.add("" + givenString.charAt(1) + givenString.charAt(2) + givenString.charAt(0));
            strList.add("" + givenString.charAt(2) + givenString.charAt(0) + givenString.charAt(1));
            strList.add("" + givenString.charAt(2) + givenString.charAt(1) + givenString.charAt(0));
            return strList;
        }
        return null;
    }
}

  找规律:

if(givenString.length() == 3) {
            String str = givenString.replace(givenString.charAt(0) + "", "");
            strList.add("" + givenString.charAt(0) + givenString.charAt(1) + givenString.charAt(2));
            strList.add("" + givenString.charAt(0) + givenString.charAt(2) + givenString.charAt(1));

            String str1 = givenString.replace(givenString.charAt(1) + "", "");
            strList.add("" + givenString.charAt(1) + givenString.charAt(0) + givenString.charAt(2));
            strList.add("" + givenString.charAt(1) + givenString.charAt(2) + givenString.charAt(0));

            String str2 = givenString.replace(givenString.charAt(2) + "", "");
            strList.add("" + givenString.charAt(2) + givenString.charAt(0) + givenString.charAt(1));
            strList.add("" + givenString.charAt(2) + givenString.charAt(1) + givenString.charAt(0));
            return strList;
        }

  重构代码:

if(givenString.length() == 3) {
     for (int i = 0; i < givenString.length(); i++) {
         String str = givenString.replace(givenString.charAt(i) + "", "");
         strList.add("" + givenString.charAt(i) + str.charAt(0) + str.charAt(1));
         strList.add("" + givenString.charAt(i) + str.charAt(1) + str.charAt(0));

     }
     return strList;
 }

  查找规律:

if(givenString.length() == 3) {
   for (int i = 0; i < givenString.length(); i++) {
       String str = givenString.replace(givenString.charAt(i) + "", "");
       strList.add("" + givenString.charAt(i) + getAnagrams(str).get(0));
       strList.add("" + givenString.charAt(i) + getAnagrams(str).get(1));
   }
   return strList;
}

  再次重构givenString.length() == 3的代码,去掉重复代码,抽方法,inline代码:

if(givenString.length() == 3) {
    for (int i = 0; i < givenString.length(); i++) {
        for (int j = 0; j < getAnagrams(getRemaindString(givenString, i)).size(); j++) {
            strList.add("" + givenString.charAt(i) + getAnagrams(getRemaindString(givenString, i)).get(j));
        }
    }
    return strList;
}

  最终如下:

package cs.anagrams;

import java.util.ArrayList;
import java.util.List;

public class AnagramsProblem {
    public List<String> getAnagrams(String givenString) {
        List<String> strList = new ArrayList<>();//java 1.8 新特性
        if(givenString.length() == 1) {
            strList.add(givenString);
            return strList;
        }

        if(givenString.length() == 2) {
            strList.add("" + givenString.charAt(0) + givenString.charAt(1));
            strList.add("" + givenString.charAt(1) + givenString.charAt(0));
            return strList;
        }

        if(givenString.length() == 3) {
            for (int i = 0; i < givenString.length(); i++) {
                for (int j = 0; j < getAnagrams(getRemaindString(givenString, i)).size(); j++) {
                    strList.add("" + givenString.charAt(i) + getAnagrams(getRemaindString(givenString, i)).get(j));
                }
            }
            return strList;
        }
        return null;
    }

    private String getRemaindString(String givenString, int i) {
        return givenString.replace(givenString.charAt(i) + "", "");
    }
}

四、当有四个字母的时候
测试方法:

@Test
    public void testFourLetters() {
        //given
        String strGiven = "biro";
        AnagramsProblem anagramsProblem = new AnagramsProblem();
        List<String> exceptStr = Arrays.asList("biro", "bior", "brio", "broi", "boir", "bori",
            "ibro", "ibor", "irbo", "irob", "iobr", "iorb",
            "rbio", "rboi", "ribo", "riob", "roib", "robi",
            "obir", "obri", "oibr", "oirb", "orbi", "orib");
        Collections.sort(exceptStr);

        //when
        List<String> strReturn = anagramsProblem.getAnagrams(strGiven);
        Collections.sort(strReturn);

        //then
        Assert.assertEquals(exceptStr, strReturn);
    }

业务语句:

if(givenString.length() == 4) {
    for (int i = 0; i < givenString.length(); i++) {
         for (int j = 0; j < getAnagrams(getRemaindString(givenString, i)).size(); j++) {
             strList.add("" + givenString.charAt(i) + getAnagrams(getRemaindString(givenString, i)).get(j));
         }
     }
     return strList;
 }

五、当有N个字母的时候
业务类,抽共性:

package cs.anagrams;

import java.util.ArrayList;
import java.util.List;

public class AnagramsProblem {
    public List<String> getAnagrams(String givenString) {
        List<String> strList = new ArrayList<>();//java 1.8 新特性
        if(givenString.length() == 1) {
            strList.add(givenString);
            return strList;
        }

        if(givenString.length() >= 2) {
            for (int i = 0; i < givenString.length(); i++) {
                for(int j = 0; j < getAnagrams(getRemaindString(givenString, i)).size(); j++)
                strList.add("" + givenString.charAt(i) + getAnagrams(getRemaindString(givenString, i)).get(j));
            }
            return strList;
        }

        return null;
    }

    private String getRemaindString(String givenString, int i) {
        return givenString.replace(givenString.charAt(i) + "", "");
    }
}

六、去掉重复字符
  使用set代替List即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值