【问题标题】:Delphi - Sorting real numbers in high, low, high, low orderDelphi - 按高、低、高、低顺序对实数进行排序
【发布时间】:2013-05-12 13:53:49
【问题描述】:

假设我有数据 1,2,3,4,5,6

我想对这些数据进行排序以便输出 6 1 5 2 4 3

这样,数字被匹配,因此低数字与高数字配对

我会使用归并排序将其按数字顺序排序,然后拆分列表并根据此条件匹配它们吗?

我正在尝试对从数据文件中读取的字符串网格中的实数数据进行排序;我有一个按数字顺序对这些数据进行排序的工作程序,但我不确定如何对其进行编码,以便按照高、低、高、低进行排序

这是我的网格排序代码

procedure TForm1.SortGrid(Grid: TStringGrid; const SortCol: Integer;
//sorting the string grid
  const datatype: Integer; const ascending: boolean);
var
  i: Integer;
  tempgrid: TStringGrid;
  list: array of Integer;
begin
  tempgrid := TStringGrid.create(self);
  with tempgrid do
  begin
    rowcount := Grid.rowcount;
    ColCount := Grid.ColCount;
    fixedrows := Grid.fixedrows;
  end;
  with Grid do
  begin
    setlength(list, rowcount - fixedrows);
    for i := fixedrows to rowcount - 1 do
    begin
      list[i - fixedrows] := i;
      tempgrid.rows[i].assign(Grid.rows[i]);
end;
   Mergesort(Grid, list, SortCol + 1, datatype, ascending);


      for i := 0 to rowcount - fixedrows - 1 do
      begin
    rows[i + fixedrows].assign(tempgrid.rows[list[i]])
      end;
      row := fixedrows;
    end;
    tempgrid.free;
    setlength(list, 0);
  end;

【问题讨论】:

  • 如果你想按高-低-高-低的顺序对数字进行排序,你不应该从初始数据中得到 6 1 5 2 4 3 吗?
  • 我只是写得很快,没有任何想法,但是是按这个顺序写的
  • 我回滚了你的问题。原来的问题很好,已经回答了。
  • 如何处理重复的数字?

标签: delphi sorting pascal


【解决方案1】:

首先,使用您想要的任何算法对数字进行降序排序(我在示例中使用了冒泡排序)

那么,如果数组中有 n 个元素:

  • 设置一个从 1 到 (n div 2) 的计数器
  • 取出最后一个元素并将其存储在临时变量中 (tmp)
  • 将所有元素向右移动一位,从 (counter - 1) * 2 + 1 开始。这将覆盖最后一个元素,但您将其存储在 tmp var
  • array[(counter - 1) * 2 + 1] 元素设置为 tmp
  • 结束计数器

这样,您可以有效地从数组中取出最后一个元素并将其插入到 1、3、5... 位置,直到插入数组元素的后半部分。

示例代码:

procedure Sort(var AArray: array of Double);
var
  C1, C2: Integer;
  tmp   : Double;
  pivot : Integer;
begin
  for C1 := Low(AArray) to High(AArray) - 1 do
    for C2 := C1 + 1 to High(AArray) do
      if AArray[C1] < AArray[C2] then
      begin
        tmp := AArray[C1];
        AArray[C1] := AArray[C2];
        AArray[C2] := tmp;
      end;

  pivot := Length(AArray) div 2;
  for C1 := 1 to pivot do
  begin
    tmp := AArray[High(AArray)];
    for C2 := High(AArray) downto (C1 - 1) * 2 + 1 do
      AArray[C2] := AArray[C2 - 1];
    AArray[(C1 - 1) * 2 + 1] := tmp;
  end;
end;

【讨论】:

  • 我将如何为字符串网格中的记录执行此操作
  • 您应该使用网格数据填充动态数组并将其传递给 Sort() 函数,然后清除网格并使用 Sort() 返回的数据重新填充它。
  • 对不起,我不知道该怎么做
  • 您是否将数据存储在字符串网格中?这通常是个坏主意。
  • 我认为他目前的问题比他存储数据的方式更大:)
【解决方案2】:

根据您上面提供的示例数据,我假设输入数组是预先排序的。

[请注意,我手头没有编译器,因此您必须运行它并查看它是否有效——可能需要稍作调整。]

procedure SerratedSort(var AArray: array of Double);
var
  Length1: Integer;
  Index1: Integer;
  Temp1: Double;
begin
  Length1 := Length(AArray);
  Index1 := 0;
  while Index1 < Length1 do begin
    Temp1 := AArray[Length1 - 1];
    System.Move(AArray[Index1], AArray[Index1 + 1], (Length1 - Index1 + 1) * SizeOf(Double));
    AArray[Index1] := Temp1;
    Index1 := Index1 + 2;
  end;
end;

这是它(应该)如何逐步工作

输入数组:123456

  • 索引1:0

温度 1 := 6

System.Move: 112345

数组:612345

  • 索引1:2

温度 1 := 5

System.Move: 612234

数组:615234

  • 索引1:4

温度 1 := 4

System.Move: 615233

数组:615243

输出数组:615243


对于一个记录结构,比如 TPerson,应该是这样的:

procedure SerratedSort(var A: array of TPerson);
var
  s: Integer;
  i: Integer;
  t: TPerson;
begin
  s := Length(A);
  i := 0;
  while i < s do begin
    t := A[s - 1];
    System.Move(A[i], A[i + 1], (s - i + 1) * SizeOf(TPerson));
    A[i] := t;
    i := i + 2;
  end;
end;

【讨论】:

  • 首先,IMO 使用 Grid 本身对数据进行排序是一种草率的编程。您应该使用中间数组。其次,请不要一直改变问题。
  • 我不是为了效率,这是我唯一知道的方法,因为我没有编程经验
  • 这里没有人谈论效率。
  • 在定义问题时,缺乏编程经验并不是缺乏能力的借口。您的第一次尝试是正确的,因为它要求使用 sn-p 算法解决一个可概括的问题。现在你已经把它变成了“为我编写程序”。请不要这样做。你得到了解决方案。使其适应您的 TPerson 记录结构——或使用该 TPerson 数组中的索引。
【解决方案3】:

按升序对数据进行排序。然后使用以下索引选择值:0, n-1, 1, n-2, ....

在伪代码中,算法如下所示:

Sort;
lo := 0;
hi := n-1;
while lo<=hi do
begin
  yield lo;
  inc(lo);
  if lo>hi then break;
  yield hi;
  dec(hi);
end;

【讨论】:

  • 我忘了说我的编程知识非常少,所以我不知道该怎么做
  • @Nathan:那么你需要有人为你编写完整的程序。
【解决方案4】:

演示上述解决方案的示例程序:

program Project1;

{$APPTYPE CONSOLE}

const
  Count = 12;
type
  TValues = array[0..Count - 1] of Double;
const
  Input: TValues = (1,2,4,9,13,14,15,23,60,100,101,102);
var
  I: Integer;
  Output: TValues;

procedure ShowValues(Caption: String; Values: TValues);
var
  I: Integer;
begin
  Write(Caption);
  for I := 0 to Count - 2 do
    Write(Round(Values[I]), ', ');
  WriteLn(Round(Values[Count - 1]));
end;

begin
  if Odd(Count) then
    WriteLn('Cannot compute an odd number of input values')
  else
  begin
    WriteLn('Program assumes sorted input!');
    ShowValues('Input:  ', Input);
    for I := 0 to (Count div 2) - 1 do
    begin
      Output[2 * I] := Input[I];
      Output[2 * I + 1] := Input[Count - 1 - I];
    end;
    ShowValues('Output: ', Output);
  end;
  ReadLn;
end.

【讨论】:

  • 满足奇数长度的数组很简单
猜你喜欢
  • 2011-12-08
  • 1970-01-01
  • 2020-09-04
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
相关资源
最近更新 更多