Dlaczego „abcd” .StartsWith („”) zwraca prawdę?

87

Tytuł to całe pytanie. Czy ktoś może mi podać powód, dla którego tak się dzieje?

Zniszczony
źródło

Odpowiedzi:

164

Tak - ponieważ zaczyna się od pustego ciągu. Rzeczywiście, pusty ciąg logicznie występuje między każdą parą znaków.

Ujmując to w ten sposób: jaką definicję „zaczyna się od” mógłbyś podać, która by to wykluczała? Oto prosta definicja „zaczyna się od”, która nie:

„x zaczyna się od y, jeśli pierwsze y.Lengthznaki x są zgodne z y”.

Alternatywna (równoważna) definicja:

„x zaczyna się od y, jeśli x.Substring(0, y.Length).Equals(y)

Jon Skeet
źródło
3
x zaczyna się od y, jeśli x.Substring (0, y.Length). Equals (y) wtedy i tylko wtedy, gdy y.Length> 0
Vinko Vrsalovic
8
Tak, rzeczywiście można było wyraźnie wykluczyć ten przypadek. To dość nieelegancka definicja, prawda?
Jon Skeet,
7
Prawdziwe. Wymaga to również ich być niezerowe, zbyt ... ale powiedziałbym, że oba te dodają do dokładności podczas zabierając z duchem prostego definicji :)
Jon Skeet
8
Nieskończone wystąpienia pustego ciągu występują między każdą parą znaków.
Lotus Notes,
3
Tak, to tak, jakby wstawić zero przed liczbą - nie zmienia wartości, ale nadal istnieje.
pop850
47

Spróbuję rozwinąć to, co powiedział Jon Skeet.

Powiedzmy, że x, y i z są łańcuchami, a operator + jest w rzeczywistości konkatenacją, a następnie:

Jeśli możemy podzielić z, aby zapisać z = x + y, oznacza to, że z zaczyna się od x. Ponieważ każdy ciąg z można podzielić na z = "" + z, wynika z tego, że każdy ciąg zaczyna się od "".

Tak więc, ponieważ ("" + "abcd") == "abcd" wynika z tego, że "abcd" zaczyna się od ""

pero
źródło
17

Ta metoda porównuje parametr value z podciągiem na początku tego ciągu, który ma taką samą długość jak value, i zwraca wartość wskazującą, czy są one równe. Aby być równe, wartość musi być pustym ciągiem (Empty), odwołaniem do tego samego wystąpienia lub odpowiadać początkowi tego wystąpienia.

.NET String.StartsWith

true, jeśli sekwencja znaków reprezentowana przez argument jest przedrostkiem sekwencji znaków reprezentowanej przez ten ciąg; w przeciwnym razie fałsz. Należy również zauważyć, że wartość true zostanie zwrócona, jeśli argument jest pustym ciągiem lub jest równy temu obiektowi String, zgodnie z metodą equals (Object).

Java String.startsWith

Firas Assaad
źródło
17

Zacznę od powiązanego faktu, który jest łatwiejszy do zrozumienia.

Pusty zbiór jest podzbiorem każdego zestawu.

Czemu? Definicja z podzbioru stanów, które Ajest podzbiorem Bjeśli każdy element Ajest elementem B. I odwrotnie, Anie jest podzbiorem, Bjeśli istnieje element, Aktóry nie jest elementem B.

Teraz napraw zestaw B. Ustalę, że pusty zbiór jest podzbiorem B. Zrobię to, pokazując, że nie jest tak, że pusty zbiór nie jest podzbiorem B. Gdyby pusty zestaw nie był podzbiorem B, mógłbym znaleźć element pustego zestawu, którego nie ma B. Ale pusty zestaw nie ma żadnych elementów i dlatego nie mogę znaleźć elementu, którego nie ma B. Dlatego nie jest tak, że pusty zbiór nie jest podzbiorem B. Zatem pusty zbiór musi być podzbiorem B.

Każdy ciąg zaczyna się od pustego łańcucha.

Po pierwsze, musimy zgodzić się na naszą definicję rozruchów . Let sand tbe strings Mówimy, że s zaczyna się od t if, s.Length >= t.Lengtha pierwsze t.Lengthznaki tpasują do tych z s. Oznacza to, że s.Length >= t.Lengthi dla każdego Int32 indextakie, że 0 <= index < t.Length, s[index] == t[index]jest prawdą. I odwrotnie, powiedzielibyśmy, że snie zaczyna się od, tjeśli instrukcja

s.Length < t.Lengthlub s.Length >= t.Lengthi jest Int32 indextaki, że 0 <= index < t.Lengthis[index] != t[index]

jest prawdziwy. Mówiąc prostym językiem, sjest krótszy niż t, lub, jeśli nie, jest znak, który tnie pasuje do znaku w tej samej pozycji s.

