九宫格数值分组

解答网友问题, 记录如下:

原始数据

11,38
11,36
11,37
11,39
11,40
12,34
12,35
12,36
12,37
12,38
12,40
13,33
13,34
13,35
13,36
13,40
14,32
14,33
14,34
14,35
14,40
15,31
15,32
15,33
15,34
15,40
16,30
16,31
16,32
16,39
17,29
1,1
2,0
2,1
2,3
2,4
3,1


处理代码

unit Unit15;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, rtlconsts;

type
  TForm15 = class(TForm)
    btn1: TButton;
    mmo1: TMemo;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form15: TForm15;

implementation

type
  TCustomGroup = class
  private
    type
    TRes = record
      X, Y, Sum : integer;
    end;
    PRes = ^TRes;
  private
    FArr : array of TRes;

    FFileName : string;
    FCount : integer;

    procedure Fill;
    procedure FillRes(const Value : string; ARes : PRes);
    procedure Sort;
    procedure Output(ALst : TStrings);
  public
    constructor Create(const AFileName : string);
    function Exec(ALst : TStrings) : Boolean;
  end;
{$R *.dfm}

procedure TForm15.btn1Click(Sender: TObject);
begin
  mmo1.Clear;

  with TCustomGroup.Create('c:\test.txt') do
  try
    if Exec(mmo1.Lines) then
    begin
      mmo1.SelStart := 0;
      mmo1.SelLength := 0;

      ShowMessage('Ok')
    end
    else
      ShowMessage('Error');
  finally
    Free;
  end;
end;

{ TCustomGroup }

constructor TCustomGroup.Create(const AFileName: string);
begin
  FFileName := AFileName;
end;

function TCustomGroup.Exec(ALst: TStrings): Boolean;
begin
  Result := false;
  try
    Fill;
    Sort;
    Output(ALst);

    Result := True;
  except on E: Exception do
    Result := false;
  end;
end;

procedure TCustomGroup.Fill;
var
  i: Integer;
  sLst : TStringList;
begin
  sLst := TStringList.Create;
  try
    sLst.LoadFromFile(FFileName);

    if sLst.Count < 2 then
      Exit;

    FCount := sLst.Count;
    SetLength(FArr, FCount);

    for i := 0 to sLst.Count - 1 do
    begin
      FillRes(sLst.Strings[i], @FArr[i]);
    end;
  finally
    slst.Free;
  end;
end;

procedure TCustomGroup.FillRes(const Value: string; ARes: PRes);
var
  idx : integer;
begin
  idx := Pos(',', value);
  ARes.X := StrToInt(Copy(Value, 1, idx - 1));
  ARes.Y := StrToInt(Copy(Value, idx + 1, Length(Value)));
  ARes.Sum := ARes.X + ARes.Y;
end;

procedure TCustomGroup.Output(ALst : TStrings);
var
  vRes : TRes;

  procedure Extract(const idx: integer);
  begin
    if (idx < 0) or (idx >= FCount) then
      raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);

    ALst.Add(Format('%d,%d', [FArr[Idx].X, FArr[Idx].Y]));
    Dec(FCount);

    if Idx <> FCount then
    begin
      vRes := FArr[Idx];
      Move(FArr[Idx + 1], FArr[Idx], (FCount - Idx) * SizeOf(TRes));
      FillChar(FArr[FCount], SizeOf(TRes), 0);
    end;
  end;
var
  idx, X, Y : integer;
begin
  repeat
    idx := Low(FArr);
    vRes := FArr[idx];

    while FCount > idx do
    begin
      X := Abs(FArr[idx].x - vRes.x);
      Y := Abs(FArr[idx].y - vRes.y);

      if (X in [0, 1]) and (Y in [0, 1]) then
      begin
        Extract(idx);
      end
      else
      begin
        inc(idx);
      end
    end;
    ALst.Add('');
  until FCount = 0;
end;

procedure TCustomGroup.Sort;
var
  i, j : integer;
  vRes : TRes;
begin
  for i := low(FArr) to High(FArr) - 1 do
  begin
    for j := i + 1 to High(FArr) do
    begin
      if FArr[i].X > FArr[j].X then
      begin
        vRes := FArr[i];
        FArr[i] := FArr[j];
        FArr[j] := vRes;
      end
      else
      if (FArr[i].X = FArr[j].X) and (FArr[i].Y > FArr[j].Y) then
      begin
        vRes := FArr[i];
        FArr[i] := FArr[j];
        FArr[j] := vRes;
      end;
    end;
  end;
end;

end.


处理结果

1,1
2,0
2,1
3,1

2,3
2,4

11,36
11,37
11,38
11,39
11,40
12,40
13,40
14,40
15,40
16,39

12,34
12,35
12,36
12,37
12,38

13,33
13,34
13,35
13,36
14,35
15,34

14,32
14,33
14,34
15,33
16,32

15,31
15,32
16,31

16,30
17,29


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值