Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
второй вариант что-то вроде
2 try
  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.002 c
2-1472651923
Анна
2016-08-31 16:58
2018.10.21
Удалилась БД


2-1472826405
hei
2016-09-02 17:26
2018.10.21
Property не читает значение поля


2-1473244823
валя
2016-09-07 13:40
2018.10.21
чтение запись строки из файла


2-1472882501
RusSun
2016-09-03 09:01
2018.10.21
Как быстро узнать что в строке одни нули?


1-1359522126
Vasya
2013-01-30 09:02
2018.10.21
Virtual Treeview как скрыть строку





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский