Чому “abcd” .StartsWith (“”) повертає true?


Відповіді:


164

Так - тому що він починається з порожнього рядка. Дійсно, порожній рядок логічно виникає між кожною парою символів.

Покладіть це так: яке визначення поняття "починається з" ви могли б дати, щоб це не дозволило? Ось просте визначення поняття "починається з", яке не означає:

"x починається з y, якщо перші y.Lengthсимволи x збігаються з y."

Альтернативне (еквівалентне) визначення:

"x починається з y, якщо x.Substring(0, y.Length).Equals(y)"


3
x починається з y, якщо x.Substring (0, y.Length) .Equals (y) if and only if y.Length> 0
Vinko Vrsalovic

8
Так, ви дійсно можете прямо виключити цю справу. Хоча це досить неелегантне визначення, чи не так?
Джон Скіт,

7
Правда. Це також вимагає, щоб вони теж не були нульовими ... але я б сказав, що обидва вони додають точності, віднімаючи дух простого визначення :)
Джон Скіт,

8
Нескінченні випадки порожнього рядка трапляються між кожною парою символів.
Lotus Notes

3
Так, це просто як ставити нуль перед числом - це значення не змінює, але воно все ще існує.
pop850

47

Я спробую детальніше розказати про те, що сказав Джон Скіт.

Скажімо, x, y та z - це рядки, а оператор + насправді є конкатенацією, тоді:

Якщо ми можемо розділити z на запис z = x + y, це означає, що z починається з x. Оскільки кожен рядок z може бути розділений на z = "" + z, отже, кожен рядок починається з "".

Отже, оскільки ("" + "abcd") == "abcd", виходить, що "abcd" починається з ""


17

Цей метод порівнює параметр значення з підрядком на початку цього рядка, який має однакову довжину зі значенням, і повертає значення, яке вказує, чи рівні вони. Щоб бути рівним, значення має бути порожнім рядком (Empty), посиланням на цей самий екземпляр або відповідати початку цього екземпляра.

.NET String.StartsWith

істина, якщо послідовність символів, представлена ​​аргументом, є префіксом послідовності символів, представленої цим рядком; інакше помилково. Також зауважте, що true буде повернуто, якщо аргумент є порожнім рядком або дорівнює цьому об’єкту String, як визначено методом equals (Object).

Java String.startsWith


17

Почну з пов'язаного факту, який легше зрозуміти.

Порожній набір є підмножиною кожного набору.

Чому? Визначення з підмножини станів , що Aє підмножиною , Bякщо кожен елемент Aє елементом B. І навпаки, Aне є підмножиною, Bякщо є елемент, Aякий не є елементом B.

Тепер виправте набір B. Я встановлю, що порожній набір є підмножиною B. Я зроблю це, показавши, що це не те, що порожній набір не є підмножиною B. Якби порожній набір не був підмножиною, Bтоді я міг би знайти елемент порожнього набору, якого немає B. Але порожній набір не має жодних елементів, і, отже, я не можу знайти елемент, якого немає B. Тому справа не в тому, що порожній набір не є підмножиною B. Таким чином, порожній набір повинен бути підмножиною B.

Будь-який рядок починається з порожнього рядка.

По-перше, ми повинні погодитись з нашим визначенням початку . Let sand tbe strings Ми говоримо, що s починається з t if s.Length >= t.Lengthі перші t.Lengthсимволи tвідповідності символам s. Тобто, s.Length >= t.Lengthі кожен Int32 indexтаким чином, що 0 <= index < t.Length, s[index] == t[index]вірно. І навпаки, ми б сказали, що sце не починається з tтвердження

s.Length < t.Lengthабо s.Length >= t.Lengthі є Int32 indexтакий, що 0 <= index < t.Lengthіs[index] != t[index]

правда. На простому англійській мові sкоротший за tабо, якщо ні, є символ, який tне відповідає символу, як однакова позиція в s.

