Содержит ли пустая строка пустую строку в C ++?

Просто был интересный аргумент в комментарии к одному из моих вопросов. Мой оппонент утверждает, что заявление "" делает не содержать "" неправильно.

Я считаю, что если "" содержал другой "", что один также будет содержать "" и так далее.

Кто не прав?

Постскриптум

Я говорю о std::string

Постскриптум P.S

Я не говорил о подстроках, но даже если я добавлю к своему вопросу «как подстроку», это все равно не имеет смысла. Пустая подстрока ерунда. Если вы разрешаете содержать пустые подстроки в строках, это означает, что у вас есть бесконечность пустых подстрок. Какой смысл в этом?

Редактировать:

Я единственный, кто считает, что с функцией что-то не так? std::string::find?

Ссылка на C ++ ясно говорит

Возвращаемое значение: позиция первого символа первого совпадения.

Хорошо, давайте предположим, что это имеет смысл на минуту и ​​запустим этот код:

string empty1 = "";
string empty2 = "";

int postition = empty1.find(empty2);

cout << "found \"\" at index " << position << endl;

Выход: found "" at index 0

Бессмысленная часть: как может быть индекс 0 в строке длины 0? Это ерунда.

Чтобы быть в состоянии даже иметь 0-я позиция, строка должна быть длиной не менее 1 символа.

И C ++ дает исключение в этом случае, что подтверждает мою точку зрения:

cout << empty2.at( empty1.find(empty2) ) << endl;

Если бы он действительно содержал пустую строку, у него не было бы проблем распечатать его.

4

Решение

Это зависит от того, что вы подразумеваете под «содержит».

Пустая строка подстрока пустой строки, и поэтому содержится в этом смысле.

С другой стороны, если вы рассматриваете строку как набор символов, пустая строка не может содержать пустую строку, поскольку ее элементы являются символами, а не строками.

Относительно наборов, набор

{2}

это подмножество из набора

A = {1, 2, 3}

но {2} это не член из A — все AЧленами являются числа, а не множества.

Точно так же, {} это подмножество {}, но {} не является элементом в {} (это не может быть, потому что это пусто).

Так что вы оба правы.

15

Другие решения

C ++ согласен с вашим «оппонентом»:

#include <iostream>
#include <string>
using namespace std;

int main()
{
bool contains = string("").find(string("")) != string::npos;
cout << "\"\" contains \"\": "<< boolalpha << contains;
}

Выход: "" contains "": true

демонстрация

7

Это просто. Строка A содержит подстроку B, если есть аргумент offset такой, что A.substr(offset, B.size()) == B, Никаких особых случаев для пустых строк не требуется.

Итак, посмотрим. std::string("").substr(0,0) оказывается std::string(""), И мы можем даже проверить ваш «контрпример». std::string("").substr(0,0).substr(0,0) также четко определен и пуст. Черепахи все время вниз.

4

Первое, что неясно, говорите ли вы о std::string или строки C с нулевым символом в конце, второе почему это должно иметь значение?. Я приду std::string,

Требования к std::string определить, как должен вести себя компонент, а не каким должно быть его внутреннее представление (хотя некоторые требования влияют на внутреннее представление). Если требования к компоненту соблюдены, то, содержит ли он что-то внутри, является деталью реализации, которую вы, возможно, даже не сможете проверить.

В частном случае пустой строки нет ничего, что требовало бы, чтобы она содержала что-либо. Он может содержать элемент размера, установленный в 0, и указатель (для динамически выделяемой памяти, если / когда он не пустой) также установлен в 0. Требование в operator[] требует, чтобы он возвращал ссылку на символ со значением 0, но поскольку этот символ нельзя изменить, не вызывая неопределенного поведения, и поскольку строгие правила псевдонимов позволяют читать из lvalue типа char, реализация может просто вернуть ссылку на один из байты в size член (все установлено в 0) в случае пустой строки.

Некоторые реализации std::string использовать оптимизацию небольших объектов, в этих реализациях будет зарезервирована память для небольших строк, включая пустой строка. В то время как std::string явно не будет содержать std::string внутренне он может содержать последовательность символов, составляющих пустую строку (то есть завершающий нулевой символ)

0

пустая строка ничего не содержит — это ПУСТО. 🙂

0

Конечно, пустая строка не содержать пустая строка. Это будут черепахи, если так и будет.

принимать String empty = ""; который объявляет строковый литерал, который является пустым, если вы хотите, чтобы строковый литерал представлять пустой строковый литерал, который вам понадобится String representsEMpty = """"; но, конечно, вы должны избежать этого, давая вам string actuallyRepresentsEmpty = "\"\"";

PS Я принимаю прагматичный подход к этому. Оставьте математическую ерунду у двери.

Думая о вашей поправке, вполне возможно, что ваш «оппонент» имел в виду, что «пустая» строка std :: string по-прежнему имеет внутреннюю память для символов, которая сама по себе не содержит символов. Я уверен, что это было бы деталью реализации, возможно, он мог бы просто сохранить массив символов определенного размера (скажем, 10) «просто упаковывать», так что технически он не будет пустым.

Конечно, есть вопрос с подвохом, что «ничто» не вписывается во что-то бесконечное время, что-то вроде ситуации «делим на ноль».

0

Сегодня у меня возник тот же вопрос, поскольку в настоящее время я связан с паршивой реализацией STL (восходящей к эпохе, предшествовавшей C ++ 98), которая отличается от C ++ 98 и всех следующих стандартов:

TEST_ASSERT(std::string().find(std::string()) == string::npos); // WRONG!!! (non-standard)

Это особенно плохо, если вы пытаетесь написать переносимый код, потому что так трудно доказать, что ни одна функция не зависит от этого поведения. К сожалению, в моем случае это действительно так: он выполняет обработку строк, чтобы сократить ввод телефонных номеров в зависимости от спецификации абонентской линии.

На Cppreference я вижу в станд :: basic_string :: найти Явное описание пустых строк, которое, я думаю, точно соответствует рассматриваемому случаю:

пустая подстрока находится в pos, если и только если pos <= размер ()

Упомянутый pos определяет позицию, с которой начинается поиск, по умолчанию 0 (начало).

Соответствующий стандарту Стандартная библиотека C ++ пройдут следующие тесты:

TEST_ASSERT(std::string().find(std::string()) == 0);
TEST_ASSERT(std::string().substr(0, 0).empty());
TEST_ASSERT(std::string().substr().empty());

Такое толкование «содержать» отвечает на вопрос «да».

0
По вопросам рекламы [email protected]