Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / заменить последовательность диапазоном / 18 сообщений из 18, страница 1 из 1
02.11.2012, 12:13
    #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
02.11.2012, 12:16
    #38023131
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
В циклы копать. При чем написать алгоритм быстрее, чем написать на форум и ждать ответа хотя-бы минут 5.
...
Рейтинг: 0 / 0
02.11.2012, 12:50
    #38023206
Goffman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
wadman написать алгоритм быстрее, чем написать на форум и ждать ответа хотя-бы минут 5.
Не уверен, задача довольно нетривиальная, осложняется тем, что номера могут быть такие:
VST45 - VST123
...
Рейтинг: 0 / 0
02.11.2012, 12:57
    #38023219
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
Goffman , задача - тривиальная.

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

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

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

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

сначала определитесь, а потом спрашивайте... А то щас обсуждать начнём, а окажется, что у вас номер может записываться иероглифом или римскими числами, а ещё потом в двоичной системе в перемешку с буквами... )))
Минимум: приведите реальный список, который будет, и то, что из такого списка получить надо
...
Рейтинг: 0 / 0
02.11.2012, 14:01
    #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
02.11.2012, 14:05
    #38023354
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
AkinaЕсли предположить (форум, всё-таки, SQL.RU), что средствами SQL - следует отказаться от свёртки диапазонов в пользу нормализации данных.
Сегодня уже не составляет проблемы свернуть диапазон средствами SQL. По крайней мере, нормального SQL.
...
Рейтинг: 0 / 0
02.11.2012, 14:34
    #38023416
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
softwarerСегодня уже не составляет проблемы свернуть диапазон средствами SQL. По крайней мере, нормального SQL.Свернуть - да. Использовать, особенно если быстродействие критично - далеко не всегда.
...
Рейтинг: 0 / 0
02.11.2012, 14:46
    #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
02.11.2012, 15:00
    #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
02.11.2012, 15:20
    #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
02.11.2012, 15:37
    #38023546
dzone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
softwarer,

)) согласен, можно и по красивее написать, будет кода поменьше. хотя у вас результат не в одну строчку и не через запятую :(
...
Рейтинг: 0 / 0
02.11.2012, 15:46
    #38023564
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
dzoneхотя у вас результат не в одну строчку и не через запятую :(
Ну ещё одна строка кода - и результат будет испорчен таким образом, только вот зачем?
...
Рейтинг: 0 / 0
02.11.2012, 18:58
    #38023886
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
Goffmanкто подскажет куда копать Они ж у Вас осортированы ! Берите первый и последний элементы. Между ними ставьте черточку.
...
Рейтинг: 0 / 0
02.11.2012, 22:02
    #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
02.11.2012, 22:12
    #38024100
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
заменить последовательность диапазоном
GoffmanБывают более сложные варианты, например т.н. шахматка
A1Б1, А1Б2, A2Б1, А2Б2, А3Б1, А3Б2
получается
А1Б1 - А3Б2 Эту задачу можно решить только при помощи графов (деревьев)
...
Рейтинг: 0 / 0
06.11.2012, 10:34
    #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]