Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.06.2014, 14:29   #1
Леон2110
Пользователь
 
Регистрация: 23.06.2014
Сообщений: 13
По умолчанию Задача с сортировкой (Delphi). Дано n точек на плоскости. Указать (n-1)-звенную несамопересекающуюся незамкнутую ломаную

Здравствуйте, подскажите как правильно это реализовать, вот задание:

Дано n точек на плоскости. Указать (n-1)-звенную несамопересекающуюся незамкнутую ломаную, проходящую через все эти точки. (Соседним отрезкам ломаной разрешается лежать на одной прямой.) Обеспечить число действий порядка n*log n.

Указание. Упорядочим точки по x-координате, а при равных x-координатах - по y-координате. В таком порядке и можно проводить ломаную.

С одной стороны все понятно,
1. создаю массив, наполняю его координатами (тут пока не совсем понимаю как их наполнять ведь в координатах будет две цифры по х и по у)
2. отсортировать массив по х это понятно, но как подставить если по х одинаковые значения, чтобы смотрелось на вторую координату y.
3. далее уже с упорядоченного массива можно построить график и прочертить ломаную.

Пока все проблемы, что непонятно как быть со второй координатой? есть мысль пузырьком упорядочить, но как туда подставить проверку на -y координаты если по -х совпадут значения.
Леон2110 вне форума Ответить с цитированием
Старый 23.06.2014, 20:20   #2
BHMJ(G)
 
Регистрация: 23.06.2014
Сообщений: 6
По умолчанию

Надо создать массив структур и отсортировать его qsort'ом. В функции сравнения сначала сравнивать X'ы, а при их совпадении -- Y'и. По отсортированному таким образом массиву координат легко строится ломаная.

Кстати, интересно было бы модифицировать алгоритм так, чтобы по заданному набору случайных точек строилась ломаная, закрученная по спирали, от краев области к центру.
BHMJ(G) вне форума Ответить с цитированием
Старый 23.06.2014, 21:33   #3
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,577
По умолчанию

Модифицировать можно, но эффективность упадет. Зачем нужны эти спирали вообще, что за извращения?

Упадет потому, что надо будет получать точки выпуклой оболочки, соединять их, получать новую оболочку и т.п. Время будет вроде бы тоже n*log(n), но лишних операций будет достаточно. Достаточно и непонятно из за чего вся эта свистопляска.
rrrFer вне форума Ответить с цитированием
Старый 23.06.2014, 22:18   #4
BHMJ(G)
 
Регистрация: 23.06.2014
Сообщений: 6
По умолчанию

Спираль -- это усложнённая вариация задачи. Как я и написал, просто интересно было бы её решить, почему сразу "извращения"? В результате работы программы, решающей исходную задачу, область будет "заштрихована" линиями, идущими более или менее вертикально, а в моей вариации получится красивая спиралька. Попробую сделать, отпишусь по результатам.
BHMJ(G) вне форума Ответить с цитированием
Старый 24.06.2014, 23:40   #5
Леон2110
Пользователь
 
Регистрация: 23.06.2014
Сообщений: 13
По умолчанию

Спасибо за ответы, но не получается пока. *(плохо с программированием)

К примеру сделал массив (пока без рандома или ручного ввода):
Const
po : Array[0..4] Of TPoint = ((x:20; y:40),(x:40; y:40),(x:30; y:10),(x:50; y:20),(x:30; y:20));


Вывожу на форме по нажатии кнопки так:
procedure TForm1.btn1Click(Sender: TObject);
begin
Form1.Canvas.Polygon(po);
end;

Помогите как его упорядочить перед выводом.
Леон2110 вне форума Ответить с цитированием
Старый 25.06.2014, 12:13   #6
BHMJ(G)
 
Регистрация: 23.06.2014
Сообщений: 6
По умолчанию

Используйте любой алгоритм сортировки (ищите на этом сайте по запросу "сортировка массива delphi"). В том месте, где сравниваются элементы массива, сначала сравнивайте x координаты, при их равенстве -- у координаты.

Например при пузырьковой сортировке код, сравнивающий элементы будет такой:

Код:
if (po[i].x > po[j].x) or ( (po[i].x = po[j].x) and (po[i].y > po[j].y) ) then begin
  ; меняем местами элементы
end;
BHMJ(G) вне форума Ответить с цитированием
Старый 25.06.2014, 14:22   #7
Леон2110
Пользователь
 
Регистрация: 23.06.2014
Сообщений: 13
По умолчанию

Нашел такой пример:

Код:
//кнопка заполняет мемо 20-ю случайными числами
procedure TForm1.Button2Click(Sender: TObject);
begin
 Memo1.Clear;
for i:=0 to 19 do
begin
 a[i]:=Random(20) ;
   Memo1.Lines.Add(IntToStr(a[i]))
end;
end;
Код:
//процедура сортировки пузырьком
procedure BubbleSort( var a: array of integer; min, max: Integer);
var
i, j, tmp: integer;
begin
for i:=min to max do
for j:=min to max-i do
if A[j]>A[j+1] then
begin
tmp:=A[j];
A[j]:=A[j+1];
A[j+1]:=tmp;
end;
end;
Код:
//кнопка вызывает процедуру сортировки и помещает отсортированные данныее в мемо 2
procedure TForm1.Button4Click(Sender: TObject);
begin
BubbleSort(a,0,high(a));
for i:=0 to 19 do
begin
   Memo2.Lines.Add(IntToStr(a[i]))
