0

之前在 C#.Net Mandelbrot 集合上发布了一个问题,该问题得到了有益的回答,但是我不得不回到这个 Mandelbrot 集合并在其定义(虚构和真实)坐标的双变量上实现一个结构。

作为一个刚接触结构并且对它们有点生疏的人,我想就我做错了什么以及如何通过查看它来改进上述代码提供一些建议,我相信它可以稍微优化一下. 这是使用结构的正确方法吗?如果不是,有哪些替代方案或最佳技术?谢谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace wmcMandelbrot
{
struct doubleVar
{

    public double realCoord, imagCoord;
    public double realTemp, imagTemp, realTemp2, arg;
    public double newIcoord, newIcoord1, newIcoord2;
    public double rCoord, rCoord1, rCoord2;
 }


class Program
{
    static void Main(string[] args)
    {

        doubleVar doubleNum;
        int iterations;

        Console.WriteLine("Enter first imaginary coord: ");
        doubleNum.newIcoord = Convert.ToDouble(Console.ReadLine());

        Console.WriteLine("Enter second imaginary coord: ");
        doubleNum.newIcoord1 = Convert.ToDouble(Console.ReadLine());

        Console.WriteLine("Enter third imaginary coord: ");
        doubleNum.newIcoord2 = Convert.ToDouble(Console.ReadLine());

        Console.WriteLine("Enter first real coord: ");
        doubleNum.rCoord = Convert.ToDouble(Console.ReadLine());

        Console.WriteLine("Enter second real coord: ");
        doubleNum.rCoord1 = Convert.ToDouble(Console.ReadLine());

        Console.WriteLine("Enter third real coord: ");
        doubleNum.rCoord2 = Convert.ToDouble(Console.ReadLine());

        for (doubleNum.imagCoord = doubleNum.newIcoord; doubleNum.imagCoord >= -doubleNum.newIcoord1; doubleNum.imagCoord -= doubleNum.newIcoord2)
        {
            for (doubleNum.realCoord = -doubleNum.rCoord; doubleNum.realCoord <= doubleNum.rCoord1; doubleNum.realCoord += doubleNum.rCoord2)
            {
                iterations = 0;
                doubleNum.realTemp = doubleNum.realCoord;
                doubleNum.imagTemp = doubleNum.imagCoord;
                doubleNum.arg = (doubleNum.realCoord * doubleNum.realCoord) + (doubleNum.imagCoord * doubleNum.imagCoord);
                while ((doubleNum.arg < 4) && (iterations < 40))
                {
                    doubleNum.realTemp2 = (doubleNum.realTemp * doubleNum.realTemp) - (doubleNum.imagTemp * doubleNum.imagTemp) - doubleNum.realCoord;
                    doubleNum.imagTemp = (2 * doubleNum.realTemp * doubleNum.imagTemp) - doubleNum.imagCoord;
                    doubleNum.realTemp = doubleNum.realTemp2;
                    doubleNum.arg = (doubleNum.realTemp * doubleNum.realTemp) + (doubleNum.imagTemp * doubleNum.imagTemp);
                    iterations += 1;
                }
                switch (iterations % 4)
                {
                    case 0:
                        Console.Write(".");
                        break;
                    case 1:
                        Console.Write("o");
                        break;
                    case 2:
                        Console.Write("O");
                        break;
                    case 3:
                        Console.Write("@");
                        break;
                }
            }
            Console.Write("\n");
        }
        Console.ReadKey();




    }
  }
}
4

2 回答 2

3

我认为您应该使用结构来表示每个复数。然后,该结构可以包含将这些复数加、减、乘的函数:

例如。

struct Complex
{
    public double real;
    public double imag;

    public Complex(double r, double i)
    {
        real = r;
        imag = i;
    }

    public Complex add(Complex operand)
    {
        return new Complex(real + operand.real, imag + operand.imag);
    }

    public Complex multiply(Complex operand)
    {
        return new Complex(real * operand.real - imag * operand.imag, real * operand.imag + operand.real * imag);
    }
}

然后使用结构你可以做类似的事情

Complex c = new Complex( ...coordinate goes here... );
Complex z = new Complex(0,0);

// z -> z^2 + c
Complex result = z.multiply(z).add(c);

等等

您还可以将“sq”(数字平方)或“pow”(提高到给定的幂)或“arg”(在上面的代码中)添加到复数结构。天空是极限!请注意,这些函数不必返回另一个复数,例如“arg”将返回一个双精度数。

此外,如果您总是将两个复数(地图点和 z 值)组合在一起,您可以创建一个结构来保存两个复数:

struct MapPoint
{
    Complex c;
    Complex z;
}

等等。对我来说,将事物分组在逻辑上不可分割的结构或始终作为一个组工作的事物是有意义的。

于 2012-09-07T01:00:59.353 回答
1

只存储定义坐标(读取和虚部)所需的值而不存储任何临时值是有意义的。计算值也可以是属性,如下所示:

public struct MapPoint
{
    public double realCoord, imagCoord;
    public double realConst, imagConst;

    public MapPoint(double realConst, double imagConst)
        : this(realConst, imagConst, realConst, imagConst) { }

    public MapPoint(double realCoord, double imagCoord, double realConst, double imagConst)
    {
        this.realCoord = realCoord;
        this.imagCoord = imagCoord;
        this.realConst = realConst;
        this.imagConst = imagConst;
    }
    public double Argument // calculated property
    {
        get { return realCoord * realCoord + imagCoord * imagCoord; }
    }

    public MapPoint Iterate()
    {
        // Do the z = z^2+c thing

        return new MapPoint(
            realCoord * realCoord - imagCoord * imagCoord + realConst,
            2 * realCoord * imagCoord + realConst,
            realConst, imagConst);
    }
}

现在像这样使用这个结构:

void Main() {
    for( double y=...
      for( double x=...

        int iterations = 0;
        MapPoint point = new MapPoint(x, y);

        while (iterations < 40 || point.Argument < 4.0)
        {
            point = point.Iterate();
            iterations++;
        }

        switch (iterations % 4)
        {
            //...
        }
    ...
}

关键是所有计算都在结构内部完成,靠近存储信息的地方。这样,结构可以在其他地方重用,而无需再次重新编写计算块。此外,任何临时值在不需要时都会被丢弃,并且不会存储在重要值旁边。

请承诺阅读此处此处的结构,然后将上面的代码重新编写为您自己的代码。

于 2012-09-07T00:32:15.887 回答