Помощь - Поиск - Пользователи - Календарь
Полная версия: Как правильно отсортировать двумерный массив?
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Delphi
Narcisa
Такая, вроде бы банальная задачка: как отсортировать двумерный массив в Дэлфи? Но "чем только я ее ни пробовала" .... mega_chok.gif
Вобще задача такая: нужно отсортировать так, чтобы максимальный элемент оказался в одном углу, и так по убывающей числа бы в матрице шли в другой угол. Так получается, когда сортируешь матрицу 2 раза: сначала по строкам, затем - по столбцам (или наоборот).
Вот только мне не удается даже 1 раз 2-мерный массив отсортировать blink.gif , не то что 2 раза... wacko.gif
Перепробовала много способов и вариантов, а результат один:либо просто все перетасовывается, либо половина чисел заменяется "0"-ми, или исчезает один из элементов, а все остальное сортируется .... Можно просто застрелиться, когда ты новичек в этом деле mega_chok.gif wink.gif

Помогите пожалуйста!!
Внизу последнее из моих усилий, но тоже не работает sad.gif
Там сначала идет вывод в StringGrid1, затем в StringGrid2 выводятся мах значения, а в StringGrid3 надо расположить отсортированный массив...

Цитата

procedure TForm1.Button1Click(Sender: TObject);
var
i,j,m,t,c:integer;
begin
randomize;
for i:=1 to 5 do
for j:=1 to 5 do
begin
mass [i,j]:=random(21);
StringGrid1.cells[j-1,i-1]:=inttostr(mass[i,j]);
end;
for i:=1 to 5 do
begin
max[i]:=mass[i,1];
for j:=1 to 5 do
begin
if max[i]<mass[i,j] then begin
max[i]:=mass[i,j];
end;

end;
end;
for i:=1 to 5 do
stringgrid2.Cells[0,i-1]:=inttostr(max[i]);

for i:=1 to 5 do
begin
for j:=1 to 5 do
begin
a[j]:=mass[i,j];
end;
if j=5 then
begin
for t:=1 to 5 do
if a[t]<a[t+1] then
begin
c:=a[t];
a[t]:=a[t+1];
a[t+1]:=c;
end;
end;
for m:=1 to 5 do
stringgrid3.Cells[m-1,i-1]:=inttostr(a[i]);
end;
end;
end.
мисс_граффити
самый простой вариант: "разворачиваешь" двумерный в одномерный (хотя бы мысленно), сортируешь и опять "сворачиваешь".
это если тебе нужно получить, например, такой массив:
1 2 3 4
5 6 7 8
А сортировка по строкам, а потом по столбцам дает несколько иной результат. Ну например:
0 0 2 2 4
3 3 3 4 5
3 4 5 6 6
как видишь, и строки, и столбцы отсортированы.
Смотри - какой из них тебе нужен.
klem4
Если массив очень большой, то создание еще такого же по размеру может быть просто невозможно ... Вот такой вариант могу предложить:

const
  n = 3;
type
  TMx = array [1..n, 1..n] of Integer;


procedure SortMatrix(var mx: TMx);
var
  i, j, k, l, T: Integer;
begin
  for i := 1 to n do
   for j := 1 to n do
    for k := i to n do begin
      if k = i then l := j + 1
       else l := 1;
      while (l <= n) do begin
        if mx[i, j] > mx[k, l] then begin
          T := mx[i, j];
          mx[i, j] := mx[k, l];
          mx[k, l] := T;
        end;
        inc(l);
      end;
    end;
end;
мисс_граффити
klem4, а кто говорил про еще один такой же?
и все-таки хотелось бы узнать, какой результат Narcisa стремится получить...
klem4
Ну а как ты еще его развернешь ? Если только действительно в уме smile.gif))))

{$mode delphi}
uses crt;

const
  n = 5;

type
  TMx  = array [1..n, 1..n] of Integer;
  TAr  = array [1..n*n] of Integer;

function CreateMatrix: TMx;
var
  i, j: Integer;
begin
  randomize;
  for i := 1 to n do
   for j := 1 to n do
     result[i, j] := random(12);
end;

procedure PrintMatrix(const mx: TMx);
var
  i, j: Integer;
begin
  for i := 1 to n do begin
    writeln;
    for j := 1 to n do
     write(mx[i, j]:3);
  end;
  writeln;
end;

procedure SortMatrix(var ar: TAr);
var
  i, j, T: Integer;