Teraz napraw ciąg s. Ustalę, że szaczyna się od pustego łańcucha. Zrobię to, pokazując, że nie jest tak, że snie zaczyna się od pustego ciągu. Jeśli snie zaczyna się od pustego łańcucha, to s.Length < String.Empty.Lengthlub s.Length >= String.Empty.Lengthi jest Int32 indextaki, że 0 <= index < String.Empty.Length. Ale s.Length >= 0i String.Empty.Lengthjest równe zero, więc nie może s.Length < String.Empty.Lengthbyć prawdziwe. Podobnie, ponieważ `` String.Empty.Length is equal to zero, there is noInt32 index satisfying0 <= index <String.Empty.Length`. W związku z tym

s.Length < String.Empty.Lengthlub s.Length >= String.Empty.Lengthi jest Int32 indextaki, że0 <= index < String.Empty.Length

to fałsz. Dlatego nie jest tak, że snie zaczyna się od pustego ciągu. Dlatego smusi zaczynać się od pustego ciągu.

Poniżej przedstawiono implementację startów z zakodowanym jako rozszerzenie string.

public static bool DoStartsWith(this string s, string t) {
    if (s.Length >= t.Length) {
        for (int index = 0; index < t.Length; index++) {
            if (s[index] != t[index]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

Powyższe dwa pogrubione fakty są przykładami twierdzeń bezmyślnie prawdziwych . Są one prawdziwe z tego względu, że stwierdzenia je definiujące ( podzbiór i rozpoczynają się od ) są uniwersalnymi kwantyfikacjami pustych wszechświatów. W pustym zestawie nie ma elementów, więc nie może być żadnych elementów z pustego zestawu, których nie ma w innym ustalonym zestawie. W pustym ciągu nie ma żadnych znaków, więc nie może być znaku, ponieważ jakaś pozycja w pustym ciągu nie pasuje do znaku na tej samej pozycji w innym ustalonym ciągu.

Jason
źródło
13

Powiedzmy, że "abcd".StartsWith("")zwraca fałsz.

jeśli tak, to do czego zmienia się następujące wyrażenie, prawda czy fałsz:

 ("abcd".Substring(0,0) == "")

okazuje się, że evals to true, więc łańcuch zaczyna się od pustego łańcucha ;-), czyli innymi słowy, podciąg „abcd” zaczynający się na pozycji 0 i mający 0 długości równa się pustemu ciągowi „”. Całkiem logiczne imo.

Pop Catalin
źródło
Fakt, że „abcd” .Substring (0, 0) zwraca pusty ciąg, nie oznacza, że ​​„abcd” faktycznie zaczyna się od pustego łańcucha. Wynik mógł również zostać zadeklarowany jako „niezdefiniowany”, ponieważ nullbyłaby równie odpowiednią wartością zwracaną.
Tom Lint
@TomLint Nie. Zwykle łączysz warunki IE x.FirstName.StartsWith (userEnteredFirstName) && x.LastName.StartsWith (userEnteredLastName) .... To sprawia, że ​​warunek działa, nawet jeśli jeden z wprowadzonych wartości valeus jest pustym ciągiem.
Pop Catalin
7

W C # w ten sposób specyfikacja nakazuje mu reagować;

Aby być równe, wartość musi być pustym ciągiem (Empty), odwołaniem do tego samego wystąpienia lub odpowiadać początkowi tego wystąpienia.

strzałka do dmuchawki
źródło
5

Pierwsze N ​​znaków z dwóch ciągów jest identycznych. N jest długością drugiego łańcucha, czyli zero.

Ralph
źródło
5

Dlaczego „abcd” .StartsWith („”) zwraca prawdę?

PRAWDZIWA ODPOWIEDŹ:

Musi tak być, w przeciwnym razie miałbyś przypadek, w którym

    "".startsWith("") == false 
    "".equals("") == true

    but yet

    "a".startsWith("a") == true
    "a".equals("a") == true

a potem znowu mielibyśmy Y2K, ponieważ całe oprogramowanie bankowe, które opiera się na równych łańcuchach zaczynających się od siebie, pomieszałoby nasze konta i nagle Bill Gates będzie miał moje bogactwo, a ja będę miał jego, do cholery! Po prostu los nie jest dla mnie taki łaskawy.

user804965
źródło
Nie zgadzam się. „” .startsWith („”) powinno mieć wartość true, ponieważ ciągi są identyczne, a nie z powodu jakiejś dziwnej logiki biznesowej.
Tom Lint
@TomLint W rzeczywistości zgadzasz się z zapewnieniem w odpowiedzi ...
neonblitzer
4

Dla przypomnienia, String.StartsWith()wewnętrznie wywołuje metodę, System.Globalization.CultureInfo.IsPrefix()która jawnie dokonuje następującego sprawdzenia:

if (prefix.Length == 0)
{
    return true;
}
Tamas Czinege
źródło
1

Ponieważ ciąg zaczyna się dobrze od „niczego”.

gadżet
źródło
1
... tak jest, jeśli string.empty to nic! Tego nadmiernego uproszczenia nie można uogólniać. Sugeruję, abyśmy śledzili dyskusje bardziej zorientowane na teorię zbiorów.
Pita.O
1

Jeśli myślisz o tym w terminach wyrażeń regularnych, ma to sens. Każdy ciąg (nie tylko „abcd”, ale także „” i „sdf \ nff”) zwraca prawdę podczas obliczania wyrażenia regularnego „zaczyna się od pustego ciągu”.


źródło