Count Up Down(上下计数)

209 篇文章 1 订阅

这个题目是 Kayak 发布的代码挑战题目。

最简单的描述就是不使用循环,输出 0 到 5,然后同样不是会用循环的方式再次输出 5 到 0。

英文描述

Part 1

Write a program that counts in sequential order when given a start and end value - without using any iterative programing loops, i.e. while, for, do, for-each, etc.

You can assume that both the start and end values will always be positive and that the start value will always be less then the end value. There should only be one method with the following signature:

void countUp(int start, int end) {
// All code exercise code should go here
}

Here is example output with start=0 and end=5:

[ 0,1,2,3,4,5]

Part 2

Continuing with part 1 change the output of the test, so that it now prints out in sequential order to the end value (only once), but then also counts down to the start value.

Again, using no iterative loops, and assuming that both the start and end values will always be positive and that start value will always be less then the end value. There should only be one method with the following signature:

void countUpAndDown(int start, int end) {
// All code exercise code should go here
}

Here is example output with start=0 and end=5:

[0,1,2,3,4,5,4,3,2,1,0]

中文描述

这里我不按照原文一字一字的翻译,但是尽量按照题目的要求把题目解释清楚。

最简单的描述就是不使用循环,输出 0 到 5,然后同样不是会用循环的方式再次输出 5 到 0。

本题目分 2 部分,第一部分是不使用循环的方式输出 0 到 5,第二部分是不使用循环的方式输出 0 到 5 以后,再输出 5 到 0。

其中需要注意的是 5 只能输出一次。

思路和点评

不使用 For 循环的方式输出 0 到 5 ,我们可以想到有几个方法。

第一个方法可能比较容易想到的就是递归调用,你可以根据输入的值,递归调用需要的次数就可以输出值了。你还可以采用计算机时钟的方式进行输出。

在这里我们采用递归调用的方式进行输出。

源代码

源代码和有关代码的更新请访问 GitHub:

https://github.com/cwiki-us/codebank-algorithm/blob/master/src/main/java/com/ossez/codebank/interview/KayakCountUpDown.java

测试类请参考:

https://github.com/cwiki-us/codebank-algorithm/blob/master/src/test/java/com/ossez/codebank/interview/tests/KayakTest.java

代码思路请参考:

package com.ossez.codebank.interview;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * https://www.cwiki.us/display/ITCLASSIFICATION/Count+Up+Down
 * 
 * @author YuCheng
 *
 */
public class KayakCountUpDown {
  private final static Logger logger = LoggerFactory.getLogger(KayakCountUpDown.class);

  static int minNumber = 0;
  static int maxNumber = 0;
  int tmpN = 0;
  List<Integer> retList = new ArrayList<Integer>();

  /**
   * 
   * @param start
   * @param end
   * @return
   */
  public List<Integer> countUp(int start, int end) {
    logger.debug("BEGIN");
    maxNumber = end;
    tmpN = start;
    moveUp(0);
    retList.add(end);
    return retList;

  }

  /**
   * 
   * @param start
   * @param end
   * @return
   */
  public List<Integer> countUpDown(int start, int end) {
    logger.debug("BEGIN");
    minNumber = start;
    maxNumber = end;
    tmpN = start;

    moveUp(0);
    retList.add(end);

    moveDown(1);
    return retList;

  }

  /**
   * 
   * @param n
   */
  private void moveUp(int n) {
    retList.add(tmpN);
    tmpN++;
    if (tmpN != maxNumber) {
      moveUp(tmpN + 1);
    }

  }

  /**
   * 
   * @param n
   */
  private void moveDown(int n) {
    tmpN = (maxNumber - n);
    retList.add(tmpN);

    if (tmpN != minNumber) {
      moveDown(n + 1);
    }
  }

}

 

 

测试结果

上面程序的测试结果如下:

