首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编写一个递归函数,它接受一个正整数n,并绘制N到N的Hadamard模式,其中N= 2^n。

编写一个递归函数,它接受一个正整数n,并绘制N到N的Hadamard模式,其中N= 2^n。
EN

Code Review用户
提问于 2020-08-31 13:00:21
回答 2查看 226关注 0票数 2

这是网络练习2.3.20。从“计算机科学”一书中看塞奇威克和韦恩的跨学科方法:

编写一个递归程序,它接受命令行参数n,并绘制N到N的Hadamard模式,其中N= 2^n。不要使用数组。一个1乘1的Hadamard图案是一个单一的黑色方块.通常,一个2N乘2N Hadamard图案是通过对4拷贝的N- by -N模式的形式,以2-2网格的形式,然后反转所有的颜色在右下角N-N拷贝。N-by-N - Hadamard H(N)矩阵是一个布尔矩阵,具有任意两行在N/2位上完全不同的显著性质。以下是前几个Hadamard矩阵。

这是我的节目:

代码语言:javascript
复制
public class wexercise2_3_20 
{
    public static void hadamard(int n, double x, double y, double size,
                                boolean color)
    {
        double x1 = x - size/2, x2 = x + size/2;
        double y1 = y - size/2, y2 = y + size/2;
        if (n == 0) return;
        if (color) 
        {
            StdDraw.setPenColor(StdDraw.BLACK);
            StdDraw.filledSquare(x,y,size);
        }
        else
        {
            StdDraw.setPenColor(StdDraw.WHITE);
            StdDraw.filledSquare(x,y,size);
        }
        hadamard(n-1, x1, y1, size/2, color);
        hadamard(n-1, x1, y2, size/2, color);
        hadamard(n-1, x2, y2, size/2, color);
        hadamard(n-1, x2, y1, size/2, !color);

    }
    public static void main(String[] args)
    {
        int n = Integer.parseInt(args[0]);
        hadamard(n, 0.5, 0.5, 0.5, true);
    }
}

StdDraw是本书作者编写的一个简单的API。

有什么办法可以改进我的计划吗?

感谢您的关注。

EN

回答 2

Code Review用户

回答已采纳

发布于 2020-08-31 20:40:08

在您的代码中存在以下退出条件:

代码语言:javascript
复制
if (n == 0) return;

您可以在n > 0开始时重写代码执行它,前提是n总是从问题描述中得到肯定,所以您的函数可以重写如下:

代码语言:javascript
复制
public static void hadamard(int n, double x, double y, double size,
                                boolean color) {
    if (n > 0) { 
     //your code 
    }
}

注意:正如@RoToRa在我的回答下面的评论中注意到的,将完整的代码函数包装在if分支中并不是一个好的实践代码,所以最好在函数的开头使用旧的if (n == 0) return;,然后是函数的主体。

在代码的开头,有以下声明:

代码语言:javascript
复制
double x1 = x - size/2, x2 = x + size/2;
double y1 = y - size/2, y2 = y + size/2;

您可以如下所示重写它们:

代码语言:javascript
复制
final halfSize = size / 2;
final double x1 = x - halfSize;
final double y1 = y - halfSize;

然后,对函数的递归调用可以重写如下:

代码语言:javascript
复制
--n; //<-- decrementing n here for clarity
hadamard(n, x1, y1, halfSize, color);
hadamard(n, x1, y1 + size, halfSize, color);
hadamard(n, x1 + size, y1 + size, halfSize, color);
hadamard(n, x1 + size, y1, halfSize, !color);

您的方法可以这样重写:

代码语言:javascript
复制
public static void hadamard(int n, double x, double y, double size,
            boolean color) {

    if (n > 0) {

        final double halfSize = size / 2;
        final double x1 = x - halfSize;
        final double y1 = y - halfSize;
        Color c = color ? StdDraw.BLACK : StdDraw.WHITE;

        StdDraw.setPenColor(c);
        StdDraw.filledSquare(x, y, size);

        --n; //put here for clarity
        hadamard(n, x1, y1, halfSize, color);
        hadamard(n, x1, y1 + size, halfSize, color);
        hadamard(n, x1 + size, y1 + size, halfSize, color);
        hadamard(n, x1 + size, y1, halfSize, !color);

    }
}
票数 2
EN

Code Review用户

发布于 2020-08-31 14:58:39

Java中的类名应该以大写字母开头。

避免在同一行中初始化两个变量。

filledSquare调用在两个if分支中是相同的,它可以从if中移出。现在,两个if分支只在参数中更改为setPenColor调用,您可以将其替换为

代码语言:javascript
复制
Color theColor = color ? WHITE : BLACK;

现在看来,您可以完全删除布尔参数(布尔参数糟糕),并传递一个Color;您所需要的只是一个反转颜色的函数。

这种批评与递归无关;我不知道这是否正确:)

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/248698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档