相信不少人都见过下面这道龟兔赛跑问题。
题目来源:PTA
这是一道很简单的问题。不过我在查阅了一些帖子之后发现,可能因为它本身是一道C语言的练习题,大部分解法都是以面向过程思路编写的。即使是一些使用C++和Java的解法,仔细观察之后也可以发现是C语言解法的换皮。于是我想要转换思路,用OOP的思维解决这个问题。
main函数的部分非常简单,核心是设定一个for循环记录时间的流逝,每流逝1分钟,调用移动方法(即go())计算一次兔子和乌龟的位置。
int main(void)
{
int time;
std::cin >> time;
Turtle turtle;
Rabbit rabbit;
for (int t = 0; t < time; t++) {
turtle.go();
rabbit.go();
}
if (turtle.position > rabbit.position) {
std::cout << "@_@ " << turtle.position << std::endl;
}
else if(turtle.position < rabbit.position){
std::cout << "^_^ " << rabbit.position << std::endl;
}
else {
std::cout << "-_- " << turtle.position << std::endl;
}
return 0;
}
很显然这里需要定义两个类,Rabbit和Turtle(欸我知道Turtle和Tortoise不是同一种生物,但是我代码写完了才发现写成了海龟www,算了,错就错吧,海龟更可爱),它们需要一个position属性表示它们跑过的距离,以及一个go()方法。于是在这里我首先建立了一个Animal类,计划将Rabbit和Turtle作为其子类。
class Animal {
public:
int turtleSpeed = 3;
int rabbitSpeed = 9;
int rabbitSleepTime = 30;
int rabbitMoveTime = 10;
void go(void) {
;
}
};
在这里我额外设定了turtleSpeed、rabbitSpeed、rabbitSleepTime和rabbitMoveTime以备后续使用。注意在Animal类里并没有上文提到的position属性。最开始的时候我加入了position属性,但是后来我发现将position作为子类的静态属性更好一些,详细请看下文。
Turtle类的设计是平凡的。
class Turtle: public Animal{
public:
static int position;
void go(void) {
position += turtleSpeed;
}
};
int Turtle::position = 0;
Rabbit类的行为有些复杂。首先需要比较Rabbit和Turtle所在position的大小,如果将position设定在父类中,设计go()的时候就无法获取Turtle类对象的position,从而无法比较。正是因此我将position设定为各个子类的静态属性。
其次,Rabbit的移动并不直接以1分钟为单位,而是每10分钟或每30分钟进行一次判定,再根据判定的结果决定下个10分钟或30分钟的行动。因此,我先在在go()中描述对比判定、运动和休息的过程,再额外设定了私有方法move()和sleep(),用于描述Rabbit每分钟内的行为。
class Rabbit: public Animal{
public:
static int position;
void go(void) {
if (movingTimeLeft != 0) {
move();
}
else if (sleepTimeLeft != 0) {
sleep();
}
else {
if (Rabbit::position > Turtle::position) {
sleepTimeLeft = rabbitSleepTime;
sleep();
}
else {
movingTimeLeft = rabbitMoveTime;
move();
}
}
}
private:
int sleepTimeLeft = 0;
int movingTimeLeft = rabbitMoveTime;
void move(void) {
position += rabbitSpeed;
movingTimeLeft--;
}
void sleep(void) {
sleepTimeLeft--;
}
};
int Rabbit::position = 0;
每次判定,设置一个movingTimeLeft或sleepingTimeLeft作为时钟记录运动或休息的时间。若兔子发现自己领先,设定sleepingTimeLeft倒数30分钟,反之设定movingTimeLeft倒数10分钟。在这时间段里,执行move()或sleep()方法,反应运动或休息的时间流逝。注意判定的那一分钟里也要执行一次动作。
按照以上代码设计好程序,输入PTA裁判,全红,好耶!
以上就是我使用OOP思路编写的龟兔赛跑问题的解法。