URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9154
[ Назад ]

Исходное сообщение
"оставить только начальное и конечное значение"

Отправлено rec , 06-Июн-11 13:42 
Есть данные в виде таблицы:

902  2700000  2709999
902  2710000  2719999
902  2720000  2729999
902  2730000  2739999
902  2740000  2749999
902  2750000  2759999
902  2760000  2769999
902  2780000  2789999
902  2790000  2799999
903  2810000  2819999
903  2820000  2829999

(Информация о нумерации сотовых операторов).
Чтобы точнее сформулировать задачу, приведу конечный результат, который хотелось бы получить:

902  2700000  2769999  
902  2780000  2799999
903  2810000  2829999

Т.е. диапазон нумерации в отдельных строках является продолжением нумерации предыдущей строки. Хотелось бы иметь только начальное и конечное значение приведенных диапазонов и те, которые являются продолжением диапазона из предыдущей строки объединить в один диапазон.
Реально скрипт такой сочинить? Не подкините идеи?
Можно для начала упростить задачу: убрать первый столбец (902, 903).


Содержание

Сообщения в этом обсуждении
"оставить только начальное и конечное значение"
Отправлено Andrey Mitrofanov , 06-Июн-11 14:19 
> Чтобы точнее сформулировать задачу, приведу конечный результат, который хотелось бы получить:
> 902  2700000  2769999
> 902  2780000  2799999
> 903  2810000  2829999

$ awk 'function f(){if(a!="")print a" "b" "c;a=$1;b=$2;c=$3}{if(a!=""&&$1==a&&$2==c+1)c=$3;else f()}END{f()}' <data
902 2700000 2769999
902 2780000 2799999
903 2810000 2829999
$ _

Как я могу получить сои деньги?


"оставить только начальное и конечное значение"
Отправлено rec , 06-Июн-11 15:36 
> Как я могу получить сои деньги?

Спасибо за красивое решение задачи, работает.
Думаю, не корысти ради помогаете в таких вот вопросах. :)



"оставить только начальное и конечное значение"
Отправлено sm00th1980 , 06-Июн-11 15:37 
как мне кажется в лоб такая задача в 2-3 строки не решается(типа хитрым регекспом).
Тут нужно попытаться объеденить несколько диапазонов в один - по возможности.
Т.е. как минимум где-то хранить диапазоны - и по полному списку пытаться понять есть ли продолжение текущего диапазона или нет.

А какой язык то предполагается?

хотя конечно могу ошибаться.

PS вариант через рекурсию - зачётный :)


"оставить только начальное и конечное значение"
Отправлено rec , 06-Июн-11 15:48 
> как мне кажется в лоб такая задача в 2-3 строки не решается
> А какой язык то предполагается?

тоже склонялся к такому варианту. Не ожидал однострочного решения.


"оставить только начальное и конечное значение"
Отправлено Andrey Mitrofanov , 06-Июн-11 16:07 
> PS вариант через рекурсию - зачётный :)

:-О Где-е-е??


"оставить только начальное и конечное значение"
Отправлено sm00th1980 , 06-Июн-11 16:28 
>> PS вариант через рекурсию - зачётный :)
> :-О Где-е-е??

function f(){if(a!="")print a" "b" "c;a=$1;b=$2;c=$3}{if(a!=""&&$1==a&&$2==c+1)c=$3;else f()}END{f()}

может я конечно что-то не так понял... но вроде как f() предпоследний - это вызов саму себя - я прав или нет?

трудно просто без форматирования возможно понять :)


"оставить только начальное и конечное значение"
Отправлено Andrey Mitrofanov , 06-Июн-11 17:33 
> может я конечно что-то не так понял... но вроде как f() предпоследний
> - это вызов саму себя - я прав или нет?

Нет, это не рекурсия ни разу. Посто оформление одного куска кода, используемого в двух местах, в виде функции.


"оставить только начальное и конечное значение"
Отправлено Aquarius , 06-Июн-11 16:57 
>[оверквотинг удален]
> Чтобы точнее сформулировать задачу, приведу конечный результат, который хотелось бы получить:
> 902  2700000  2769999
> 902  2780000  2799999
> 903  2810000  2829999
> Т.е. диапазон нумерации в отдельных строках является продолжением нумерации предыдущей
> строки. Хотелось бы иметь только начальное и конечное значение приведенных диапазонов
> и те, которые являются продолжением диапазона из предыдущей строки объединить в
> один диапазон.
> Реально скрипт такой сочинить? Не подкините идеи?
> Можно для начала упростить задачу: убрать первый столбец (902, 903).

я бы посоветовал сначала преобразовать в префиксную нотацию, а потом, если требуется, обратно;
то есть, то что получися, будет списком начал номеров, таких, что если номер начинается с этих цифр, он входит в диапазон
к примеру, для вашего списка получится
902270
902271
902272
902273
902274
902275
902276
902278
902279
903281
903282
у вас пример данных не универсален, решив задачу на этих номерах, вы можете столкнуться с проблемами с другими, более раздробленными диапазонами, к примеру
902 2700000 2703999
из которого получается такой список префиксов:
9022700
9022701
9022702
9022703
то есть, в общем случае, получается не одна строка
список префиксов сортируется и анализируется на покрывающие префиксы (диапазон, где весь префикс повторяется кроме последней цифры, на месте которой есть все от 0 до 9, заменяется одним префиксом без этой последней цифры)
список префиксов вернуть к исходному формату - плевое дело - дописать недостающее количество нулей для начала и девяток для конца диапазона

P.S. "для начала" надо не убирать первый столбец, а "приклеить" его ко второму и третьему


"оставить только начальное и конечное значение"
Отправлено rec , 07-Июн-11 08:35 
>[оверквотинг удален]
> у вас пример данных не универсален, решив задачу на этих номерах, вы
> можете столкнуться с проблемами с другими, более раздробленными диапазонами
> то есть, в общем случае, получается не одна строка
> список префиксов сортируется и анализируется на покрывающие префиксы (диапазон, где весь
> префикс повторяется кроме последней цифры, на месте которой есть все от
> 0 до 9, заменяется одним префиксом без этой последней цифры)
> список префиксов вернуть к исходному формату - плевое дело - дописать недостающее
> количество нулей для начала и девяток для конца диапазона
> P.S. "для начала" надо не убирать первый столбец, а "приклеить" его ко
> второму и третьему

открывая тему, старался максимально упростить задачу, было желание получить определенный результат и убедиться в возможности таких преобразований юниксовскими командами (не сомневаюсь в возможностях программистов сделать это более рационально с помощью соответствующих языков программирования, коими я, к сожалению, не владею).
Ваше замечание о другом дроблении префиксов (и оно имеет место быть) очень своевременно, обращу на это внимание.
Конечная задача конечно же намного сложнее и запутаннее. Спасибо за ваш совет по использованию полного 10-ти значного префикса, источник перечислил их (префиксы) в удобной для себя форме. Для работы удобнее будет объединить цифры первого столбца со вторым и третьим.