Тепер зафіксуйте рядок s. Я встановлю, що sпочинається з порожнього рядка. Я зроблю це, показавши, що справа не в тому, що sне починається з порожнього рядка. Якщо sне починається з порожнього рядка, тоді s.Length < String.Empty.Lengthабо s.Length >= String.Empty.Lengthі є Int32 indexтакий, що 0 <= index < String.Empty.Length. Але s.Length >= 0і String.Empty.Lengthдорівнює нулю, тому неможливо s.Length < String.Empty.Lengthбути правдою. Подібним чином, оскільки `` String.Empty.Length is equal to zero, there is noInt32 індекс satisfying0 <= index <String.Empty.Length '' . Тому

s.Length < String.Empty.Lengthабо s.Length >= String.Empty.Lengthі є Int32 indexтакий, що0 <= index < String.Empty.Length

є хибним. Тому справа не в тому, що sне починається з порожнього рядка. Таким чином, sповинен починатися з порожнього рядка.

Далі наводиться реалізація запусків з кодуванням як розширення до 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;
}

Два вищезазначені жирні факти є прикладами безглуздо правдивих тверджень . Вони істинні в силу того, що твердження, що їх визначають ( підмножина і починається з ), є універсальними квантифікаціями над порожніми всесвітами. У порожньому наборі немає елементів, тому не може бути елементів порожнього набору, не в якомусь іншому фіксованому наборі. У порожньому рядку немає символів, тому не може бути символу, оскільки якась позиція в порожньому рядку не відповідає символу в тій самій позиції в іншому фіксованому рядку.


13

Скажімо, "abcd".StartsWith("")повертає false.

якщо так, то що означає наступний вираз, true або false:

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

виявляється, evals до true, тому рядок починається з порожнього рядка ;-), або іншими словами, підрядок "abcd", що починається з позиції 0 і має 0 довжину, дорівнює порожньому рядку "". Досить логічне іммо.


Той факт, що "abcd" .Substring (0, 0) повертає порожній рядок, не означає, що "abcd" насправді починається з порожнього рядка. Результат також міг бути оголошений "невизначеним", як nullце було б не менш відповідним значенням повернення.
Том Лінт

@TomLint Ні. Зазвичай ви поєднуєте умови IE x.FirstName.StartsWith (userEnteredFirstName) && x.LastName.StartsWith (userEnteredLastName) .... Це робить умову справною, навіть якщо один із введених valeus є порожнім рядком.
Pop Catalin

7

У C # це те, як специфікація говорить йому реагувати;

Щоб бути рівним, значення має бути порожнім рядком (Empty), посиланням на цей самий екземпляр або відповідати початку цього екземпляра.


5

Перші N символів двох рядків однакові. N - довжина другого рядка, тобто нуль.


5

Чому “abcd” .StartsWith (“”) повертає true?

РЕАЛЬНИЙ ВІДПОВІДЬ:

Це повинно бути так, інакше у вас був би випадок де

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

    but yet

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

і тоді у нас знову буде Y2K, тому що все банківське програмне забезпечення, яке залежить від рівних рядків, починаючи з них самих, змішає наші рахунки, і раптом Білл Гейтс отримає моє багатство, а я його отримаю, і блін! Доля просто не така добра для мене.


Я не погоджуюсь. "" .startsWith ("") має дорівнювати істині, оскільки рядки ідентичні, а не через якусь дивну бізнес-логіку.
Том Лінт

@TomLint Ви насправді погоджуєтесь із твердженням у відповіді ...
neonblitzer

4

Тільки для запису, String.StartsWith()внутрішньо викликає метод, System.Globalization.CultureInfo.IsPrefix()який явно робить наступну перевірку:

if (prefix.Length == 0)
{
    return true;
}

1

Тому що рядок добре починається з "нічого".


1
... тобто якщо string.empty - це ніщо! Це надмірне спрощення не можна узагальнити. Я пропоную наслідувати більш набір теоретично орієнтованих дискусій.
Pita.O

1

Якщо ви думаєте про це регулярними виразами, це має сенс. Кожен рядок (не просто "abcd", а також "" та "sdf \ nff") повертає значення true при обчисленні регулярного виразу "починається з порожнього рядка".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.