Имя: Пароль:
1C
1С v8
Пятничная задачка. Алгоритм преобразования ряда чисел в строку.
,
0 apl1978
 
06.02.15
09:54
Доброе утро, коллеги!

Предлагаю задачку, чтобы немного отвлечься.
Есть ряд чисел например (1,2,3,4,5,9,12,13,14).
Его надо вывести в строку вида (1-5, 9, 12-14).
Ряд может принимать любые заранее неизвестные значения. Может быть весь последовательным (1,2,3,4,5) - тогда выводим (1-5), а может вообще не содержать последовательных (1,3,5) тогда в этом виде и выводим.

Одно точно известно - ряд всегда "отсортирован" от минимального до максимального.

Это что-то явно математическое, но никак не нащупаю нить. Простым перебором вроде бы не обойтись.

Может кто-нибудь знает алгоритм на любом языке, я под 1С 8 перепишу.

Всем доброй пятницы!
1 Asmody
 
06.02.15
09:57
Эта "интересная задачка" сплывает раз в два-три месяца. На ИС её даже запросами решение лежит.
2 Crush
 
06.02.15
09:58
(0) "Простым перебором вроде бы не обойтись."
Больше походит на пятничный троллинг:)
3 Cube
 
06.02.15
09:59
(0) Пф... Сначала РазложитьСтрокуВМассивПодстрок() эта функция есть в любой типовой, а потом простой цикл...
4 PR
 
06.02.15
09:59
Не взлетит ветка. Задачка плевая.
5 spectre1978
 
06.02.15
10:00
(3) +1
6 spectre1978
 
06.02.15
10:00
самое сложное - разложить в массив подстрок - уже написано во всех типовых...
7 Crush
 
06.02.15
10:01
for(i==1;n-1;1)
8 b_ru
 
06.02.15
10:02
>>Простым перебором вроде бы не обойтись.

У решения простым перебором сложность O(n) и требования к памяти o(1). Куда уж лучше то.
9 PR
 
06.02.15
10:03
(6) Эээ...
СтрЗаменить(Стр, ",", Символы.ПС).
10 User_Agronom
 
06.02.15
10:06
(6) А в лоб перебором слабо?
Всё в один цикл вместится.
11 User_Agronom
 
06.02.15
10:07
(9) Это слишком просто. Решение не тянет на пятничную задачу.
12 Cube
 
06.02.15
10:08
(10) Если заказчик башляет за мизерный прирост производительности, то любой каприз, как оговориться :)
13 patria0muerte
 
06.02.15
10:12
14 PR
 
06.02.15
10:14
(11) Тут и задачка не тянет на пятничную.
15 PR
 
06.02.15
10:15
(12) Заказчик в данном случае никакого прироста не заметит, только прирост денег в кармане программиста за счет кармана клиента.
16 1Сергей
 
06.02.15
10:16
(13) не нашел
17 patria0muerte
 
06.02.15
10:17
(16) 2ой пункт
18 1Сергей
 
06.02.15
10:25
(17) ну и хрен с ним
19 1Сергей
 
06.02.15
10:25
в лоб:

Функция ПолучитьМассив(
    Знач1 = Неопределено,
    Знач2 = Неопределено,
    Знач3 = Неопределено,
    Знач4 = Неопределено,
    Знач5 = Неопределено,
    Знач6 = Неопределено,
    Знач7 = Неопределено,
    Знач8 = Неопределено,
    Знач9 = Неопределено,
    Знач10 = Неопределено,
    Знач11 = Неопределено,
    Знач12 = Неопределено,
    Знач13 = Неопределено,
    Знач14 = Неопределено,
    Знач15 = Неопределено,
    Знач16 = Неопределено,
    Знач17 = Неопределено,
    Знач18 = Неопределено,
    Знач19 = Неопределено,
    Знач20 = Неопределено,
    Знач21 = Неопределено,
    Знач22 = Неопределено,
    Знач23 = Неопределено,
    Знач24 = Неопределено,
    Знач25 = Неопределено,
    Знач26 = Неопределено,
    Знач27 = Неопределено,
    Знач28 = Неопределено,
    Знач29 = Неопределено,
    Знач30 = Неопределено)
    
    Результат = Новый Массив;
    
    Для Счетчик = 1 по 30 Цикл
        Значение = Вычислить("Знач" + Счетчик);
        Если Значение = Неопределено Тогда
            Прервать;
        КонецЕсли;
        Результат.Добавить(Значение);
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции


Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    //1,2,3,4,5,9,12,13,14
    МассивСтраниц = ПолучитьМассив(1,2,3,4,5,9,12,13,14);
    
    Результат = "";
    НачалоРяда = Неопределено;
    ПредыдущиеЗначение = Неопределено;
    
    Для Каждого Значение Из МассивСтраниц Цикл
        
        Если ПредыдущиеЗначение = Неопределено Тогда
            ПредыдущиеЗначение = Значение;
            Продолжить;
        КонецЕсли;
        
        Если Значение = (Число(ПредыдущиеЗначение) + 1) Тогда
            Если НачалоРяда = Неопределено Тогда
                НачалоРяда = ПредыдущиеЗначение;
            КонецЕсли;
        ИначеЕсли Не НачалоРяда = Неопределено Тогда
             Результат = ?(Результат="", "", Результат + ", ") + НачалоРяда + "-" + ПредыдущиеЗначение;
             НачалоРяда = Неопределено;
        Иначе
            Результат = ?(Результат="", "", Результат + ", ") + ПредыдущиеЗначение;
        КонецЕсли;
        
        ПредыдущиеЗначение = Значение;
        
    КонецЦикла;

    Если Не НачалоРяда = Неопределено Тогда
         Результат = ?(Результат="", "", Результат + ", ") + НачалоРяда + "-" + ПредыдущиеЗначение;
    Иначе
        Результат = ?(Результат="", "", Результат + ", ") + ПредыдущиеЗначение;
    КонецЕсли;
    
    Сообщить(Результат);
        
КонецПроцедуры
20 kosts
 
06.02.15
10:27
(0) Точно такую же задачу неделю назад решал, только с датами.
21 1Сергей
 
06.02.15
10:29
(20) циклом решил?
22 kosts
 
06.02.15
10:32
(21) Хотел рекурсией, но решил, что в рабочей базе так не очень хорошо будет.
В итоге решил запросом, но потом циклом все же.
23 kosts
 
06.02.15
10:32
(22) Т.е. решил и запросом и циклом, но оставил цикл, что бы базу не дергать.
24 apl1978
 
06.02.15
11:12
Всем большое спасибо!

Тему можно закрыть. Сделал перебором по массиву со сравнением.

Доброй пятницы и хороших выходных :)
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший