Имя: Пароль:
1C
1С v8
Помогите решить задачку с сортировкой двумерного массива по ключу
0 Zakella86
 
30.08.16
17:51
Помогите решить задачку.
[url=http://radikal.ru][img]http://s41.radikal.ru/i093/1608/53/1092dc1291f2.png[/img][/url]

я часть уже решил , но дальше не могу понять что делать
вот часть моего решения

  Массив = Новый Массив(6, 5);
  


  
  массив[0][0]=1;  
  массив[0][1]=6;    
  массив[0][2]=3;    
  массив[0][3]=4;    
  массив[0][4]=5;  
  
  массив[1][0]=2;        
  массив[1][1]=2;      
  массив[1][2]=1;  
  массив[1][3]=2;
  массив[1][4]=3;
  
  
  массив[2][0]=5;    
  массив[2][1]=6;  
  массив[2][2]=6;    
  массив[2][3]=4;  
  массив[2][4]=7;
  
  массив[3][0]=4;    
  массив[3][1]=4;  
  массив[3][2]=5;    
  массив[3][3]=1;  
  массив[3][4]=2;
  
  массив[4][0]=1;    
  массив[4][1]=2;  
  массив[4][2]=2;    
  массив[4][3]=2;  
  массив[4][4]=3;
  
  массив[5][0]=3;    
  массив[5][1]=6;  
  массив[5][2]=4;    
  массив[5][3]=4;  
  массив[5][4]=5;

   ПервыйКлюч=2; ВторойКлюч=4;
  
   МассивКлючей=Новый Массив(6,5);
   Для ИндексСтрока = 0 По Массив.Количество() - 1 Цикл
       Для ИндексСтолбец = 0 По Массив[ИндексСтрока].Количество() - 1 Цикл
           //Сообщить(Массив[ИндексСтрока][ИндексСтолбец]);
          
           Если ИндексСтолбец=ПервыйКлюч-1  Тогда
               МассивКлючей[ИндексСтрока][ПервыйКлюч-1]=Массив[ИндексСтрока][ИндексСтолбец];
           КонецЕсли;
          
           Если  ИндексСтолбец=ВторойКлюч-1 Тогда
              
               МассивКлючей[ИндексСтрока][ВторойКлюч-1]=Массив[ИндексСтрока][ИндексСтолбец];
              
              
           КонецЕсли;
          
       КонецЦикла;
      
   КонецЦикла;
2 Zakella86
 
30.08.16
17:56
http://i11.pixs.ru/storage/9/2/2/1jpg_5947600_23112922.jpg вот изображение получше
3 Euguln
 
30.08.16
17:56
ТЗ.Свернуть()
4 Zakella86
 
30.08.16
17:57
неа, не все так просто, тут прикол именно в двумерном массиве
5 Euguln
 
30.08.16
17:58
(4) Выгрузи в тз, сверни, выгрузи в массив.
6 Zakella86
 
30.08.16
17:59
представь что нет ТЗ. Только сортировка двумерного массив. Как решить эту задачу не используя тз?
7 Zakella86
 
30.08.16
18:02
своим алгоритмом я уже определил столбцы которые являются ключами. Но никак не могу вспомнить как их сортировать
8 Euguln
 
30.08.16
18:03
(7) Где в задаче написано, что надо отсортировать?
9 Zakella86
 
30.08.16
18:06
ну я думаю сначала так , нужно выявить колонки ключи, затем выбрать только уникальные значения в колонках, а затем по ключам плюсовать суммируемые колонки. Если кто то видит другое решение буду рад
10 Euguln
 
30.08.16
18:13
Цикл по строкам массива, вложенный цикл по строкам массива, дальше текущей в первом цикле. По индексам колонок определяем подходящие строки, плюсуем к текущей и удаляем.
11 orefkov
 
30.08.16
18:19
(10)
Так O(N^2) получится.
Лучше сначала отсортировать массив по ключевым столбцам, потом за один проход просуммировать, сравнивая с ключами в предыдущей строке.
12 Zakella86
 
30.08.16
18:21
можете отписать ваше решение, у меня что то не получается так
13 Euguln
 
30.08.16
18:27
(11) Меньше, т.к. строки будут удаляться.
Сортировка массива тоже некоторое количество проходов съест.
14 orefkov
 
30.08.16
18:44
(13)
Расчет O делается для общего случая, так что будет грубо говоря N сравнений для каждой из N строк. Итого N^2.
А хорошие сортировки имеют O=N*log2(N).
(12)
Тебе стратегию расписали, над деталями сам думай, не барское это дело :)
15 Zakella86
 
30.08.16
18:47
(14) вчера праздновал деняру, нифига еще не вышло из меня. Туплю вообще
16 Йохохо
 
30.08.16
18:48
в таких задачах подразумевается что нельзя использовать доп переменные? доп структура с номером строки выходной таблицы и все
17 Zakella86
 
30.08.16
18:49
(16) главное типа не использовать тз.
18 Йохохо
 
30.08.16
18:53
(17) ну, фигарь, взял строку, построил ключ строки, поискал, нашел добавил в выходную, не нашел... о маленькое от (N+1), развод
19 Zakella86
 
30.08.16
18:57
(18) ок сейчас попробуй. но мозги болит просто жуть, не могу сосредоточится даже на простом алгоритме
20 Йохохо
 
30.08.16
19:06
в (18) наврал. без ограничения общности столбцы ключа первые К столбцов - очевидно бинарный поиск, О(Н лог2(Н))
21 Garykom
 
гуру
30.08.16
19:58
2N сложность, всего 2 цикла требуется
22 Garykom
 
гуру
30.08.16
20:00
(21)+ Хотя наврал "ширина" то таблицы любая а не 2 колонки, и ключ составной еще же.
23 Zakella86
 
30.08.16
22:06
блин стратегию понимаю, но в рабочий код пока это не выливается :(
24 Torquader
 
30.08.16
22:49
Во-первых, нужно создать уникальный ключ на основании двух столбцов. Далее - перебираем массив - создаём ключ и выполняем операции с ячейками.
25 Euguln
 
30.08.16
23:44
МассивКлючей =Новый Массив;
  МассивКлючей.Добавить(2);
  МассивКлючей.Добавить(4);
  
  МассивЗначенийКлючей  =Новый Массив;
  ИндесТекущейСтроки    = 0;
  
  Пока ИндесТекущейСтроки< массив.Количество() Цикл
      
      МассивЗначенийКлючей.Очистить();
      Для Сч = 1 По МассивКлючей.Количество() Цикл
      
          МассивЗначенийКлючей.Добавить(массив[ИндесТекущейСтроки][МассивКлючей[Сч - 1] - 1]);    
      
      КонецЦикла;
      
      ИндекСтрокиПеребора    = ИндесТекущейСтроки  + 1;
      Пока ИндекСтрокиПеребора< массив.Количество() Цикл
          
          КлючПодходит = Истина;
          Для Сч = 1 По МассивЗначенийКлючей.Количество() Цикл
                КлючПодходит    = КлючПодходит И (массив[ИндекСтрокиПеребора][МассивКлючей[Сч - 1] - 1] = МассивЗначенийКлючей[Сч - 1]);      
          КонецЦикла;
          
          Если КлючПодходит Тогда
              Для Сч = 0 По 4 Цикл
              
                  Если МассивКлючей.Найти(Сч + 1) = Неопределено Тогда
                
                    массив[ИндесТекущейСтроки][Сч]    = массив[ИндесТекущейСтроки][Сч] + массив[ИндекСтрокиПеребора][Сч];    
                
                КонецЕсли;     
              
              КонецЦикла;
                массив.Удалить(ИндекСтрокиПеребора);
          Иначе    
              ИндекСтрокиПеребора = ИндекСтрокиПеребора + 1;
          КонецЕсли;
          
      КонецЦикла;
      
      ИндесТекущейСтроки    = ИндесТекущейСтроки + 1;
      
  КонецЦикла;
26 Garykom
 
гуру
30.08.16
23:52
Тут слегка того, размеры исходного массива могут быть любые а не только 6х5

Для Сч = 0 По 4 Цикл
   Если МассивКлючей.Найти(Сч + 1) = Неопределено Тогда
      массив[ИндесТекущейСтроки][Сч] = массив[ИндесТекущейСтроки][Сч] + массив[ИндекСтрокиПеребора][Сч];    
   КонецЕсли;    
КонецЦикла;
27 Garykom
 
гуру
30.08.16
23:52
(26) к (25)
28 Euguln
 
30.08.16
23:54
(27) Ну простите, что не все разжевал )))
29 Garykom
 
гуру
30.08.16
23:54
(25) Но кода правильная, я бы только получение таблицы для заполнения (ключи без дублей) вынес в отдельный цикл в начале.

Тогда извращаться с удалением строк из массива не придется и можно без "Найти" обойтись будет просто циклами.
Это на случай если захотят решение на "базовых алгоритмах" без продвинутых возможностей структур.
30 Euguln
 
30.08.16
23:57
(29) Зато перебора строк меньше.
31 Garykom
 
гуру
31.08.16
00:02
(30) Внутри "Найти" один фиг перебор строк )) Это если индексы самому не реализовывать )))
32 Euguln
 
31.08.16
00:16
(31) Ну вместо "Найти" можно ещё один массив завести, с суммирующими колонками.
33 Zakella86
 
31.08.16
09:11
(25) благодарю