Форум: "Начинающим";
Текущий архив: 2018.10.21;
Скачать: [xml.tar.bz2];
ВнизКак быстро узнать что в строке одни нули? Найти похожие ветки
← →
RusSun © (2016-09-03 09:01) [0]Сабж.
← →
RusSun © (2016-09-03 09:02) [1]Строка тип String.
← →
RusSun © (2016-09-03 09:17) [2]"Пришло" пока только два "варианта".
1 сравнивать от символа к символу. И в конце result:=true/false
второй вариант что-то вроде
2try
result:=false;
if StrToInt(s) = 0 then
result:=true
finally end; //of finally
Есть ли ещё?
← →
Leonid Troyanovsky © (2016-09-03 09:53) [3]
> RusSun © (03.09.16 09:17) [2]
> к символу. И в конце result:=true/false
Не в конце, а до первого несовпадения.
Ну, и сравнивать можно сразу по 4 (or 8) байт.
--
Regards, LVT.
← →
Игорь Шевченко © (2016-09-03 10:52) [4]
> finally end; //of finally
Ты зачем так пишешь ? Не надо.
Если надо быстро, заведи длинный образец и сравнивай с ним быстрой функцией сравнения.
← →
RusSun © (2016-09-03 11:26) [5]to Игорь Шевченко
> finally end; //of finally
> Ты зачем так пишешь ? Не надо.
потому Не часто пользуюсь, try http://www.delphibasics.ru/Try.php,
что не означает, что так как я написал верно и так всем надо делать. =)
to Leonid Troyanovsky,Игорь Шевченко.
1ое можно код.
2ое строка имеет переменную длину.
С уважением, RusSun.
← →
RusSun © (2016-09-03 12:00) [6]
> быстрой функцией сравнения.
можно по точнее
← →
Leonid Troyanovsky © (2016-09-03 14:53) [7]
> RusSun © (03.09.16 11:26) [5]
function IsStringMonoChar(const s: String; c: Char): Boolean;
var
i, k, L: Longint;
p: PChar;
t: array [0..3] of Char;
begin
L := Length(s);
Result := L > 0;
if not Result then
Exit;
p := PChar(s);
FillChar(t, 4, c);
k := L div 4;
for i := 0 to k-1 do
begin
Result := PLongint(p)^ = PLongint(@t)^;
if not Result then
Exit;
inc(p, 4);
end;
k := L mod 4;
for i := L-k+1 to L do
begin
Result := s[i] = c;
if not Result then
Exit;
end;
end;
no tested.
--
Regards, LVT.
← →
Игорь Шевченко © (2016-09-03 18:50) [8]RusSun © (03.09.16 11:26) [5]
Примерно так:const
Zeros: PChar = "00000000000000000000000000000000000000000000000000"; //Сколько надо по длине
function TestStringsForZeros (const Source: string): Boolean; inline;
begin
Result := CompareMem(PChar(Source), Zeros, Length(Source));
end;
← →
Sha © (2016-09-03 22:55) [9]Так тоже должно быть довольно быстро, хотя и не очень красиво, наверное:
function IsBufferOfByte(pBuf: pointer; Len: integer; Value: byte): boolean;
var
Mask: cardinal;
label
ExitFalse;
begin;
if Len=0 then goto ExitFalse;
Mask:=Value * $01010101;
while Len>=4 do begin;
if pCardinal(pBuf)^<>Mask then goto ExitFalse;
inc(pCardinal(pBuf));
dec(Len,4);
end;
if (Len=0) or ((pCardinal(pBuf)^ xor Mask) shl ((4-Len) shl 3)=0) then begin;
Result:=true;
exit;
end;
ExitFalse:
Result:=false;
end;
Использовать так:
var
s: string;
begin;
s:="aaaaa";
Result:=IsBufferOfByte(pointer(s),Length(s),byte("a")))));
end;
← →
sniknik © (2016-09-04 01:48) [10]быстро, красиво, ... надо проще делать.
function TestStringsForZeros(const Source: string; Count: integer): Boolean;
begin
Result:= Source = StringOfChar("0", Count);
end;
← →
sniknik © (2016-09-04 01:52) [11]а ну да, в оригиналном вопросе просто проверка на все нули, с неопределенной/заданной длиной, еще проще -
function TestStringsForZeros(const Source: string): Boolean;
begin
Result:= Source = StringOfChar("0", Length(Source));
end;
и кстати думаю довольно быстро будет.
← →
Sha © (2016-09-04 09:19) [12]> sniknik © (04.09.16 01:52) [11]
> и кстати думаю довольно быстро будет.
Думаю, в разы разница будет.
А если в [9] цикл развернуть, то и на порядок.
← →
Sha © (2016-09-04 11:36) [13]Вариант с развернутым циклом:
function IsBufferOfByte(pBuf: pointer; Len: integer; Value: byte): boolean;
const
Test: array[0..3] of cardinal= (0, $FF, $FFFF, $FFFFFF);
var
Mask: cardinal;
pEnd: pointer;
label
ExitFalse;
begin;
if Len=0 then goto ExitFalse;
Mask:=Value * $01010101;
pEnd:=@pIntegerArray(pBuf)[Len shr 3 * 2];
while pBuf<>pEnd do begin;
if Int64Rec(pBuf^).Lo<>Mask then goto ExitFalse;
if Int64Rec(pBuf^).Hi<>Mask then goto ExitFalse;
inc(pInt64(pBuf));
end;
if Len and 4<>0 then begin;
if Cardinal(pBuf^)<>Mask then goto ExitFalse;
inc(pCardinal(pBuf));
end;
Len:=Len and 3;
if (Len=0) or ((pCardinal(pBuf)^ xor Mask) and Test[Len]=0) then begin;
Result:=true;
exit;
end;
ExitFalse:
Result:=false;
end;
← →
Игорь Шевченко © (2016-09-04 12:05) [14]Дабы не утруждать мозг раздумиями:
Text: "000000000000", length: 12
Sha: 0,090 seconds to compare 10000000 times.
Sniknik: 0,635 seconds to compare 10000000 times.
Igor Schevchenko: 0,110 seconds to compare 10000000 times.
Text: "0", length: 1
Sha: 0,095 seconds to compare 10000000 times.
Sniknik: 0,561 seconds to compare 10000000 times.
Igor Schevchenko: 0,096 seconds to compare 10000000 times.
Text: "Edit1", length: 5
Sha: 0,090 seconds to compare 10000000 times.
Sniknik: 0,563 seconds to compare 10000000 times.
Igor Schevchenko: 0,090 seconds to compare 10000000 times.
← →
Игорь Шевченко © (2016-09-04 12:09) [15]Sha © (04.09.16 11:36) [13]
Кстати, на длинных строках у меня быстрее получается. Но не думаю, что автору нужно длинные строки сравниватьText: "0000000000000000000000000000000000000000000000000000000", length: 55
Sha: 0,167 seconds to compare 10000000 times.
Sniknik: 0,698 seconds to compare 10000000 times.
Igor Schevchenko: 0,143 seconds to compare 10000000 times.
← →
Sha © (2016-09-04 12:29) [16]> Игорь Шевченко © (04.09.16 12:09) [15]
В последних версиях Delphi, вероятно, так и будет
за счет инлайна и улучшенной функции сравнения.
А у меня (как и у автора) D7.
Там моя быстрее в 2 раза даже на длинных строках.
И мне не хочется думать, что это из-за не очень нового компа )
← →
manaka © (2016-09-04 12:44) [17]Удалено модератором
Примечание: Флудить завязывай
← →
Игорь Шевченко © (2016-09-04 12:48) [18]Sha © (04.09.16 12:29) [16]
> В последних версиях Delphi, вероятно, так и будет
Я проверял далеко на не последней, это проверялось на D2006. Кстати, на юникодных "0" это не байт.
← →
Sha © (2016-09-04 12:52) [19]> manaka © (04.09.16 12:44) [17]
Берем за образец что-нибудь вроде
function CharPos(ch: char; const s: string): integer;
var
i: integer;
begin;
for i:=1 to Length(s) do if s[i]=ch then begin;
Result:=i; exit;
end;
Result:=0;
end;
и делаем что-нибудь вроде
function NonBlankPos(const s: string): integer;
var
i: integer;
begin;
for i:=1 to Length(s) do if s[i]>#32 then begin; //или <>
Result:=i; exit;
end;
Result:=0;
end;
← →
Sha © (2016-09-04 12:57) [20]> Игорь Шевченко © (04.09.16 12:48) [18]
> Я проверял далеко на не последней, это проверялось на D2006.
ну значит там RTL уже поправлена
> Кстати, на юникодных "0" это не байт.
именно поэтому я так аккуратно и назвал свою функцию
← →
RusSun © (2016-09-04 13:43) [21]to All Спасибо большущее.
Строки от коротких ~16 до более длинных 64 и более символов.
тема закрыта.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2018.10.21;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.001 c