在Delphi中编程拉丁方?

在Delphi中编程拉丁方?,delphi,pascal,Delphi,Pascal,我正在尝试制作一个拉丁方程序,该程序接受用户输入的正方形大小(例如,输入5将生成一个拉丁方5x5),然后将格式化后的正方形输出给用户 如果你不知道什么是拉丁方,或者想看看我设定的实际任务 我已经稍微编写了一些代码,但我在第一关就失败了。老师们没有提供帮助,你们是我唯一的希望 uses System.SysUtils; var // Variables // 2D array, size defined in main code Square: array of array o

我正在尝试制作一个拉丁方程序,该程序接受用户输入的正方形大小(例如,输入5将生成一个拉丁方5x5),然后将格式化后的正方形输出给用户

如果你不知道什么是拉丁方,或者想看看我设定的实际任务

我已经稍微编写了一些代码,但我在第一关就失败了。老师们没有提供帮助,你们是我唯一的希望

uses
  System.SysUtils;

var
  // Variables

  // 2D array, size defined in main code
  Square: array of array of integer;
  // Integer holding the square size
  SquareSize: integer;

begin
  // Introduction
  writeln('This program will generate a Latin Squar of a size designated by you.');
  // Ask for user input, receive and store in a variable
  write('Enter the size of the Latin Square (1 value): ');
  readln(SquareSize);
  // More user friendly garbage
  writeln('Latin Square size: ', SquareSize, ' x ', SquareSize, '.');

  // Calculations

  // Set size of the 2D array to user designated dimensions
  setlength(Square, SquareSize, SquareSize);

end.
在最后一行代码(setlength)之后,我想将新2D数组中的所有值设置为用户输入的数字。我想

除此之外,我不知道自己在做什么。

如果你想帮助我,请你尽量简单,让我能理解它

很抱歉,这是第一次在堆栈溢出上出错。

您给出的答案也给出了答案,请参见下面的代码

program LatinSquare;

{$APPTYPE CONSOLE}

type 
  TSquare = array of array of Integer;

procedure WriteLatinSquare(var Square: TSquare; N: Integer);
var
  X, Y: Integer;
begin
  { Allocate and fill the square array. }
  SetLength(Square, N, N);
  for Y := 0 to High(Square) do
    for X := 0 to High(Square[Y]) do
      Square[X, Y] := (Y + X) mod N + 1;

  { Display the Square array. }
  for Y := 0 to High(Square) do
  begin
    for X := 0 to High(Square[Y]) do
      Write(Square[X, Y]:3);
    Writeln;
  end;
  Writeln;
end;

var
  Square: TSquare;
  SquareSize: Integer;

begin
  SquareSize := 6;
  WriteLatinSquare(Square, SquareSize);
  Readln;
end.
正如链接所说:从
123456
开始,然后下一行按1移位,这样就变成
23456
,以此类推。。。这就是第一部分(使用
X
Y
循环)所做的:它填充正方形

当然,
Y+X
可以超过
0..5
的限制(稍后我添加了
1
),因此您使用
mod
来包装值,因此
6
变成
0
7
变成
1
,等等。实际上:

1st line: 0+0=0 -> 0, 0+1=1 -> 1, 0+2=2 -> 2, 0+3=3 -> 3, 0+4=4 -> 4, 0+5=5 -> 5
2nd line: 1+0=1 -> 1, 1+1=2 -> 2, 1+2=3 -> 3, 1+3=4 -> 4, 1+4=5 -> 5, 1+5=6 -> 0
3rd line: 2+0=2 -> 2, 2+1=3 -> 3, 2+2=4 -> 4, 2+3=5 -> 5, 2+4=6 -> 0, 2+5=7 -> 1
etc...
然后您添加1,因此得到的不是
012345
,而是
123456

例程的第二部分只是打印
正方形
数组

如果不需要保存正方形,可以通过一个部分完成:

procedure WriteMagicSquare2(N: Integer);
var
  X, Y: Integer;
begin
  for Y := 0 to N - 1 do
  begin
    for X := 0 to N - 1 do
      Write((Y + X) mod N + 1, ' ');
    Writeln;
  end;
  Writeln;
end;
输出(对于N=6):

您给出的答案也给出了答案,请参见下面的代码

program LatinSquare;

{$APPTYPE CONSOLE}

type 
  TSquare = array of array of Integer;

procedure WriteLatinSquare(var Square: TSquare; N: Integer);
var
  X, Y: Integer;
begin
  { Allocate and fill the square array. }
  SetLength(Square, N, N);
  for Y := 0 to High(Square) do
    for X := 0 to High(Square[Y]) do
      Square[X, Y] := (Y + X) mod N + 1;

  { Display the Square array. }
  for Y := 0 to High(Square) do
  begin
    for X := 0 to High(Square[Y]) do
      Write(Square[X, Y]:3);
    Writeln;
  end;
  Writeln;
end;

var
  Square: TSquare;
  SquareSize: Integer;

begin
  SquareSize := 6;
  WriteLatinSquare(Square, SquareSize);
  Readln;
end.
正如链接所说:从
123456
开始,然后下一行按1移位,这样就变成
23456
,以此类推。。。这就是第一部分(使用
X
Y
循环)所做的:它填充正方形

当然,
Y+X
可以超过
0..5
的限制(稍后我添加了
1
),因此您使用
mod
来包装值,因此
6
变成
0
7
变成
1
,等等。实际上:

1st line: 0+0=0 -> 0, 0+1=1 -> 1, 0+2=2 -> 2, 0+3=3 -> 3, 0+4=4 -> 4, 0+5=5 -> 5
2nd line: 1+0=1 -> 1, 1+1=2 -> 2, 1+2=3 -> 3, 1+3=4 -> 4, 1+4=5 -> 5, 1+5=6 -> 0
3rd line: 2+0=2 -> 2, 2+1=3 -> 3, 2+2=4 -> 4, 2+3=5 -> 5, 2+4=6 -> 0, 2+5=7 -> 1
etc...
然后您添加1,因此得到的不是
012345
,而是
123456

例程的第二部分只是打印
正方形
数组

如果不需要保存正方形,可以通过一个部分完成:

procedure WriteMagicSquare2(N: Integer);
var
  X, Y: Integer;
begin
  for Y := 0 to N - 1 do
  begin
    for X := 0 to N - 1 do
      Write((Y + X) mod N + 1, ' ');
    Writeln;
  end;
  Writeln;
end;
输出(对于N=6):


假设你在我的学校,这是我在同一本书上逐字逐句的作业。注意上面的代码,我将添加一点,拉丁方的大小应该由用户输入,因此在最后一段代码中将其更改为:

  var
  Square: TSquare;
  X, UserI, SquareSize: Integer;

begin
  X := 0;
  Writeln('type -1000 to stop the loop');
  repeat
    Writeln('What size square do you want?');
    readln(UserI);
    if UserI = -1000 then
    begin
      goto gotolable;
    end

    else
      SquareSize := UserI;
    WriteLatinSquare(Square, SquareSize);
    writeln ('Press enter to do another Latin square');
    readln;
  until X = 1;
gotolable:

假设你在我的学校,这是我在同一本书上逐字逐句的作业。注意上面的代码,我将添加一点,拉丁方的大小应该由用户输入,因此在最后一段代码中将其更改为:

  var
  Square: TSquare;
  X, UserI, SquareSize: Integer;

begin
  X := 0;
  Writeln('type -1000 to stop the loop');
  repeat
    Writeln('What size square do you want?');
    readln(UserI);
    if UserI = -1000 then
    begin
      goto gotolable;
    end

    else
      SquareSize := UserI;
    WriteLatinSquare(Square, SquareSize);
    writeln ('Press enter to do another Latin square');
    readln;
  until X = 1;
gotolable:

对于y:=0到高(平方)do FillChar(平方[y],长度(平方[y]),SomeValueLength
应该乘以
SizeOf(Integer)
来获得一行中的字节数。除了
0
,什么是
SomeValue
?请注意,dynarray由
SetLength
填充为零。@Rudy,我认为OP希望用给定的值(
SomeValue
)初始化整个数组。我个人会填充平方[y][0],而不是平方[y]?
对于y:=0到高(平方)dofillchar(平方[y],长度(平方[y]),SomeValueLength
应该乘以
SizeOf(Integer)
来获得一行中的字节数。除了
0
,什么是
SomeValue
?请注意,dynarray是由
SetLength
填充的零。@Rudy,我认为OP想要用给定的值(
SomeValue
)初始化整个数组。我个人会填充平方[y][0],而不是平方[y]?当我尝试使用它时,我在WriteMagicSquare(6)上得到一个错误
[dcc32 Error]ProjectName.dpr(34):E2033类型的实际和形式var参数必须相同
另外,我想问一下,由于我是初学者,您能否快速完成try WriteMagicSquare(6)中的内容;除了E:Exception do Writeln(E.ClassName,“:”,E.Message);简单地说是什么意思?另外,type和var之间有什么区别?@ihavenoidawhatimdoding:这就是您在现场修改代码所得到的结果。;-)我会更新代码。
try..except
部分执行异常处理。它是在较新版本的Delphi中自动生成的。你可以忽略它。我将删除它。您应该知道
type
var
之间的区别。前者声明一个类型(开始一个类型部分),我在其中声明正方形的类型。第二个启动var部分,例如程序中的X和Y以及程序中的平方。X和Y的类型是整数,正方形的类型是TSquare(在顶部附近声明)。@ihavenoidawhatimdo:了解你在做什么。我想这是家庭作业,所以我可能已经“帮助”你太多了。这样你什么也学不到。阅读我提到的章节并学习。不会花很长时间的。下一课,你可以