Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
ora600
Member

Откуда: Москва
Сообщений: 289
CREATE OR REPLACE FUNCTION for_firststeps(
a VARCHAR2)
RETURN VARCHAR2
IS
 RETURN 'kcah';
END;
/
17 фев 05, 00:15    [1326598]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18484
И ведь действительно можно без встроенных функций ;-)
17 фев 05, 01:43    [1326642]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
SergLet
Member

Откуда: .. темная сторона.
Сообщений: 6162
Хм, ... в точку попал ! Но вот предпоследнее это глупость уже!
17 фев 05, 09:53    [1326987]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
ktv2003
Member

Откуда: Краснодар
Сообщений: 1283
Markelenkov
"Преимущество этого метода в простоте. Берется достаточно обширный текст, скажем, «Жизнь животных» Брема в пяти томах. Машкин садится за свой агрегат и начинает печатать слово за словом, строчку за строчкой, страницу за страницей. При этом анализатор агрегата будет анализировать, думатель... – у ей внутре ведь есть, кажется, думатель? – ...думатель будет думать, и таким образом агрегат станет у вас обучаться. Вы и ахнуть не успеете, как он у вас начнет сам печатать. Вот вам рубль подъемных, и ступайте в библиотеку за Бремом..."

А. и Б. Стругацкие, "Сказка о Тройке"




5 баллов.. валяюсь просто............................
17 фев 05, 10:43    [1327170]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
vecna
Member

Откуда: msc
Сообщений: 234
Ладно, я расскажу идею правильного варианта... =)
На самом деле формулировку можно более интересную придумать.
Ввести последовательноть символов, и выввести ее наоборот без использования любох массивов...

делается это с помощью рекурсии

proc (str) {
if str is empty then exit;
proc(substr(str,1)); -- строка без первого символа
print(str[0]); -- первый символ
}
17 фев 05, 12:13    [1327546]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Владимор Конев
Member

Откуда:
Сообщений: 3451
vecna
Ладно, я расскажу идею правильного варианта... =)
На самом деле формулировку можно более интересную придумать.
Ввести последовательноть символов, и выввести ее наоборот без использования любох массивов...

делается это с помощью рекурсии

proc (str) {
if str is empty then exit;
proc(substr(str,1)); -- строка без первого символа
print(str[0]); -- первый символ
}


Рекурсия на PL/SQL???
17 фев 05, 12:21    [1327591]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18484
Почему нет?
tst> set serveroutput on
tst> declare
  2  procedure rev(str in varchar2) is
  3  begin
  4  if length(str) is null then return; end if;
  5  rev(substr(str, 2));
  6  dbms_output.put(substr(str, 1, 1));
  7  return;
  8  end;
  9  begin
 10  rev('hack');
 11  dbms_output.put_line('');
 12  end;
 13  /
kcah

PL/SQL procedure successfully completed.
17 фев 05, 12:29    [1327625]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Владимор Конев
Member

Откуда:
Сообщений: 3451
Вячеслав Любомудров
Почему нет?
tst> set serveroutput on
tst> declare
  2  procedure rev(str in varchar2) is
  3  begin
  4  if length(str) is null then return; end if;
  5  rev(substr(str, 2));
  6  dbms_output.put(substr(str, 1, 1));
  7  return;
  8  end;
  9  begin
 10  rev('hack');
 11  dbms_output.put_line('');
 12  end;
 13  /
kcah

PL/SQL procedure successfully completed.


О, как! :-)
17 фев 05, 12:38    [1327669]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Andrew Max
Member

Откуда:
Сообщений: 1045
Забавный конкурс. Интересно: а автор это всерьез затеял?

Вот вариант решения без стандартных функций. Только не подумайте, что я люблю подобные извращения. В жизни никогда такого писать не буду.

Для начала надо небольшую вспомогательную табличку создать (две с половиной сотни строк):

SQL*Plus: Release 9.2.0.6.0 - Production on Чтв Фев 17 12:22:38 2005

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Введите имя пользователя: max
Введите пароль:

Присоединен к:
Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 9.2.0.6.0 - Production

SQL> create table symbols(symbol varchar2(1));

Таблица создана.

SQL> insert into symbols select chr(rownum)
  2   from all_objects where rownum <= 255;

255 строк создано.

SQL> delete from symbols where symbol in ('_', '%');

2 строк удалено.

SQL> commit;

Фиксация обновлений завершена.

Ах, да... Совсем забыл. Нам же нельзя пользоваться встроенными функциями, а я тут вдруг – CHR Ну, при желании эту табличку можно заполнить не в цикле, а ручками, написав двести с лишним операторов INSERT. В общем, будем считать, что некто так и поступил.
Идем далее. В нашей основной функции нам просто не обойтись без некоторого способа нахождения длины строки. Эх, жаль, стандартную Length нельзя использовать. Ну, и ладно, напишем свою:

SQL> create or replace function IdioticLength(s in varchar2) return integer is
  2   d varchar2(32767);
  3   cnt integer;
  4   flag boolean;
  5  begin
  6   d := s;
  7   cnt := 0;
  8   flag := false;
  9   while not flag loop
 10    begin
 11      d := d || '$';
 12      cnt := cnt + 1;
 13    exception
 14      when others then flag := true;
 15    end;
 16   end loop;
 17   return 32767 - cnt;
 18  end;
 19  /

Функция создана.

Проверим, все ли в порядке:

SQL> select Idioticlength('') as Marazm from dual;

    MARAZM
----------
         0

SQL> select Idioticlength('12345') as Marazm from dual;

    MARAZM
----------
         5

Вроде как работает. Ну, и хорошо. Теперь – основная функция, выполняющая «переворот» строки:

SQL> create or replace function IdioticReverse(s in varchar2) return varchar2 is
  2   strlen integer;
  3   cnt integer;
  4   after_mask varchar2(32767);
  5   before_mask varchar2(32767);
  6   cur varchar2(1);
  7   res varchar2(32767);
  8  begin
  9   res := '';
 10   strlen := IdioticLength(s);
 11   for i in 1..strlen loop
 12     after_mask := '';
 13     before_mask := '';
 14     for j in 1..i-1 loop
 15       after_mask := after_mask || '_';
 16     end loop;
 17     for j in i+1..strlen loop
 18       before_mask := before_mask || '_';
 19     end loop;
 20     begin
 21       execute immediate
 22        'select symbol from symbols
 23          where exists (select 0 from dual where :A like :B || symbol || :C)'
 24        into cur using s, before_mask, after_mask;
 25     exception
 26       when others then
 27         begin
 28           execute immediate
 29            'select count(1) from dual where :A like :B escape :C'
 30            into cnt using s, before_mask || '@_' || after_mask, '@';
 31           if cnt = 1 then cur := '_'; else cur := '%'; end if;
 32         end;
 33     end;
 34     res := res || cur;
 35   end loop;
 36   return res;
 37  end;
 38  /

Функция создана.

Ну вот, собственно, и все. Кратко, а главное – очень полезно на практике. Я уверен, что многие теперь непременно будут пользоваться этой функцией в своем коде.

Пара тестовых запусков:

SQL> column Marazm format a80;
SQL> set timing on
SQL> select IdioticReverse('ABCDEFGHIJKLMNO_АБВГДЕЖЗИКЛМНОПРСТ%1234567890')
  2   as Marazm from dual;

MARAZM
--------------------------------------------------------------------------------
0987654321%ТСРПОНМЛКИЗЖЕДГВБА_ONMLKJIHGFEDCBA

Затрач.время: 00:00:00.03
SQL> select IdioticReverse('qwerty % _ фывапролдж')
  2   as Marazm from dual;

MARAZM
--------------------------------------------------------------------------------
ждлорпавыф _ % ytrewq

Затрач.время: 00:00:00.02

Я ничего не упустил? Кстати, согласно официальной документации, || - это оператор конкатенации, а операторами нам вроде никто пользоваться не запрещал.

P.S. Спасибо автору темы. Давно так не веселился.
17 фев 05, 13:01    [1327812]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
SkyNet77
Guest
ktv2003
Markelenkov
"Преимущество этого метода в простоте. Берется достаточно обширный текст, скажем, «Жизнь животных» Брема в пяти томах. Машкин садится за свой агрегат и начинает печатать слово за словом, строчку за строчкой, страницу за страницей. При этом анализатор агрегата будет анализировать, думатель... – у ей внутре ведь есть, кажется, думатель? – ...думатель будет думать, и таким образом агрегат станет у вас обучаться. Вы и ахнуть не успеете, как он у вас начнет сам печатать. Вот вам рубль подъемных, и ступайте в библиотеку за Бремом..."

А. и Б. Стругацкие, "Сказка о Тройке"




5 баллов.. валяюсь просто............................

Присоединяюсь
17 фев 05, 13:49    [1328062]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Stax
Guest
5 (по новому 12)
Andrew Max

Я ничего не упустил?

CHR(0) заменило на %
--------::::))))))))
17 фев 05, 13:51    [1328081]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Andrew Max
Member

Откуда:
Сообщений: 1045
Stax
CHR(0) заменило на %

Ой...
Щас починим.

SQL> insert into symbols values(chr(0));

1 строка создана.

SQL> commit;

Фиксация обновлений завершена.

SQL> select IdioticReverse(CHR(0)) as MARAZM from dual;

MARAZM



SQL> select IdioticReverse('H' || CHR(0) || 'A' || chr(0) || 'C' || chr(0) || 'K')
  2   as MARAZM from dual;

MARAZM

K C A H

17 фев 05, 14:19    [1328192]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Stax
Guest

Ой...
Щас починим.

Спасиб, буду пользовать, осталось гранты раздать
17 фев 05, 15:15    [1328416]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
AI
Member

Откуда: Москва
Сообщений: 2817
Stax

Ой...
Щас починим.

Спасиб, буду пользовать, осталось гранты раздать


Рано пользовать, что делать с юникодными символами?

Может, закроем эту тему?
17 фев 05, 15:23    [1328453]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Андрей Владимирович 83
Guest
SergLet,
SELECT replace(wm_concat(c),',','')
FROM (
SELECT LEVEL , SUBSTR('Доброе утро',LEVEL, 1) c
FROM dual CONNECT BY LEVEL<=LENGTH('Доброе утро')
ORDER BY 1 DESC
);
15 фев 13, 11:57    [13930855]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Андрей Владимирович 83,

из мортиры по одинокому микробу
15 фев 13, 12:12    [13930944]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Добрый Э - Эх
Guest
orawish,

да фиг с ними, с мортирой и микробом. Главное - так своевременно. Автор же 8 лет сидит тут и ждет правильного ответа
З.Ы.
Я с тех пор успел сменить три синих учетки и стать анонимом... ;)
15 фев 13, 12:37    [13931125]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
Андрей Владимирович 83
SergLet,
SELECT replace(wm_concat(c),',','') 
FROM (
	SELECT LEVEL , SUBSTR('Доброе утро',LEVEL, 1) c 
	FROM dual CONNECT BY LEVEL<=LENGTH('Доброе утро') 
	ORDER BY 1 DESC
);


Так вот ты какой, PL/SQL...
15 фев 13, 18:54    [13933967]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
Lecter
Member

Откуда: Киев
Сообщений: 2032
suPPLer
Так вот ты какой, PL/SQL...


И не говори, как я заблуждался все эти годы.
15 фев 13, 19:04    [13934015]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Чисто теоретически можно и без функций:
create table t0 (a varchar2(4000) primary key, b varchar2(4000));
insert into t0 ('a', 'a');
insert into t0 ('b', 'b');
insert into t0 ('ab', 'ba');
....
commit;
select b from t0 where a = input_string;
15 фев 13, 20:14    [13934342]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
Или plsql аналог (про ограничения не говорим):
create function reverse2 (input_string varchar2) return varchar2 is
begin
   return case input_string when 'a' then 'a' when 'b' then 'b' when 'ab' then 'ba' ... end;
end;
15 фев 13, 20:17    [13934356]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
_Nikotin,

хранимая биекция множества всех возможных строк (даже в SQL, где они пока ещё ограничены длиной в 4000 байт) -- это чересчур. Даже для пятницы.
15 фев 13, 20:26    [13934383]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 5151
_Nikotin
Чисто теоретически можно и без функций
Более увлекательно было бы посчитать сколько байт надо для хранения всех таких комбинаций, если представить что комбинация требует столько же байт для хранения сколько букв.

Ну а все условия автора можно соблюсти если написать процедуру на C/Java и вызывать ее из PL/SQL.

Если же хочется без строковых функций, то можно с определенными ограниченими так (от chr, lpad здесь можно избавиться):
select listagg(chr(mod(trunc(to_number(rawtohex(str),lpad('x', 63, 'x'))/power(256,level-1)),256))) within group (order by level) str
from (select 'Hello world' str from dual) connect by level <= length(rawtohex(str));

STR
--------------------------------------------------------------------------------
dlrow olleH
15 фев 13, 21:17    [13934549]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
dbms_photoshop
Более увлекательно было бы посчитать сколько байт надо для хранения всех таких комбинаций, если представить что комбинация требует столько же байт для хранения сколько букв.

Если считать алфавит состоящим из 256 состояний байта и забыть про байты длины, структуру блока и прочие издержки, то считается просто. Это сумма N первых членов геометрической прогрессии, где первый член и знаменатель прогрессии равны 256, а N равно максимальной длине строки. Для 4000 это:


Ерунда, сейчас пару солнечных систем под хранение отведём, и порядок.
15 фев 13, 22:46    [13934860]     Ответить | Цитировать Сообщить модератору
 Re: Переворот строки с помощью PL/SQL! Конкурс!  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
suPPLer,

Это по-больше числа атомов в видимой части вселенной :-)
16 фев 13, 00:47    [13935245]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Oracle Ответить