Obecnie pracuję nad generatorem skanera. Generator działa już poprawnie. Ale gdy używasz klas postaci, algorytm staje się bardzo wolny.Efektywny algorytm do przekształcania zestawu znaków w nfa/dfa
Generator skanera tworzy skaner dla plików zakodowanych w UTF8. Pełen zakres znaków (od 0x000000 do 0x10ffff) powinien być obsługiwany.
Jeśli używam dużych zestawów znaków, takich jak dowolny operator ". lub właściwość unicode {L}, nfa (a także dfa) zawiera wiele stanów (> 10000). Tak więc konwersja dla nfa do dfa i stworzenie minimalnej dfa zajmuje dużo czasu (nawet jeśli wyjściowy minimalny dfa zawiera tylko kilka stanów).
Oto moja obecna implementacja tworzenia zestawu znaków w NFA.
void CreateNfaPart(int startStateIndex, int endStateIndex, Set<int> characters)
{
transitions[startStateIndex] = CreateEmptyTransitionsArray();
foreach (int character in characters) {
// get the utf8 encoded bytes for the character
byte[] encoded = EncodingHelper.EncodeCharacter(character);
int tStartStateIndex = startStateIndex;
for (int i = 0; i < encoded.Length - 1; i++) {
int tEndStateIndex = transitions[tStartStateIndex][encoded[i]];
if (tEndStateIndex == -1) {
tEndStateIndex = CreateState();
transitions[tEndStateIndex] = CreateEmptyTransitionsArray();
}
transitions[tStartStateIndex][encoded[i]] = tEndStateIndex;
tStartStateIndex = tEndStateIndex;
}
transitions[tStartStateIndex][encoded[encoded.Length - 1]] = endStateIndex;
}
Czy ktoś wie, jak wdrożyć funkcję o wiele bardziej wydajnie, aby stworzyć tylko niezbędne stany?
Edycja:
Konkretniej muszę funkcji takich jak:
List<Set<byte>[]> Convert(Set<int> characters)
{
???????
}
funkcja pomocniczych do konwersji postaci (int) do bajtu kodowania UTF-8 [] jest zdefiniowany jako:
byte[] EncodeCharacter(int character)
{ ... }
Budujesz xFA dla wejścia _byte_? Czy nie byłoby dużo łatwiej (i bardziej niezawodnie) działać na znakach (Utf16)? –
Nie sądzę, że rozmiar tabeli (tabel) wyszukiwania wzrósłby przy użyciu 16-bitowych znaków. Również typowy plik wejściowy byłby większy, gdyby używał utf16 (w porównaniu z utf8). – raisyn
Przykro mi, źle mnie zrozumiałem! Zaakceptowanie dowolnego kodowania byłoby dobrą opcją dla przyszłej wersji. Ale żeby to było proste, wydaje mi się, że łatwiej jest zaimplementować tylko jedno kodowanie, a UTF-8 wygląda dla mnie jak prawo. – raisyn