PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Найти число без регулярного выражения


Найти число без регулярного выражения

Сообщений 1 страница 6 из 6

1

Чисто экспериментирую идею. Небольшая прога на 100 кб хочется добавить поиск числа в тексте и тут встраивание регулярный выражений добавляет 100 кб к проге, хотя не используется активно.
Но вот думаю если подойти к поиску бинарно, то будет более оптимизировано. То есть считать очередной байт из памяти, а потом прочитать по указателю нужное число байтов.

Код:
EnableExplicit

Declare StrToArrLetter(Array Arr.s{1}(1), String$)
Global i, f, pos1 = 0, pos2 = 0
Global Dim Arr.s{1}(0)
Global TextFile$ = "можно проверить на десятичное число 34.89 или найти в тексте"

StrToArrLetter(Arr(), TextFile$)

Procedure StrToArrLetter(Array Arr.s{1}(1), String$)
	Protected LenStr, i
	LenStr = Len(String$)
	If LenStr
    ReDim Arr(LenStr - 1)
    PokeS(Arr(), String$, -1, #PB_String_NoZero)
	EndIf
	ProcedureReturn
EndProcedure


; Вывод результата
For i=0 To ArraySize(Arr())
	Select Arr(i)
    Case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."
    	f = 1
    Default
    	f = 0
	EndSelect
	If f And pos1 = 0
    pos1 = i+1
	EndIf
	If f = 0 And pos1
    pos2 = i+1
    Break
	EndIf
Next


If pos2 And pos1
	Debug Mid(TextFile$, pos1, pos2 - pos1)
EndIf

0

2

Когда то было нужно подобное.  Только нужно было искать все числа в строке и не реагировать на точки вне чисел.
Посмотри идею, может пригодится для опытов:

Код:
Procedure IsDigits(s.s,StartPosition =1)
   For i=StartPosition To Len(s)
     If Asc(Mid(s,i,1))=46  Or (Asc(Mid(s,i,1))>=48 And Asc(Mid(s,i,1))<=57) 
       If Asc(Mid(s,i,1))=46 And i = Len(s):ProcedureReturn 0:EndIf
       If Asc(Mid(s,i,1))=46 And (Asc(Mid(s,i+1,1))<48 Or Asc(Mid(s,i+1,1))>57) :ProcedureReturn 0:EndIf
         ProcedureReturn i
        EndIf
   Next 
  ProcedureReturn 0
EndProcedure

 ;__________TEST_____________
 TextFile$ = "можно проверить 12345.09 на  десятичное число 22.45  или  найти 33.55 в тексте."
 ; Проверка на число
 If IsDigits(TextFile$): Debug "Есть число": Else: Debug "Нет числа": EndIf
 
 ; Поиск всех чисел
 For d = 1 To Len(TextFile$)
   i=d
   d = IsDigits(TextFile$,d)
   If d:
     If d-i>1: Dig$ +" " :EndIf; знак раздела пробел
     Dig$ + Mid(TextFile$,d,1)
  Else: Break: EndIf
 Next

 Debug   Dig$

0

3

Asc() большой тормоз, из памяти брать нужно, тоже самое, 48-57

0

4

newJS написал(а):

Asc() большой тормоз, из памяти брать нужно

Тут куда торопиться то? Пару чисел вытащить из строки.
Можешь и на ассемблере написать, ещё с 0.005 микросекунд выиграть.

0

5

ВиниПур написал(а):

Можешь и на ассемблере написать, ещё с 0.005 микросекунд выиграть.

если можно, то почему нельзя сделать сразу лучше
и коду эта функция генерит больше, а ты аж три текстовые функции использовал
Len() аж два раза за одну итерацию строку перемеряет, зачем?

сильно не упирался, но вроде отдаёт только десятичное число

Код:
Procedure IsDigits2(s.s, k=0)

;ShowMemoryViewer(@s-Mod(@s, 16), 32)
While PeekU(@s+k)<>0

;Debug ""+PeekU(@s+k)+" "+PeekU(@s+k-2)+" "+PeekU(@s+k+2)+" "+Hex(@s)
; если точка и перед ней цифра и после неё цифра
If PeekU(@s+k)=46 And (PeekU(@s+k-2)>47 And PeekU(@s+k-2)<58) And (PeekU(@s+k+2)>47 And PeekU(@s+k+2)<58)
ProcedureReturn 1
EndIf

k+2
Wend
ProcedureReturn 0
EndProcedure
 If IsDigits2("not."): Debug "Есть число": Else: Debug "Нет числа": EndIf
 If IsDigits2("no.t"): Debug "Есть число": Else: Debug "Нет числа": EndIf
 If IsDigits2("not99."): Debug "Есть число": Else: Debug "Нет числа": EndIf
 If IsDigits2("not.99."): Debug "Есть число": Else: Debug "Нет числа": EndIf
 If IsDigits2("yes.9.9."): Debug "Есть число": Else: Debug "Нет числа": EndIf

0

6

newJS написал(а):

если можно, то почему нельзя сделать сразу лучше

Потому, что есть принцип KISS (акроним для «Keep it simple, stupid»).
А прямые операции с памятью априори являются небезопасными, и предназначены для опытных пользователей.
Если умеешь. то молодец, я же не запрещаю. Более того, я не настаиваю, а сразу написал - "Посмотри идею".
Если тебе понравилась моя идея, то просто поставь "+" в репу, и используй и изменяй как угодно.

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Найти число без регулярного выражения