begin
  for i := n*n downto 2 do
   for j := 1 to i - 1 do
    if ar[j] > ar[j + 1] then begin
      T := ar[j];
      ar[j] := ar[j+1];
      ar[j + 1] := T;
    end;
end;

var
  mx: TMx;
  ar: TAr absolute mx;

begin
  clrscr;

  mx := CreateMatrix;

  PrintMatrix(mx);

  SortMatrix(ar);

  PrintMatrix(mx);

  readln;
end.

мисс_граффити
именно что в уме... какая разница, что делфи его считает двумерным... по сути - просто сравнивать последний в строке элемент с первым в следующей строке.
klem4
Мм что-то я тебя не очень понимаю, покажи что ты имеешь в виду.
Тут еще одна идея у меня родилась, попозже попробую сделать.
мисс_граффити
ну... грубо говоря, вот так.
for k:=1 to 25 do //до то есть до n*n - размерность массива
begin
j:=1;
i:=1;
repeat
  if j>5 then //если элемент последний в строке
    begin
    if mas[i,j]>mas[i+1,1] then //сравниваем его с первым следующей строки
      begin
      vspom:=mas[i,j];
      mas[i,j]:=mas[i+1,1];
      mas[i+1,1]:=vspom;
      end;
    i:=i+1; //переходим на работу со следующей строкой
    j:=1; //с первого элемента
    end
  else //если не последний в строке
    begin
    if (mas[i,j]>mas[i,j+1]) then //сравниваем со следующим по строке
      begin
      vspom:=mas[i,j];
      mas[i,j]:=mas[i,j+1];
      mas[i,j+1]:=vspom;
      end;
    j:=j+1; //переходим на следующий по строке
    end;
until (i=6);//пока не кончатся строки
end;

в результате получается массив вида
1 2 3 4
5 6 7 8
volvo
blink.gif А, простите, зачем Absolute? Что, нельзя привести тип одного массива к другому?

var
  mx: TMx;
 //  ar: TAr absolute mx;

begin
  clrscr;
  mx := CreateMatrix;
  PrintMatrix(mx);

  SortMatrix(TAr(mx)); // <--- Вот так

  PrintMatrix(mx);
  readln;
end.
Размеры-то совпадают идеально...
klem4
А как вам такой вариант:

{$mode delphi}
uses crt;
const
  n = 5;
type
  TMx  = array [1..n, 1..n] of Integer;

function CreateMatrix: TMx;
var
  i, j: Integer;
begin
  randomize;
  for i := 1 to n do
   for j := 1 to n do
     result[i, j] := random(12);
end;

procedure PrintMatrix(const mx: TMx);
var
  i, j: Integer;
begin
  for i := 1 to n do begin
    writeln;
    for j := 1 to n do
     write(mx[i, j]:3);
  end;
  writeln;
end;

procedure Sort(var mx: TMx);
var
  i, j: ^Integer;
  T: Integer;
begin
  // можно применить любой метод сортировки одномерных массивов
  i := @mx[1, 1];
  while (Integer(i) <= Integer(@mx[n, n]) - 1) do begin
    j := i + 1;
    while (Integer(j) <= Integer(@mx[n, n])) do begin
      if i^ > j^ then begin
        T := i^;
        i^ := j^;
        j^ := T;
      end;
      inc(j);
    end;
    inc(i);
  end;
end;

var
  mx: TMx;
begin
  clrscr;
  mx := CreateMatrix;
  PrintMatrix(mx);
  Sort(mx);
  PrintMatrix(mx);
  readln;
end.
мисс_граффити
По-моему, Narcisa давно испугалась и убежала.
Narcisa
Цитата
По-моему, Narcisa давно испугалась и убежала.

неее smile.gif просто возможности нету часто в интернет выходить dry.gif а так - мы трудностей не боимся!! yes2.gif разве что если массивов иногда wacko.gif

как я поняла из своего задания, результат должен быть примерно таким:
9 8 4 3
7 7 3 2
5 4 2 1
3 2 2 1
Ну, что-то типа этого...
Или может действительно змейкой? mega_chok.gif
Вобщем, чем больше способов знаем, тем лучше good.gif Большое спасибо за советы!!! give_rose.gif
klem4
Результат должен быть совсем не таким blink.gif

Вот если у нас на входе матрица:

9 8 4 3
7 7 3 2
5 4 2 1
3 2 2 1

то на выходе

1 1 2 2
2 2 3 3
3 4 4 4
7 7 8 9
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.