题目要求是这样的
1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7。
2. 让100个学生拍成一队,然后按顺序报数。
3. 学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz;
如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;
如果所报数字是第三个特殊数(7)的倍数,那么要说Whizz。
4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,
比如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, 以此类推。
如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。
5. 学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要说相应的单词,
比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。
如果数字中包含了第一个特殊数,那么忽略规则3和规则4,
比如要报35的同学只报Fizz,不报BuzzWhizz。
在工作之前就很喜欢没事去学校的ACM网站刷题玩,现在工作后很少在做这种有意思的题目了,这次无意间看到ThoughtWorks的这道面试题,瞬间又找回了当初刷题时的感觉。
我是一名android程序员,尽管已经有一年多没有碰C语言了,但是看到这个题目的时候,第一反应还是用C语言去实现,毕竟当初的算法题目都是用C语言去实现的。
以下是我第一遍写的代码(这种C不像C,java不像java的代码风格,还希望大家不要吐槽,长时间没有用C语言了):
#include<stdio.h>
int main(void)
{
int a,b,c;
int i;
//因为报数不可能报0,所以此处忽略对0的检测
printf("请输入三个数:");
scanf("%d%d%d",&a,&b,&c);
printf("\n");
//比最小的数还要小不考虑
for(i = 1; i <a;i++){
printf("%d\n",i);
}
//判断
for(i = a; i <=100; i++)
{
switch(checked(a,b,c,i))
{
case 1:
printf("Fizz\n");
break;
case 2:
printf("Buzz\n");
break;
case 3:
printf("Whizz\n");
break;
case 0:
checked_multiple(a,b,c,i);
printf("\n");
break;
}
}
return 0;
}
//检测倍数
void checked_multiple(int a, int b, int c, int n)
{
int boolean = 0;
if (n%a == 0){
printf("Fizz");
boolean = 1;
}
if (n%b == 0){
printf("Buzz");
boolean = 1;
}
if(n%c == 0){
printf("Whizz");
boolean = 1;
}
if(!boolean){
printf("%d",n);
}
}
//检测与位数相同的情况
int checked(int a, int b, int c, int n)
{
int prev; //十位
int next; //个位
if (n >10){
prev = n/10;
next = n%10;
}else{
prev = 0;
}
if (a == prev || a == next){
return 1;
}
if (b == prev || b == next){
return 2;
}
if (c == prev || c == next){
return 3;
}
return 0;
}
在第一遍写完后,我最大的感想就是:我变了。
我变的不再像当初那个一心求效率,一心求代码行数的自己,现在的我,考虑的更多的是功能的模块化,与重用性。
如果是两年前的自己,一定会一个main函数,十几二十行代码,想尽一切办法的压缩代码行数去完成这个题目。
我不知道是不是因为接触到了java,是不是因为面向对象,是不是因为做了太多的项目的原因,现在的自己考虑的更多的是别人如何看懂我的代码,我的代码如何适用更多的场合。
于是,有了如下的改动(期间发现自己对题目的理解还出了些差错,第五项说的是仅考虑第一个特殊数字)
#include<stdio.h>
int main(void)
{
int a,b,c;
int i,j;
//因为报数不可能报0,所以此处忽略对0的检测
printf("请输入三个数(用逗号分隔):");
scanf("%d,%d,%d",&a,&b,&c);
printf("\n");
for(i = 1; i < a; i++){
printf("%d\n",i);
}
//判断
for(i = a; i <=100; i++){
j = 0;
if (checked_fizz(a,i)){
printf("Fizz");
}else{
j += checked_multiple2(a,i,"Fizz");
j += checked_multiple2(b,i,"Buzz");
j += checked_multiple2(c,i,"Whizz");
if (!j){
printf("%d",i);
}
}
printf("\n");
}
return 0;
}
//检测含有第一个数字
int checked_fizz(int a, int n){
if (n/10 == a || n%10 == a){
return 1;
}else{
return 0;
}
}
//检测倍数
int checked_multiple2(int a, int n,char* str){
if (n%a == 0){
printf("%s",str);
return 1;
}else{
return 0;
}
}
我 不敢保证这是效率最高的代码,但我敢保证这是可以让任何人使用的代码,即使题目的条件改变:比如输出的文字变成kkkk,或者jjj,再或者其他的东西, 我的函数模块是不需要改变的,我的逻辑判断是不需要改变的。即使题目再多添加特殊数字,我的函数功能依旧不变,所需要改变的仅仅是main函数中对j值的 累加操作次数。
以上是我对于这道题的总结,也是我对于自己这两年改变的一次回顾。
我一直认为,人只有认识到自己的过去改变,才能为了未来更好的改变。