Regex szukanie dokładnie jednego wystąpienia podanego znaku

Odpowiedz Nowy wątek
2019-08-22 18:50

Rejestracja: 1 rok temu

Ostatnio: 3 miesiące temu

0

Potrzebuje znaleźć w Stringu dokładnie jednego wystąpienia wybranego znaku.
Kombinuje tak

System.out.println(!txt1.matches("[^a]*"));

Jak już pewnie wiecie, nie zawsze daje odpowiedni wynik.

[^a]{1}...? - Spearhead 2019-08-22 19:20

Pozostało 580 znaków

2019-08-22 19:01

Rejestracja: 6 lat temu

Ostatnio: 2 godziny temu

Lokalizacja: Wrocław

1

Czy próbujesz dostać informację, że jakiś znak występuje w tekście dokładnie jeden raz? Dziwne to Twoje zdanie i wole się upewnić :)
Jeśli tak, to gugle mi podpowiedział dosyć szybko: "^[^a]*a[^a]*$"


"We don’t use Spring, because debugging annotation-driven problems is not fun," said Grzesik
edytowany 1x, ostatnio: baant, 2019-08-22 19:11

Pozostało 580 znaków

2019-08-22 19:17

Rejestracja: 1 rok temu

Ostatnio: 22 minuty temu

2

Polecam sprawdzić swoje wyrażenie w parserze wyrażeń, np. http://regexr.com/. Był ostatnio temat na forum, programowy tester / edytor wyrażeń regularnych.
Jeśli dobrze rozumiem co autor miał na myśli, to nie potrzeba tu wyrażenia. Lepiej zrobić tak: text.contains("a"). Metoda contains odpowiada na pytanie czy podany ciąg znaków znajduje się w tym, którego metoda się tyczy - nieważne w jakim miejscu i nieważne ile razy - ważne, że jest. Opis metody https://docs.oracle.com/javas[...]tains(java.lang.CharSequence)
A jeśli już koniecznie chce regex, to tak System.out.println(txt1.matches("[a]"));. Gwiazdka może byłaby spoko, bo każe znaleźć dowolną liczbę podanego znaku. Ale za to [^a] oznacza negację. Czyli wychodzi nam niespodzianka "znajdź dowolną liczbę czegoś, co nie jest znakiem a.


Nie sztuka uciec gdy w dupie sztuciec
edytowany 1x, ostatnio: PerlMonk, 2019-08-22 19:19
W zadaniu chodzi o dokładnie jedno wystąpienie i nie więcej a contains zwróci true również jeśli wystąpień będzie więcej. Więc tylko rozwiązanie twojego przedmówcy pasuje. - manifestor 2019-08-22 19:35
Tylko problem z rozwiązaniem wyżej jest taki, że wyrażenie dopasuje cały tekst. - PerlMonk 2019-08-22 19:43

Pozostało 580 znaków

2019-08-22 19:56

Rejestracja: 1 rok temu

Ostatnio: 22 minuty temu

baant napisał(a):

Czy próbujesz dostać informację, że jakiś znak występuje w tekście dokładnie jeden raz? Dziwne to Twoje zdanie i wole się upewnić :)
Jeśli tak, to gugle mi podpowiedział dosyć szybko: "^[^a]*a[^a]*$"

To wyrażenie spełni swoje zadanie, ale dopasuje przy okazji cały tekst. To już prościej nie używać regexa wcale:

boolean ok = false;
int a;

for (a = 0; a < text.length(); a++) {
    if (text.charAt(a) == 'a') {
        if (!ok) {
            ok = true;
        } else {
            ok = false;
            break;
        }
    }
}

Po co używać gwiazdek do prostych zadań?


Nie sztuka uciec gdy w dupie sztuciec
Popieram. Dodatkowo zużycie RAM stałe, niemal zerowe, GC leniuchuje - AnyKtokolwiek 2019-08-22 22:01
Geniusz tkwi w prostocie :D - manifestor 2019-08-30 18:26
Dokładnie :D . Oczywiście to nie jest jedyne rozwiązanie, ale w tym przypadku zadziała. Dla długiego tekstu zadziała szybciej, niż regex, bo pominie część tekstu jeśli litera została znaleziona. Gwiazdki w wyrażeniach regularnych przydają się bardzo rzadko. - PerlMonk 2019-08-30 20:36