2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - TEST Count Up and Down 
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - [2 -> 5]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.KayakCountUpDown] - BEGIN
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - UP - [2, 3, 4, 5]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.KayakCountUpDown] - BEGIN
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - UP & DOWN - [2, 3, 4, 5, 4, 3, 2]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - [0 -> 5]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.KayakCountUpDown] - BEGIN
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - UP - [0, 1, 2, 3, 4, 5]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.KayakCountUpDown] - BEGIN
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - UP & DOWN - [0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - [-1 -> 5]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.KayakCountUpDown] - BEGIN
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - UP - [-1, 0, 1, 2, 3, 4, 5]
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.KayakCountUpDown] - BEGIN
2018/12/25 21:23:54 DEBUG [com.ossez.codebank.interview.tests.KayakTest] - UP & DOWN - [-1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, -1]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,我们需要了解Verilog中计数器的基本结构。计数器通常由一个寄存器和一个时钟信号组成,每次时钟上升沿触发时,计数器会自增一。在本次实现中,我们需要添加上下计数和装载计数的功能。 以下是一个具有上下计数和装载计数计数器Verilog代码示例: ```verilog module up_down_counter ( input clk, // 时钟信号 input rst, // 复位信号 input load, // 装载计数信号 input up_down, // 上下计数信号 output reg [7:0] count // 计数器输出 ); always @(posedge clk or posedge rst) begin if (rst) begin count <= 8'b0; // 复位计数器 end else if (load) begin count <= 8'b0; // 装载计数器 end else if (up_down) begin count <= count + 1; // 上计数 end else begin count <= count - 1; // 下计数 end end endmodule ``` 在这个示例中,我们添加了三个输入信号:`load`用于装载计数器,`up_down`用于控制计数器上下计数,`rst`用于复位计数器。计数器的输出为8位的`count`信号。 在`always`块中,我们使用了`if-else`语句来实现计数器的逻辑。当复位信号`rst`为高电平时,计数器被重置为0。当装载计数信号`load`为高电平时,计数器被重置为0。当上下计数信号`up_down`为高电平时,计数器的值增加1。当上下计数信号`up_down`为低电平时,计数器的值减少1。 接下来,我们需要验证这个计数器设计是否正确。我们可以使用仿真器来模拟计数器的行为,并检查其输出是否符合预期。以下是一个使用Verilog仿真器的示例: ```verilog module up_down_counter_tb; reg clk; reg rst; reg load; reg up_down; wire [7:0] count; // 实例化计数器 up_down_counter counter( .clk(clk), .rst(rst), .load(load), .up_down(up_down), .count(count) ); // 时钟信号 always begin clk = 0; #5; clk = 1; #5; end initial begin // 初始化输入信号 rst = 1; load = 0; up_down = 1; #10; // 取消复位信号 rst = 0; #20; // 装载计数器 load = 1; #10; load = 0; #20; // 上计数 up_down = 1; #50; // 下计数 up_down = 0; #50; // 停止仿真 $finish; end endmodule ``` 在这个示例中,我们使用了`reg`类型的输入信号和`wire`类型的输出信号。在实例化计数器时,我们将输入信号和输出信号连接到计数器模块中。 在时钟块中,我们定义了一个时钟信号,每过5个时间单元,时钟信号会从低电平变为高电平,再过5个时间单元后,时钟信号会从高电平变为低电平。这样就模拟了一个频率为100MHz的时钟信号。 在初始化块中,我们定义了输入信号的初始值,并在一定时间后修改这些信号的值。我们首先将复位信号`rst`设置为高电平,等待10个时间单元后,再将其设置为低电平。这个操作可以使计数器从0开始计数。然后,我们将装载计数信号`load`设置为高电平,等待10个时间单元后,再将其设置为低电平。这个操作可以使计数器的值被重置为0。接下来,我们先让计数器上计数50次,再下计数50次。最后,我们使用`$finish`指令停止仿真。 运行仿真器后,我们可以检查计数器的输出是否符合预期。在这个示例中,我们预期计数器的值会先变为50,然后再变为0。如果仿真结果与预期结果相符,那么这个计数器设计就可以被验证通过。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HoneyMoose

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值