powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / заменить последовательность диапазоном
18 сообщений из 18, страница 1 из 1
заменить последовательность диапазоном
    #38023123
Goffman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте, такая проблема, для краткости отображения нужно заданный ряд номеров отобразить в виде диапазона

примерно так
Код: plaintext
1.
2.
3.
4.
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66

результат 27-66


кто подскажет куда копать, может есть готовые библиотеки, или регулярное выражение
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023131
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В циклы копать. При чем написать алгоритм быстрее, чем написать на форум и ждать ответа хотя-бы минут 5.
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023206
Goffman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman написать алгоритм быстрее, чем написать на форум и ждать ответа хотя-бы минут 5.
Не уверен, задача довольно нетривиальная, осложняется тем, что номера могут быть такие:
VST45 - VST123
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023219
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Goffman , задача - тривиальная.

Goffmanосложняется тем, что номера могут быть такие: VST45 - VST123
Это не осложнение, а неумение чётко и однозначно поставить задачу. Формализуйте номер - и всё сведётся к задаче исходного поста.

Что же до реализации - всё зависит от того, какими средствами нужно это реализвывать. Если предположить (форум, всё-таки, SQL.RU), что средствами SQL - следует отказаться от свёртки диапазонов в пользу нормализации данных. Либо иметь ОЧЕНЬ веские основания для реализации этой свёртки.
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023300
Goffman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,

Однозначно поставить задачу не получается, номера могут быть хоть какими, какого то четкого правила нумерации номеров нет (извиняюсь за тавтологию:).
Да, хранятся они в таблице, каждый номер в своей записи, но это этого не легче.
Так как мы не знаем правила нумерации, и не можем на них повлиять, то и задача рассматривается в общем виде.
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023309
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GoffmanAkina,

Однозначно поставить задачу не получается, номера могут быть хоть какими, какого то четкого правила нумерации номеров нет (извиняюсь за тавтологию:).
Да, хранятся они в таблице, каждый номер в своей записи, но это этого не легче.
Так как мы не знаем правила нумерации, и не можем на них повлиять, то и задача рассматривается в общем виде.

сначала определитесь, а потом спрашивайте... А то щас обсуждать начнём, а окажется, что у вас номер может записываться иероглифом или римскими числами, а ещё потом в двоичной системе в перемешку с буквами... )))
Минимум: приведите реальный список, который будет, и то, что из такого списка получить надо
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023340
Abstraction
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Goffman,

Такая последовательность возможна?
Код: plaintext
1 2A3 3A4 5
Если да, то что должно быть на выходе?
Такая последовательность возможна?
Код: plaintext
1A 2B 3B 4C 5B 6C 7B
Если да, то что должно быть на выходе?
Такая последовательность возможна?
Код: plaintext
A-1 A-5 A-6-1
Если да, то что должно быть на выходе?
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023354
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaЕсли предположить (форум, всё-таки, SQL.RU), что средствами SQL - следует отказаться от свёртки диапазонов в пользу нормализации данных.
Сегодня уже не составляет проблемы свернуть диапазон средствами SQL. По крайней мере, нормального SQL.
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023416
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerСегодня уже не составляет проблемы свернуть диапазон средствами SQL. По крайней мере, нормального SQL.Свернуть - да. Использовать, особенно если быстродействие критично - далеко не всегда.
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023437
Goffman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Програмёр сначала определитесь, а потом спрашивайте... А то щас обсуждать начнём, а окажется, что у вас номер может записываться иероглифом или римскими числами, а ещё потом в двоичной системе в перемешку с буквами... )))
Минимум: приведите реальный список, который будет, и то, что из такого списка получить надо

Теоретически могут быть и римские, правила нумерации от заказчика зависят ))

Сейчас списки примерно такие

VM3529,VM3530,VM3531,VM3532,VM3533,VM3534,VM3493,VM3494,VM3495,VM3496,VM3497,VM3498

Свертка должна быть получиться такая
VM3529 - VM3534, VM3493 - VM3498

Бывают более сложные варианты, например т.н. шахматка
A1Б1, А1Б2, A2Б1, А2Б2, А3Б1, А3Б2
получается
А1Б1 - А3Б2

Но для начала, чтобы не усложнять, берем что есть буквенный префикс и цифровая часть.

В принципе, если хорошенько подумать, то первая задача вполне решаемая :)
Я думал есть уже готовые велосипеды
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023460
dzone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GoffmanПрограмёр сначала определитесь, а потом спрашивайте... А то щас обсуждать начнём, а окажется, что у вас номер может записываться иероглифом или римскими числами, а ещё потом в двоичной системе в перемешку с буквами... )))
Минимум: приведите реальный список, который будет, и то, что из такого списка получить надо

Теоретически могут быть и римские, правила нумерации от заказчика зависят ))

Сейчас списки примерно такие

VM3529,VM3530,VM3531,VM3532,VM3533,VM3534,VM3493,VM3494,VM3495,VM3496,VM3497,VM3498

Свертка должна быть получиться такая
VM3529 - VM3534, VM3493 - VM3498

Бывают более сложные варианты, например т.н. шахматка
A1Б1, А1Б2, A2Б1, А2Б2, А3Б1, А3Б2
получается
А1Б1 - А3Б2

Но для начала, чтобы не усложнять, берем что есть буквенный префикс и цифровая часть.

В принципе, если хорошенько подумать, то первая задача вполне решаемая :)
Я думал есть уже готовые велосипеды


Код: c#
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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
 string somedata = "VM3529,VM3530,VM3531,VM3532,VM3533,VM3534,VM3493,VM3494,VM3495,VM3496,VM3497,VM3498"; 
//1,2,3,5,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66";
            string[] origindata = somedata.Split(',');
            int[] digits = somedata.Split(',').Select(s => Int32.Parse(Regex.Match(s, @"\d+").Value)).ToArray();
            string output = string.Empty;

            int firstn = digits[0];
            int firstindex = 0;
            int lastn = digits[0];
            int lastindex = 0;

            for (int i = 1; i < digits.Length ;i++ )
            {
                if(digits[i]==lastn+1)
                {
                    lastn = digits[i];
                    lastindex = i;
                }
                else
                {
                    output += origindata[firstindex];// firstn;
                    if (lastn != firstn) 
                    {
                        output += string.Concat("-", origindata[lastindex], ",");// lastn
                    }
                    else
                    {
                        output += ",";
                    }
                    lastn = digits[i];
                    firstn = digits[i];
                    lastindex = i;
                    firstindex = i;
                }
            }
            if (lastn != firstn) output += string.Concat(origindata[firstindex], "-", origindata[lastindex]); //firstn  lastn

 
            Console.WriteLine(output);
            
            Console.ReadKey();
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023506
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dzone, как сложно-то.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 
Connected as test
 
SQL> with
  2    data as (select 'VM3529,VM3530,VM3531,VM3532,VM3533,VM3534,VM3493,VM3494,VM3495,VM3496,VM3497,VM3498' s# from dual),
  3    d1 as (select s#, instr(',' || s#, ',', 1, rownum) p1, instr(s# || ',', ',', 1, rownum) - 1 p2 from data connect by rownum <= 12),
  4    d2 as (select substr(s#, p1, p2 - p1 + 1) v# from d1),
  5    d3 as (select v#, translate(upper(v#), '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789') n# from d2)
  6  select min(v#) || ' - ' || max(v#) result
  7  from d3
  8  group by n# - rownum;
 
RESULT
--------------------------------------------------------------------------------
VM3529 - VM3534
VM3493 - VM3498
 
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023546
dzone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer,

)) согласен, можно и по красивее написать, будет кода поменьше. хотя у вас результат не в одну строчку и не через запятую :(
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023564
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dzoneхотя у вас результат не в одну строчку и не через запятую :(
Ну ещё одна строка кода - и результат будет испорчен таким образом, только вот зачем?
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38023886
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Goffmanкто подскажет куда копать Они ж у Вас осортированы ! Берите первый и последний элементы. Между ними ставьте черточку.
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38024095
dzone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerdzone, как сложно-то.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 
Connected as test
 
SQL> with
  2    data as (select 'VM3529,VM3530,VM3531,VM3532,VM3533,VM3534,VM3493,VM3494,VM3495,VM3496,VM3497,VM3498' s# from dual),
  3    d1 as (select s#, instr(',' || s#, ',', 1, rownum) p1, instr(s# || ',', ',', 1, rownum) - 1 p2 from data connect by rownum <= 12),
  4    d2 as (select substr(s#, p1, p2 - p1 + 1) v# from d1),
  5    d3 as (select v#, translate(upper(v#), '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789') n# from d2)
  6  select min(v#) || ' - ' || max(v#) result
  7  from d3
  8  group by n# - rownum;
 
RESULT
--------------------------------------------------------------------------------
VM3529 - VM3534
VM3493 - VM3498
 




Ваш метод конечно красивее, вот написал ее на шарпе

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 string[] somedata = "VM3529,VM3530,VM3531,VM3532,VM3533,VM3534,VM3493,VM3494,VM3495,VM3496,VM3497,VM3498".Split(',');
 List<Int32> digits = somedata.Select(s => Int32.Parse(Regex.Match(s, @"\d+").Value)).ToList();
 List<Int32> grpdigits = digits.Select(d =>  d - digits.IndexOf(d)).ToList();
 Int32[] groupeddigits = grpdigits.GroupBy(d => d).Select(d => grpdigits.IndexOf(d.Key)).ToArray();         
 for (int i = 0; i < groupeddigits.Count(); i++)
     {
     Console.WriteLine(String.Concat(somedata[groupeddigits[i]], " - ",
                    groupeddigits.Count() - 1 > groupeddigits[i] ? somedata[groupeddigits[groupeddigits.Count() - 1]-1] : somedata[somedata.Length - 1]));
      }      
        
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38024100
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GoffmanБывают более сложные варианты, например т.н. шахматка
A1Б1, А1Б2, A2Б1, А2Б2, А3Б1, А3Б2
получается
А1Б1 - А3Б2 Эту задачу можно решить только при помощи графов (деревьев)
...
Рейтинг: 0 / 0
заменить последовательность диапазоном
    #38026335
Goffman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВСЕМ СПАСИБО ЗА ПОМОЩЬ,
особенно Softwarer'у

для универсальности, немного модернизировал запрос, вот что получилось
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 
Connected as grpo
 
SQL> 
SQL> with
  2     data as (select 'AA8,AA9,AA3528,VM3529,VM3530,VM3531,VM3532,VM3533,VM3534,VM3493,VM3494,VM3495,VM3496,VM3497,VM3498,VM6666,AA7,A1B3,A1B4' s# from dual),
  3     d1 as (select s#, instr(',' || s#, ',', 1, rownum) p1, instr(s# || ',', ',', 1, rownum) - 1 p2 from data connect by rownum <= 19),
  4     d2 as (select substr(s#, p1, p2 - p1 + 1) v# from d1),
  5     d3 as (select d2.v#, case when regexp_like(d2.v#, '^\D+\d+$') then 1 else 0  end  masked from d2),
  6     d4 as (select d3.*, decode(d3.masked,1,regexp_substr(v#,'^\D+'),v#)base ,decode(d3.masked,1,regexp_substr(v#,'\d+$'),null)*1  num from d3),
  7     d5 as (select d4.*, num-rownum r# from (select * from d4 order by base,num) d4),
  8     d6 as (select decode(count(*),1, base||min(num), base||min(num)||'-'||base||max(num)) result  from d5 group by base,r#),
  9     d7 as (select result, row_number() over (order by result) rn from d6),
 10     d8 as (select row_number() over (order by rn desc) rn , ltrim(sys_connect_by_path(result,','), ',') result  from d7  connect by rn=prior  rn+1  start with rn=1 )
 11  select result from d8 where rn =1
 12  /
 
RESULT
--------------------------------------------------------------------------------
A1B3,A1B4,AA3528,AA7-AA9,VM3493-VM3498,VM3529-VM3534,VM6666
 
SQL> 
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Программирование [игнор отключен] [закрыт для гостей] / заменить последовательность диапазоном
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]