关于Thoughtworks在拉勾的那个面试题

来源:互联网 发布:新网域名怎么设置ip 编辑:程序博客网 时间:2024/05/16 19:09

题目内容:

FizzBuzzWhizz

你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏。此时有100名学生在上课。游戏的规则是:


1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7。
2. 让所有学生拍成一队,然后按顺序报数。
3. 学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz;如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;如果所报数字是第三个特殊数(7)的倍数,那么要说Whizz。
4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,比如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, 以此类推。如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。
5. 学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要说相应的单词,比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。如果数字中包含了第一个特殊数,那么忽略规则3和规则4,比如要报35的同学只报Fizz,不报BuzzWhizz。
 
现在,我们需要你完成一个程序来模拟这个游戏,它首先接受3个特殊数,然后输出100名学生应该报数的数或单词。比如,
 
输入
3,5,7
输出(片段)

1
2
Fizz
4
Buzz
Fizz
Whizz
8
Fizz
Buzz
11
Fizz
Fizz
Whizz
FizzBuzz
16
17
Fizz
19
Buzz 
一直到100


5.1节前,在部门内部安排大伙写了一下,很多童鞋子也写了,感觉用JAVA写出来的,没有比较理想的。后来就借这个题叫大伙坐一起,一起写了一下。代码都属临场发挥,没过多细想,应该还有很多重构空间,因为一来本来没有投简历意向,二来时间也不是很足够,所以,在此就不追求极致了。与大伙分享一下,重在思想,欢迎指正。


拿一个问题,我们首先分析问题的本质,本题的本质就是处理数字,OK.那我们就先定义一个接口:

public interface NumberHandler {    String doHandler(Integer num);}

我们继续分析,其实有2种处理数据的方式,一种是倍数,一种是包含关系,所以我们定义了2个具体实现类:ContainHandler,MutipluHandler。

经过简单重构以后,提取出了一个DefaultHandler。代码如下:


public abstract class DefaultHandler implements NumberHandler {   /**输入值*/    protected Integer value;    /**输出单词*/    protected String  word;    public DefaultHandler(Integer value, String word) {        this.value = value;        this.word = word;    }    public abstract String doHandler(Integer num);}



public class MutipluHandler extends DefaultHandler{    public MutipluHandler(Integer value, String word) {        super(value, word);    }    @Override    public String doHandler(Integer num) {        if(num % value==0){            return word;        }        return null;    }}

public class ContainHandler extends DefaultHandler implements Dictatorial{    public ContainHandler(Integer value, String word) {        super(value, word);    }    @Override    public String doHandler(Integer num) {        if(num.toString().contains(value.toString())){            return word;        }        return null;    }}

你是不是发现了ContainHandler还实现了一个Dictatorial接口,这个其实是后来加上去的,因为一旦满足ContainHandler处理条件,将不会被其它处理器处理,所以他是一个独占式的。因此定义了Dictatorial一个标识接口:

/** * Created by Administrator on 2014/5/7. * 独断处理,标识接口 */public interface Dictatorial {}


剩下要做的就是需要一个处理器链,来挨个调用处理逻辑:

public class FilterChain {  private static  LinkedList<NumberHandler> handlerList  = new LinkedList<NumberHandler>();  public void addHandler(NumberHandler handler){      if(handler instanceof  Dictatorial){          handlerList.addFirst(handler);      }else{          handlerList.add(handler);      }  }  public void doFilter(Integer num){        String result  =  "";        boolean flag = true;        for(NumberHandler handler: handlerList){            //独断处理            if(!flag) break;            String temp = handler.doHandler(num);            if(temp != null){                result+= temp;                if(handler instanceof  Dictatorial){                    flag = false;                }            }        }      System.out.println(result == "" ? num : result);  }}


最后就是测试类:

public class TestRunner {    public static void main(String[] args) {        //create resource        FilterChain chain = new FilterChain();        MutipluHandler h1 = new MutipluHandler(3,"Fizz");        MutipluHandler h2 = new MutipluHandler(5,"Buzz");        MutipluHandler h3 = new MutipluHandler(7,"Whizz");        ContainHandler h4 = new ContainHandler(3,"Fizz");        chain.addHandler(h4);        chain.addHandler(h1);        chain.addHandler(h2);        chain.addHandler(h3);        for(int i= 1; i<=100; i++){            chain.doFilter(i);        }    }}



其实在解决这个问题的时候,大致过程是这样:

1.定义接口

2.给出2个实现类,支持3,5,7

3.重构2个实现类,将3,5,7做到可以灵活配置。

4.定义FilterChain,先满足倍数处理

5.处理包含这种独占式处理器,定义标识接口,重构FilterChain



1 0
原创粉丝点击