Pozostało 580 znaków

2019-08-22 20:12

Rejestracja: 1 rok temu

Ostatnio: 4 minuty temu

Lokalizacja: Warszawa

1

Ogólnie, taki pseudo kod

str - dany tekst
key - badany znak

str. lastIndexOf(key) == str.firstIndexOf(key)
(first równy last bo wtedy wystąpił tylko jeden raz albo zero razy) i różny od -1 (bo to dało co najmniej jeden znaleziony a -1 zwracane jest kiedy klucz nie występuje w tekście)

Czy Java czy JS to sobie potem dobierasz kosmetykę składni itd.

Nie będę się upierać, że ma być -1 bo może w innym języku albo inna implementacja zwróci jakąś wartość < 0 kiedy nie znaleziono klucza.
Ale na interview ustne one to one takie rozwiązanie jak najbardziej będzie OK.


"Ktoś sobie uświadomił, że pisał pod pseudonimem rzeczy, które lepiej żeby w firmie nie wypatrzyli :-)"
"Kiedy wiedzieć czy zacząć nauke Springa? bo w czystej Javie to nic ciekawego nie zrobie chyba"
edytowany 5x, ostatnio: BraVolt, 2019-08-22 20:40
Nie widzę metody zwracającej index, pod którym znajduje się pierwsze wystąpienie (i mean firstIndexOf) - manifestor 2019-08-30 18:11
Ja głupi. Oczywiście, że jest string.indexOf() :D - manifestor 2019-08-30 19:20

Pozostało 580 znaków

2019-08-22 20:29

Rejestracja: 1 rok temu

Ostatnio: 4 minuty temu

Lokalizacja: Warszawa

1

OT, warto używać dostępnych implementacji algorytmów i struktur danych z danego języka.

Np. podobne zadanie typu isUnique(array|string) - czy array|string nie ma powtarzających się wartości.
Zamiast latać O(n^2) pętlami (i się w stresie interview pomylić) jak nam na szybko przyszło do głowy rozwiązanie, można z danych wejściowych stworzyć Set, kiedy rozmiar otrzymanego Set jest równy licznie elementów wejściowych to są one unikatowe/unikalne (kurcze, polski analfabetym wtórny mnie dopadł - unique)

Modelowe O(n^2)

const isUnique = function (arr) {
    let result = true;

    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length; j++) {
            if (i !== j && arr[i] === arr[j]) {
                result = false;
            }
        }
    }

    return result;
};

console.log(isUnique([1, 2, 3]));
console.log(isUnique([1, 1, 3]));
let numbers = [1, 2, 3];
console.log(new Set(numbers).size === numbers.length);

numbers = [1, 1, 3];
console.log(new Set(numbers).size === numbers.length);

Drugie podejście da się już zakodzić na szybko nawet w przeglądarce

A jak miałoby być na życzenie rekrutującego inżyniera wydajnie to prosty cache

const isUnique = function (arr) {
    const cache = {};

    for (let e of arr) {
        if (cache[e]) {
            return false;
        } else {
            cache[e] = true;
        }
    }

    return true;
};

Dla Javy zamiast obiektu {} będzie new HashMap(), w JS można tak samo z mapą

const isUnique = function (arr) {
    const cache = new Map();

    for (let e of arr) {
        if (cache.has(e)) {
            return false;
        } else {
            cache.set(e, true);
        }
    }

    return true;
};

"Ktoś sobie uświadomił, że pisał pod pseudonimem rzeczy, które lepiej żeby w firmie nie wypatrzyli :-)"
"Kiedy wiedzieć czy zacząć nauke Springa? bo w czystej Javie to nic ciekawego nie zrobie chyba"
edytowany 9x, ostatnio: BraVolt, 2019-08-22 22:11

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0