Wiem, że możemy dołączyć ciągi znaków za pomocą StringBuilder
. Czy istnieje sposób, w jaki możemy dołączyć ciągi znaków z wyprzedzeniem (tj. Dodać ciągi przed ciągiem), używając StringBuilder
, abyśmy mogli zachować korzyści wydajnościowe, które StringBuilder
oferuje?
c#
java
stringbuilder
spalony
źródło
źródło
Odpowiedzi:
Użycie metody wstawiania z parametrem pozycji ustawionym na 0 byłoby tym samym, co poprzedzanie (tj. Wstawianie na początku).
Przykładem jest:
varStringBuilder.insert(0, "someThing");
Działa zarówno dla C #, jak i Java
źródło
Wstawianie ciągu znaków z wyprzedzeniem zwykle wymaga skopiowania wszystkiego za punktem wstawiania z powrotem do części tablicy zapasowej, więc nie będzie to tak szybkie, jak dołączanie do końca.
Ale możesz to zrobić w ten sposób w Javie (w C # to to samo, ale metoda nazywa się
Insert
):źródło
Jeśli potrzebujesz wysokiej wydajności z dużą ilością przedrostków, musisz napisać własną wersję
StringBuilder
(lub użyć cudzej). Ze standardemStringBuilder
(choć technicznie można by to zaimplementować inaczej) wstawianie wymaga kopiowania danych po punkcie wstawienia. Wstawienie n fragmentu tekstu może zająć O (n ^ 2) czasu.Naiwnym podejściem byłoby dodanie przesunięcia do
char[]
bufora podkładowego, a także długości. Jeśli nie ma wystarczającej ilości miejsca na przedrostek, przenieś dane w górę o więcej, niż jest to bezwzględnie konieczne. To może sprowadzić wydajność z powrotem do O (n log n) (myślę). Bardziej wyrafinowanym podejściem jest zapewnienie cykliczności bufora. W ten sposób wolne miejsce na obu końcach tablicy staje się ciągłe.źródło
Możesz wypróbować metodę rozszerzenia:
źródło
Możesz zbudować ciąg w odwrotnej kolejności, a następnie odwrócić wynik. Ponosisz koszt O (n) zamiast O (n ^ 2) w najgorszym przypadku.
źródło
Nie używałem tego, ale Ropes For Java brzmi intrygująco. Nazwa projektu to gra słów, do poważnej pracy użyj liny zamiast sznurka . Obejmuje spadek wydajności dla operacji poprzedzających i innych. Warto rzucić okiem, jeśli masz zamiar dużo to robić.
źródło
Oto, co możesz zrobić, jeśli chcesz wstawić na początku za pomocą klasy StringBuilder w Javie:
źródło
Jeśli dobrze cię rozumiem, metoda insert wygląda na to, że zrobi to, co chcesz. Po prostu wstaw ciąg z przesunięciem 0.
źródło
Spróbuj użyć Wstaw ()
źródło
Sądząc po innych komentarzach, nie ma standardowego szybkiego sposobu na zrobienie tego. Używanie StringBuildera
.Insert(0, "text")
jest w przybliżeniu tylko 1-3 razy szybsze niż używanie boleśnie powolnej konkatenacji ciągów (na podstawie> 10000 konkatenacji), więc poniżej znajduje się klasa, która może poprzedzać potencjalnie tysiące razy szybciej!Podaję jakieś inne podstawowe funkcje, takie jak
append()
,subString()
ilength()
itd. Obie Dokleja i wstawia się zmieniać od około dwukrotnie szybciej do 3x wolniej niż StringBuilder dopisuje. Podobnie jak StringBuilder, bufor w tej klasie zostanie automatycznie zwiększony, gdy tekst przepełni stary rozmiar buforu.Kod był dość często testowany, ale nie mogę zagwarantować, że jest wolny od błędów.
źródło
Możesz samodzielnie stworzyć rozszerzenie dla StringBuilder za pomocą prostej klasy:
Następnie po prostu dodaj:
Na szczycie dowolnej klasy, w której chcesz użyć StringBuilder, i za każdym razem, gdy używasz funkcji intelli-sense ze zmienną StringBuilder, pojawią się metody Prepend i PrependLine. Pamiętaj tylko, że kiedy używasz dołączania na początku, będziesz musiał dodawać na początku w odwrotnej kolejności niż w przypadku dołączania.
źródło
To powinno działać:
źródło
string
, ale nie działa z wartościami typuStringBuilder
. Odpowiedź od @ScubaSteve działa dobrze.