Forum Webscript.Ru

Программирование => Perl => Тема начата: commander от 08 Сентября 2004, 14:39:40

Название: Сдвиг сортировки...
Отправлено: commander от 08 Сентября 2004, 14:39:40
Задача следующая:
Имеем строку произвольной длинны с элементами вида "a:b" где а - индекс, b - индекс сортировки... :
"34:2,56:4,65:3,675:1,69:0"

Задача элементу ($id) изментить индекс сортировки на единицу в зависимоти от условия ($order=up или $order=down);
Моя спешная реализация:
---------------------------------------------------------------------------------#!/usr/bin/perl -w
use strict;
#исходные данные.
my $var="34:2,56:4,65:3,675:1,69:0";
my $id=56;
my $order="down";
#вызов функции order
$var=order($var, $id, $order);
print "$var\\n\\n";
#вывод и сортировка хеш массива
my @arr=split(",", $var);
my $Data;
for (my $NI=0; $NI<=$#arr; $NI++)
{
($Data->[$NI]{\'id\'}, $Data->[$NI]{\'order\'})=split(":", $arr[$NI]);
}
$Data=[ sort {$a->{order}<=>$b->{order}} @$Data ];
my $NI=0;
while ($Data->[$NI])
{
print "id=".$Data->[$NI]{\'id\'}."\\n";
$NI++
}

#конец вывода
sub order    #функция сдвига сортировки
{
my ($var, $id, $order)=@_;
#определения максимального элемента
my @arr=split(",", $var);
my @arr_order;
my$i=0;
for my $el(@arr)
{
my ($id, $o)=split(":", $el);
$arr_order[$i]=$o;
$i++
}
@arr_order=sort {$b <=>$a} @arr_order;
my $max_elem=$arr_order[0];
###################################
#непосредственный сдвиг
my $var_1=$var;
$var=~/($id:)([0-9])/g;
my $ord=$2;
my $ord_old=$2;
if ($order eq "up")
{
if ($ord==0)  #проверка на ноль
{
return $var;
exit;
}
else
{$ord--}
}
elsif ($order eq "down")
{
if ($ord==$max_elem) #проверка на максимальный элемент
{
return $var;
exit;
}
else
{$ord++}
}
$var_1=~/([0-9]+)(:$ord)/g;
my $id_2=$1;
$var=~s/($id:[0-9]+)/$id:$ord/g;
$var=~s/($id_2:[0-9]+)/$id_2:$ord_old/g;
return $var;
}
---------------------------------------------------------------------------------

есть идеи по уменьшению объема кода?
Название: Сдвиг сортировки...
Отправлено: commander от 08 Сентября 2004, 14:43:42
блин...  ну вообщем смайлик это двоеточие ":" и скобка ")"
Название: Сдвиг сортировки...
Отправлено: Phoinix от 08 Сентября 2004, 15:40:53
commander

Наворотил, млин...

По порядку:

#определения максимального элемента
my $max_elem = \'1\';
my @arr=split(/[\\,\\:]/, $var);
for (my $i = 1; $i <= @arr; $i+=2) {
$max_elem = $arr[$i] if $arr[$i] > $max_elem;
}

Хотя вообще проще сделать примерно так:

sub order
{
my ($var, $id, $order)=@_;
$var=~/$id\\:([0-9]+)/g;
my $ord = $1;
my $ord_new;
if ($order eq \'down\') {$ord_new = $ord - 1}
if ($order eq \'up\') {$ord_new = $ord + 1}
if ($var =~s /([0-9]+:)$ord_new/$1$ord/g) {$var =~s /$id\\:([0-9]+)/$id\\:$ord_new/g}
return $var
}

Может немного напутал с up - down, но принцип понятен...

P.S. Исправлено, забыл = в условии...
Название: Сдвиг сортировки...
Отправлено: vladsu от 08 Сентября 2004, 17:05:41

use strict;
use warnings;
use Data::Dumper;

my $var = \'34:2,56:4,65:3,675:1,69:0\';

my $id = 34;
#my $order = \'up\';
my $order = \'down\';

my %out = map {split \':\', $_} split ",", $var;

$order eq \'up\'
?
($out{sv($out{$id}+1)} = $out{$id} and $out{$id}++)
:
($out{sv($out{$id}-1)} = $out{$id} and $out{$id}--);

print Dumper(\\%out);

sub sv {
    map {return $_ if $out{$_} eq $_[0]} keys %out;
}

to Admins Отключили бы "улыбки" в коде, или научите как это делать самому.
Название: Сдвиг сортировки...
Отправлено: NeoNox от 08 Сентября 2004, 17:16:52
vladsu в полном ответе "Отключить иконки в Этом сообщении  "
в быстрой форме - вставляйте между тегами...(прости Господи) РНР
Название: Сдвиг сортировки...
Отправлено: Phoinix от 08 Сентября 2004, 17:41:33
vladsu

Вот только проверку крайних значений (max и min), что-то не вижу...

NeoNox
[OFF]А я, обычно, закрываю правый глаз, что бы видеть только букву P... ;)[/OFF]
Название: Сдвиг сортировки...
Отправлено: vladsu от 08 Сентября 2004, 18:26:40
Цитировать
Phoinix:

Вот только проверку крайних значений (max и min), что-то не вижу...

Не понял, о чём это Вы?
Название: Сдвиг сортировки...
Отправлено: commander от 08 Сентября 2004, 19:15:42
Phoinix
спасибо за помощь!
Отдельное спасибо vladsu!

vladsu
знаю тебя больше года... но никак не могу привыкнуть к твоему стилю написания кода... ;)
Название: Сдвиг сортировки...
Отправлено: Phoinix от 08 Сентября 2004, 19:17:44
vladsu


Цитировать
commander
...
if ($ord==0) #проверка на ноль
...
if ($ord==$max_elem) #проверка на максимальный элемент
...


Я о том, что произойдет если минимальный элемент попытаются опустить вниз или максимальный вверх, у кого замещяется индекс сортировки?

при подстановке $id = 69; в массиве появляется 6-й элемент: 5=>0
Название: Сдвиг сортировки...
Отправлено: vladsu от 08 Сентября 2004, 20:37:33
Цитировать
при подстановке $id = 69; в массиве появляется 6-й элемент: 5=>0


Ааа, спасибо, об этом я в курсе, даже сразу предупредил commander\'а, он мне в асю писал прижде чем сюда запостить. И в условии ничего об этом не было сказано, т.е. я даже не знал, что в таких случаях делать, думаю он и сам сможет доделать.
Название: Сдвиг сортировки...
Отправлено: commander от 09 Сентября 2004, 11:34:30
vladsu
Уже доделал... спасибо! ;)