Требуется отсортировать многомерный массив сложным способом

Статус
В этой теме нельзя размещать новые ответы.

General Fizz

Боевой Генерал :)
Регистрация
11 Апр 2007
Сообщения
754
Реакции
428
Задача вроде бы и простая, но тем не менее...
Имеется массив:
PHP:
$mas=array(
  'строка2' => array( 712,   32, 15, 74,  1),
  'строка1' => array( 525,    0, 83,  4, 75),
  'строка3' => array(6855,  267,  3, 14, 75),
  'строка6' => array(1235, 7545,  0,  7,  2)
  ...
);


Нужно его отсортировать по строкам строка1,2,3... таким образом чтобы:
на первом месте была строка, у которой все значения среди всех пяти числовых параметров максимальны. Вторая строка после первой и так далее.

Распределенные места для примера выше:
строка2 - 3,3,2,1,4
строка1 - 4,4,1,4,1
строка3 - 1,2,3,2,1
строка6 - 2,1,4,3,3


Для данного примера правильный результат будет array('строка3', 'строка6', 'строка2', 'строка1'). Строка6 стоит выше строки2 потому что при одинаковом распределении мест (одно первое, одно второе два третьих и одно четвертое) у строки6 в параметре [0] место второе, а у строки2 третье.

Числовые значения возвращать не нужно, достаточно только отсортированные строки.

Строк может быть много, числовых параметров только пять, большинство из них могут быть нулями, но не все.
Похожая задача - отсортировать страны по количеству полученных медалей на Олимпийских Играх в соотвтетствии с их достоинством, то есть на первом месте страна с наибольшим количеством золотых медалей, потом серебрянных и бронзовых, только в данном случае числовых параметров (достоинств медалей) не 3, а 5.
 
Чтобы было более наглядно, сформулирую задачу таким образом.

На Олимпийских Играх 2030 года в Бобруйске страны-участники завоевали следующее количество медалей:

PHP:
Белоруссия      - золотых -  2, серебрянных -  3, бронзовых -  1, оловянных - 15, деревянных - 88;
Украина         - золотых - 54, серебрянных -  0, бронзовых -  8, оловянных -  1, деревянных -  7;
Китай           - золотых - 84, серебрянных - 22, бронзовых -  0, оловянных - 41, деревянных -  0;
США             - золотых - 41, серебрянных - 10, бронзовых -  0, оловянных -  0, деревянных - 17;
Зимбабве        - золотых - 18, серебрянных -  6, бронзовых - 14, оловянных - 13, деревянных -  8;
Северная Корея  - золотых -  0, серебрянных -  5, бронзовых -  0, оловянных - 22, деревянных - 12;
Казахстан       - золотых - 25, серебрянных -  0, бронзовых -  8, оловянных - 15, деревянных -  0;
Россия          - золотых - 98, серебрянных -  3, бронзовых -  7, оловянных -  2, деревянных - 10;


Или если представить по-другому:

PHP:
$medals=array(

'Белоруссия'     => array( 2,  3,  1, 15, 88),
'Украина'        => array(54,  0,  8,  1,  7),
'Китай'          => array(84, 22,  0, 41,  0),
'США'            => array(41, 10,  0,  0, 17),
'Зимбабве'       => array(18,  6, 14, 13,  8),
'Северная Корея' => array( 0,  5,  0, 22, 12),
'Казахстан'      => array(25,  0,  8, 15,  0),
'Россия'         => array(98,  3,  7,  2, 10)

);


Требуется расставить все страны по максимальному количеству медалей всех проб одновременно, в убывающем порядке. В случае одинакового количества медалей приоритет имеет проба медали.


Например из двух стран - Китай(84, 22, 0, 41, 0) и Зимбабве(18, 6, 14, 13, 8), Китай должен стоять выше, поскольку он по количеству серебрянных и оловянных медалей имеет первые места, а Зимбабве имеет первое место только по количеству бронзовых медалей.

Если же допустим у Китая(0, 22, 0, 41, 0), а у Зимбабве(0, 22, 0, 41, 8), то выше должна стоять Зимбабве, поскольку Зимбабве стоит выше Китая по количеству деревянных медалей.


Занимаемые странами места по количеству медалей одной пробы в соответствии с массивом $medals:
PHP:
$medals_positons=array(
'Белоруссия'     => array( 7,  5,  5,  3,  1),
'Украина'        => array( 3,  7,  2,  7,  6),
'Китай'          => array( 2,  1,  6,  1,  7),
'США'            => array( 4,  2,  6,  8,  2),
'Зимбабве'       => array( 6,  3,  1,  5,  5),
'Северная Корея' => array( 8,  4,  6,  2,  3),
'Казахстан'      => array( 5,  7,  2,  3,  7),
'Россия'         => array( 1,  5,  4,  6,  4)
);


То есть задача состоит в том, чтобы отсортировать массив $medals по убывающей в соответствии с критериями выше.
 
Используй функцию Для просмотра ссылки Войди или Зарегистрируйся
Для сортировки пиши свою функцию, все должно быть понятно по примерам
 
Что-то во втором твоем посте не только более наглядно, но еще и другая задача, намного проще:

1) Заведем функцию reduce() для массива с медалями конкретной страны, которая будет возвращать его "вес". Кол-во золотых медалей * миллион + кол-во серебряных * 10 тысяч + кол-во бронзовых * 100 ... и так далее. Весовые коэффициенты расставь сам по вкусу, хочешь - сделай чтоб 10 бронзовых = 1 серебряной, а хочешь - чтоб и миллион бронзовых все равно не "перевешивал" одно серебро. Разница только в соотношении порядков величин, т.е. сколько всего у страны может быть медалей одного типа. На выходе получаем просто число.

2) Как правильно заметил человек выше, создадим свою функцию сортировки и передадим ее в usort. Функция сортировки простейшая - просто сравниваем "в лоб" два reduce() от аргументов, и какой больше - тот массив и ставим выше в результатах сортировки.
 
Что-то во втором твоем посте не только более наглядно, но еще и другая задача, намного проще
Второй пост немного исправил, теперь задача описана точно как и в первом.
 
Ну то же самое, только весовые коэффициенты у тебя должны быть такие, чтобы 2 бронзовых (и даже две деревянных) перевешивало одну серебрянную, а при равном количестве приоритет отдавался более крутым медалям. И так как количества медалей - целые числа, то разница в коэффициентах должна тогда получается идти на сотые или тысячные, смотря сколько там у тебя этих медалей может максимум быть.

Т.е. reduce() будет иметь вид
$golds*1.001 + $silvers*1.00001 + $bronzes * 1.0000001 + $plumbums * 1.000000001 + $woods * 1.00000000001;
В float влазит без проблем :)
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху