Текущий архив: 2004.01.16;
Скачать: CL | DM;
Вниз
Самый нестандартный алгоритм Найти похожие ветки
← →
Knight © (2003-12-22 15:14) [40]Упростите, кто-нибудь это... желательно без TStrArr...
type TStrArr=Array of String;
function Explode(Str:String):TStrArr;
var i,k,Len:Integer;
begin
Result:=nil;
Len:=Length(Str);
if Len>0 then begin
k:=1;
for i:=2 to Len+1 do begin
if (i=Len+1) or (Str[i]=Str[1]) then begin
SetLength(Result,Length(Result)+1);
Result[High(Result)]:=Copy(Str,k+1,i-k-1);
k:=i;
end;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var A:TStrArr;
i:Integer;
begin
Memo1.Clear;
A:=Explode(false," Имеется переменная String как ее разбить на символы?");
for i:=0 to Length(A)-1 do Memo1.Lines.Append(A[i]);
A:=nil;
end;
← →
Sha © (2003-12-22 15:18) [41]Сколько параметров у Explode?
← →
Knight © (2003-12-22 15:42) [42]>> Sha © (22.12.03 15:18) [41]
> Сколько параметров у Explode?
Можно добавить символ разделителя (у меня он передаётся, как первый символ разбиваемой строки). Остальное не важно, лишь бы работало и без дополнительных типов.
← →
Sha © (2003-12-22 15:50) [43]> Sha © (22.12.03 15:18) [41]
> Сколько параметров у Explode?
> Knight © (22.12.03 15:42) [42]
> Можно добавить символ разделителя
Похоже, обсуждение будет долгим... :)
Заведи свою ветку.
← →
clickmaker © (2003-12-22 15:54) [44]SetLength(Result,Length(s));
for i := 1 to Length(s) do Result[(Length(s) - i) + 1] := s[i];
← →
Knight © (2003-12-22 16:17) [45]>> Sha © (22.12.03 15:50) [43]
Не хотел, ну да ладно... сделал :)
← →
IceBeerg © (2003-12-22 18:25) [46]Исчо вариант: (всесь кусок приводить небуду, только суть)
asm
...
push Stroka1[num] ...
...
pop Stroka2[num] ...
...
end;
← →
Sha © (2003-12-22 19:38) [47]> IceBeerg © (22.12.03 18:25) [46]
А num - это переменная или константа?
Если переменная, то так низя,
а если константа, то сколько точно строчек в твоей программе?
← →
VEG © (2003-12-22 20:01) [48]>>[9] XHelp © (22.12.03 03:06)
:) Приз за оригинальность! Оригинальнее еще не видел!
>>[12] kaif © (22.12.03 10:27)
Дополнительный буффер для смены местами букв не обязателен. Смотри выше [3] XHelp © (22.12.03 02:40) и [5] VEG © (22.12.03 02:43) - там два метода. Через xor чуть медленнее, чем с буффером, через + медленнее где-то на 15%, чем с xor.
>>[15] Евлампия (22.12.03 10:37)
Конечно, оригинальные решения получились. Но алгоритм может реализовываться не в виже функции, а линейно прямо в основном коде, поэтому в result можно только возвращать можифицированную строку s.
>>All
Придумал самый извращенный метод. Вот генератор этого кода.
const
STR_MAX_LENGTH=-2*1024*1024*1024;//2Gb
var
fOutput: TextFile;
iFtd: longint;
begin
AssignFile(fOutput, "sreverse.inc");
try
ReWrite(fOutput);
WriteLn(fOutput, "function StrReverse(sInput: string): string;");
WriteLn(fOutput, "var");
WriteLn(fOutput, " s: string;");
WriteLn(fOutput, " begin");
WriteLn(fOutput, " s:=sInput;");
for iFtd:=1 to Abs(STR_MAX_LENGTH) do
begin
WriteLn(fOutput, " if length(s)-"+IntToStr(iFtd)+"+1>"+IntToStr(iFtd)+" then");
WriteLn(fOutput, " begin");
WriteLn(fOutput, " s["+IntToStr(iFtd)+"]:=chr(ord(s["+IntToStr(iFtd)+"]) xor ord(s[length(s)-"+IntToStr(iFtd)+"+1]));");
WriteLn(fOutput, " s[length(s)-"+IntToStr(iFtd)+"+1]:=chr(ord(s["+IntToStr(iFtd)+"]) xor ord(s[length(s)-"+IntToStr(iFtd)+"+1]));");
WriteLn(fOutput, " s["+IntToStr(iFtd)+"]:=chr(ord(s["+IntToStr(iFtd)+"]) xor ord(s[length(s)-"+IntToStr(iFtd)+"+1]));");
WriteLn(fOutput, " end;");
end;
WriteLn(fOutput, " StrReverse:=s;");
WriteLn(fOutput, " end;");
finally
CloseFile(fOutput)
end;
end;
Буду удивлен, если у кого-то хватит места на жестком диске под этот инклюд. Математические подсчеты подсказывают, что он будет весить порядка 500Gb (2Gb*211b+106b=494Gb
). Хе-хе.
← →
Sha © (2003-12-22 20:08) [49]>VEG © (22.12.03 20:01) [48]
var
fOutput: TextFile;
iFtd: longint;
А как быть с запретом на дополнительные переменные?
← →
VEG © (2003-12-22 20:19) [50]>>Sha
Я привел код генерации функции. Саму функцию привести нет возможности... А в генерируемой функции нет никаких лишних переменных.
← →
Ангел. © (2003-12-22 20:35) [51]s:=AnsiReverseString(s);
Ничего невижу..
Ничего неслышу...
Ничего неговорю...
← →
VEG © (2003-12-22 21:41) [52]>[51] Ангел. © (22.12.03 20:35)
Имелось ввиду написание собственного алгоритма.
← →
Sha © (2003-12-23 11:09) [53]>VEG © (22.12.03 20:01) [48]
WriteLn(fOutput, "var");
WriteLn(fOutput, " s: string;");
Все-таки, как быть с запретом на дополнительные переменные?
← →
Igorek © (2003-12-23 13:13) [54]
procedure Reverse(var S: String);
begin
SetLength(S, Length(S) + 2);
S[Length(S) - 1] := char(0);
//S[Length(S)] - для обмена
//S[Length(S) - 1] - для цикла
while Integer(S[Length(S) - 1]) <= ((Length(S) - 1) div 2) do
begin
S[Length(S)] := S[Integer(S[Length(S) - 1])];
S[Integer(S[Length(S) - 1])] := S[Length(S) - 1 - Integer(S[Length(S) - 1])];
S[Length(S) - 1 - Integer(S[Length(S) - 1])] := S[Length(S)];
S[Length(S) - 1] := char(Integer(S[Length(S) - 1]) + 1);
end;
SetLength(S, Length(S) - 2);
end;
Правда для коротких строк.
← →
Sha © (2003-12-23 13:28) [55]> Igorek © (23.12.03 13:13) [54]
Отлично.
Попробуй реализовать похожую идею для такого объявления
function Reverse(const s: string): string;
и для строк максимальной длины, допустимой компилятором.
← →
Igorek © (2003-12-23 13:42) [56]
> Sha © (23.12.03 13:28) [55]
> Попробуй реализовать похожую идею для такого объявления
> function Reverse(const s: string): string;
> и для строк максимальной длины, допустимой компилятором.
Во-первых такое обьявление не соответствует условию - Result - неявная переменная. Во-вторых уже есть решение от Евлампии.
А если все таки реализовать
procedure Reverse(var S: String);
для больших строк, то возникают нюансы:
- если строка максимально длинная, то ничего больше выкроить мы не сможем
- если нет, то должно оставаться место на символ для обмена и переменную цикла (под нее можно отвести несколько символов (log(256,Length(S))) и делать что-то типа 256^2*(s-2)+256*(s-1)+s ) - уже лень писать
← →
Sha © (2003-12-23 13:50) [57]> Igorek © (23.12.03 13:42) [56]
> Во-первых такое обьявление не соответствует условию - Result - неявная переменная
Но не дополнительная :)
> для больших строк, то возникают нюансы:
> - если строка максимально длинная, то ничего больше выкроить мы не сможем
> - если нет, то должно оставаться место на символ для обмена и переменную цикла
Ничего выкраивать не надо, можно использовать поле длины строки.
Можно обойтись без символа обмена, как Евлампия.
В качестве иллюстрации, как тебе такой цикл:
while (pinteger(pchar(pointer(Result))[-4]))^>0 do
dec((pinteger(pchar(pointer(Result))[-4]))^);
← →
Sha © (2003-12-23 14:22) [58]> Igorek © (23.12.03 13:42) [56]
Для случаяprocedure Reverse(var S: String);
в качестве переменной цикла можно использовать поле счетчика ссылок, а обмен выполнять xor-ом.
Оба полученных решения (и procedure, и function) будут во много раз быстрее решения Евлампии
← →
VEG © (2003-12-23 17:38) [59]>>[49] Sha © (22.12.03 20:08)
Можно сразу с Result работать:)
← →
Sha © (2003-12-23 17:44) [60]> VEG © (23.12.03 17:38) [59]
STR_MAX_LENGTH=-2*1024*1024*1024;//2Gb
var
iFtd: longint;
begin
...
for iFtd:=1 to Abs(STR_MAX_LENGTH)
Сомнения берут насчет работоспособности цикла...
← →
VEG © (2003-12-23 20:18) [61]>[60] Sha © (23.12.03 17:44)
Чего же тут неработоспособного?
← →
VEG © (2003-12-23 20:25) [62]>[60] Sha © (23.12.03 17:44)
Ooops! One moment!
← →
VEG © (2003-12-23 20:29) [63]
const
STR_MAX_LENGTH=-2*1024*1024*1024;//2Gb
var
fOutput: TextFile;
iFtd: int64 ;
Дальше по тексту...
← →
Mihey © (2003-12-23 20:32) [64]Не надо переворачивать. За то при чтении можно читать с конца.
← →
Sha © (2003-12-23 23:46) [65]> VEG © (22.12.03 20:01) [48]
Еще одно замечание.
Размер твоей проги без ущерба для результата
можно уменьшить ровно в два раза, если сделать
STR_MAX_LENGTH = -1024*1024*1024;
← →
Sha © (2003-12-24 01:00) [66]> VEG © (22.12.03 20:01) [48]
> Igorek © (23.12.03 13:13) [54]
Напоследок.
procedure ForIgorek(var s: string);
begin;
UniqueString(s);
if Length(s)>0 then begin;
(pinteger(pchar(pointer(s))-8))^:=Length(s) shr 1;
while (pinteger(pchar(pointer(s))-8))^>0 do begin;
byte(pchar(pointer(s))[(pinteger(pchar(pointer(s))-8))^-1]):=
byte(pchar(pointer(s))[(pinteger(pchar(pointer(s))-8))^-1])
xor byte(pchar(pointer(s))[Length(s)-(pinteger(pchar(pointer(s))-8))^]);
byte(pchar(pointer(s))[Length(s)-(pinteger(pchar(pointer(s))-8))^]):=
byte(pchar(pointer(s))[Length(s)-(pinteger(pchar(pointer(s))-8))^])
xor byte(pchar(pointer(s))[(pinteger(pchar(pointer(s))-8))^-1]);
byte(pchar(pointer(s))[(pinteger(pchar(pointer(s))-8))^-1]):=
byte(pchar(pointer(s))[(pinteger(pchar(pointer(s))-8))^-1])
xor byte(pchar(pointer(s))[Length(s)-(pinteger(pchar(pointer(s))-8))^]);
dec((pinteger(pchar(pointer(s))-8))^);
end;
(pinteger(pchar(pointer(s))-8))^:=1;
end;
end;
← →
Igorek © (2003-12-24 01:18) [67]
> Sha © (24.12.03 01:00) [66]
> Напоследок.
>
> procedure ForIgorek(var s: string);
...
Да, серьезно ты занялся этим делом. Поди пол рабочего и пол домашнего дня угробил. :-)))
← →
Sha © (2003-12-24 10:17) [68]Igorek © (24.12.03 01:18) [67]
5 мин. Серьезно. Просто давно этим занимаюсь.
Страницы: 1 2 вся ветка
Текущий архив: 2004.01.16;
Скачать: CL | DM;
Память: 0.61 MB
Время: 0.341 c