end;
end;
Все работает, вот только это немного другой пример, тут массив с целочисленными данными, а у меня раньше был массив TPoint с двумя координатами, подскажите пожалуйста как правильно сделать, чтобы в этом массиве было по 2 координаты.
Леон2110 вне форума Ответить с цитированием
Старый 25.06.2014, 18:42   #8
BHMJ(G)
 
Регистрация: 23.06.2014
Сообщений: 6
По умолчанию

В BubbleSort у параметра a поменяйте тип вместо "массив целых чисел" сделайте "массив TPoint'ов". Алгоритм остаётся тот же, только вместо сравнения чисел сравнивайте точки, вернее их координаты, код сравнения я уже приводил. Аналогично, вместо обмена двух чисел между ячейками массива надо обменивать структуры.
BHMJ(G) вне форума Ответить с цитированием
Старый 25.06.2014, 20:14   #9
Леон2110
Пользователь
 
Регистрация: 23.06.2014
Сообщений: 13
По умолчанию

так немного вроде получилось, в мемо1 я записал координаты:
x:20; y:40
x:40; y:30
x:30; y:50
x:50; y:20
x:30; y:20
x:20; y:60
x:40; y:30
x:30; y:40
x:50; y:30
x:30; y:30
x:20; y:50
x:40; y:10
x:30; y:10
x:50; y:20
x:30; y:20
x:20; y:30
x:40; y:50
x:30; y:20
x:50; y:30
x:30; y:10

В коде я заменил массив на TPoint, вставил код для сравнения, но еще проблемы есть, как быть с этими строками перемещения элементов массива и передачи элементов к вызову процедуры:

Код:
var
  Form1: TForm1;
  i:integer;

implementation

{$R *.dfm}

//процедура сортировки
procedure BubbleSort( var a: array of TPoint; min, max: Integer);
var
i, j, tmp: integer;
begin
for i:=min to max do
for j:=min to max-i do
//if A[j]>A[j+1] then  begin
if (A[i].x > A[j].x) or ( (A[i].x = A[j].x) and (A[i].y > A[j].y) ) then begin
tmp:=A[j];
A[j]:=A[j+1];
A[j+1]:=tmp;
end;
end;

//кнопка запускающая процедуру сортировки и вывод в мемо2
procedure TForm1.Button4Click(Sender: TObject);
begin
BubbleSort(a,0,high(a));
for i:=0 to 19 do
begin
   Memo2.Lines.Add(IntToStr(a[i]))
end;
end;

end.
Леон2110 вне форума Ответить с цитированием
Старый 26.06.2014, 14:02   #10
Леон2110
Пользователь
 
Регистрация: 23.06.2014
Сообщений: 13
По умолчанию

Теперь вот как:

Код:
var
  Form1: TForm1;
  i:integer;
  a: array[0..6] of TPoint = ((x:10; y:20),(x:20; y:30),(x:30; y:40),(x:40; y:50),(x:50; y:60),(x:60; y:70),(x:70; y:80));
implementation

{$R *.dfm}

//Процедура сортировки
procedure BubbleSort( var a: array of TPoint; min, max: Integer);
var
i, j: integer;
tmp: TPoint;
begin
for i:=min to max do
for j:=min to max-i do
if (A[i].x > A[j].x) or ( (A[i].x = A[j].x) and (A[i].y > A[j].y) ) then begin
tmp:=A[j];
A[j]:=A[j+1];
A[j+1]:=tmp;
end;
end;

//кнопка запускающая процедуру сортировки и вывод в мемо2
procedure TForm1.Button4Click(Sender: TObject);
begin
BubbleSort(a,0,high(a));
for i:=0 to 6 do
begin
  Memo2.Lines.Add (IntToStr(A[i].x)+ ','+ IntToStr(A[i].y)  );
end;
end;

end.
Вот как работает сортировка, из уже отсортированных данных делает вот что:
Координаты в массиве / вывод в мемо2
x:10; y:20 / 10,20
x:20; y:30 / 40,50
x:30; y:40 / 20,30
x:40; y:50 / 30,40
x:50; y:60 / 50,60
x:60; y:70 / 60,70
x:70; y:80 / 70,80

Подскажите, что еще не так в коде?
Леон2110 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
На плоскости задано множество точек. Определить все тройки точек, которые являются вершинами прямоугольного треугольника Олечка12 Помощь студентам 11 22.04.2014 19:56
Даны координаты точек n на плоскости. Найти номера двух точек, расстояние между которыми наибольшее. getredtm Помощь студентам 3 01.07.2013 01:47
Delphi. На плоскости заданы n точек своими координатами.Построить квадрат Allexey Помощь студентам 4 18.06.2013 13:46
Даны координаты n точек на плоскости. Найти номера двух точек, расстояние между которыми наибольшее. Viwwna Паскаль, Turbo Pascal, PascalABC.NET 2 19.11.2011 06:33
определить радиус и центр окружности, на кот. лежит наиб.число точек заданного на плоскости мн-ва точек) kcю Помощь студентам 0 17.11.2009 19:50