Здравствуйте, Lonely Dog, Вы писали:
LD>Добрый день!
LD>Есть следующий код: LD>
LD>if (status == "1234" ||
LD> status == "2345" ||
LD> status == "3456")
LD>{
LD> // do something
LD>}
LD>
Правильно писать:
if ((strcmp(status,"1234")==0)||
(strcmp(status,"2345")==0)||
(strcmp(status,"3456")==0))
{
// do something
}
Потому что в C/C++ строковая переменная представляет собой указатель на самый первый (нулевой) элемент строки. И поэтому для сравнения строк надо пользоваться не = , а функцией strcmp, которая возвращает 0 в случае равенства и ненулевое значение в случае неравенства.
LD>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код?
Радость ты моя, а заранее все эти строки запихать в контейнер — никак?
Вместо вложенных ифов — просто найти в контейнере и сделать, чего с ним связано.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Проверка, что строка равна одному из значений
Здравствуйте, Lonely Dog, Вы писали:
LD> LD>>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код?
LD> LVV>Радость ты моя, а заранее все эти строки запихать в контейнер — никак? LD> LVV>Вместо вложенных ифов — просто найти в контейнере и сделать, чего с ним связано. LD> Да можно наверное. Что-нибудь типа такого? LD>
Здравствуйте, DenisCh, Вы писали:
DC>А сортировка строк быстрее?
ну дык в вопросе топикстартера список предполагается быть заранее заданным и неизменным в процессе работы программы, поэтому его можно или сразу задать отсортированным, либо отсортировать один раз перед началом работы.
Re[5]: Проверка, что строка равна одному из значений
Здравствуйте, DenisCh, Вы писали:
X>> линейная сложность.
DC>А что, это можно сделать быстрее, чем О(n) ? DC>Поделись мудростью.
Если значений много и список нужно создать один раз, а обращаться к нему часто, то можно конечный автомат построить.
Иначе — не заморачиваться и делать с линейной сложностью.
Re[2]: Проверка, что строка равна одному из значений
У меня не компилируется ни в VS2015, ни в идеоне
Да и страшно как-то выглядит. Объявляешь переменную. Статик. В ифе. Потом точка с запятой. А потом условие.
Сергей
Re[4]: Проверка, что строка равна одному из значений
niXman:
LD>>... создание hash_set (или еще чего-нибудь) займет явно больше времени, чем простой проход по этому списку. X>посмотрите мой пример, в нем set будет инициализирован только один раз.
Зато поиск у std::set не особо-то быстрый. Хаотичное хождение по нодам set-а может быть заметно дороже, чем обход элементов компактного массива, т.к. данные из небольшой непрерывной области памяти легче кэшируются. Поэтому для каких-нибудь небольших наборов строк алгоритм с линейной сложностью вполне мог бы показать заметно лучшую производительность.
Здравствуйте, Lonely Dog, Вы писали:
LD>Добрый день!
LD>В реальности, в этом if гораздо больше условий. На питоне я бы написал это так: LD>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код?
if (confirms_all_conditions(status)) // ...
Re[2]: Проверка, что строка равна одному из значений
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, Lonely Dog, Вы писали:
LD>>Добрый день!
LD>>В реальности, в этом if гораздо больше условий. На питоне я бы написал это так: LD>>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код? _>
_>if (confirms_all_conditions(status)) // ...
_>
так а дальше что? в функции будет тот же самый большой if с кучей условий
Re[2]: Проверка, что строка равна одному из значений
Здравствуйте, LaptevVV, Вы писали:
LD>>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код? LVV>Радость ты моя, а заранее все эти строки запихать в контейнер — никак? LVV>Вместо вложенных ифов — просто найти в контейнере и сделать, чего с ним связано.
Да можно наверное. Что-нибудь типа такого?
Здравствуйте, niXman, Вы писали:
X>линейная сложность.
Само собой. Но когда вариантов не так много (не забываем, что раньше в коде была куча условий в одном if, и тоже линейная сложность), то это вполне допустимо. Тем более, создание hash_set (или еще чего-нибудь) займет явно больше времени, чем простой проход по этому списку.
Re[5]: Проверка, что строка равна одному из значений
Здравствуйте, Lonely Dog, Вы писали:
LD>... создание hash_set (или еще чего-нибудь) займет явно больше времени, чем простой проход по этому списку.
посмотрите мой пример, в нем set будет инициализирован только один раз.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[6]: Проверка, что строка равна одному из значений
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, Lonely Dog, Вы писали:
LD>>... создание hash_set (или еще чего-нибудь) займет явно больше времени, чем простой проход по этому списку. X>посмотрите мой пример, в нем set будет инициализирован только один раз.
Посмотрел, осознал. Спасибо.
Re[6]: Проверка, что строка равна одному из значений
Здравствуйте, LuciferSaratov, Вы писали:
LS> DC>А что, это можно сделать быстрее, чем О(n) ? LS> DC>Поделись мудростью. LS> можно список строк (или их хэшей) заранее отсортировать и искать в нем двоичным поиском, например.
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, _NN_, Вы писали:
_NN>>Python код также будет с линейной сложностью в этом примере
X>в пайтоне это норма, но мы в плюсах так не делаем.
Лёгким движением [1,2,3] заменяем на {1,2,3} и получаем в пайтоне быстрый поиск.
Здравствуйте, _NN_, Вы писали:
_NN>Лёгким движением [1,2,3] заменяем на {1,2,3} и получаем в пайтоне быстрый поиск.
но ни один питонщик об этом не задумается.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[8]: Проверка, что строка равна одному из значений
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, _NN_, Вы писали:
_NN>>Лёгким движением [1,2,3] заменяем на {1,2,3} и получаем в пайтоне быстрый поиск. X>но ни один питонщик об этом не задумается.
Здравствуйте, Lonely Dog, Вы писали:
LD>>>В реальности, в этом if гораздо больше условий. На питоне я бы написал это так: LD>>>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код? _>>
LD>так а дальше что? в функции будет тот же самый большой if с кучей условий
1. Внутри функции можно переменную коротким именем назвать, типа "s" или "x"
2. Имя функции — бесплатный комментарий что там вообще происходит (в чем смысл условия)
3. Околонулевой оверхед
4. Не парим людям мозг на ровном месте, вводя сеты или initializer list
В общем, не жили хорошо — не стоит и начинать. Вот был бы нормальный "in" или switch — его и надо было бы использовать.
Re[3]: Проверка, что строка равна одному из значений
Здравствуйте, Sergey_BG, Вы писали:
S_B>У меня не компилируется ни в VS2015, ни в идеоне S_B>Да и страшно как-то выглядит. Объявляешь переменную. Статик. В ифе. Потом точка с запятой. А потом условие.
Так можно писать начиная с C++17.
Здравствуйте, Lonely Dog, Вы писали
LD>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код?
Если не хочется использовать ассоциативные контейнеры:
using namespace boost::algorithm;
using namespace std;
using namespace std::placeholders;
if (any_of(vector<string>{"1234", "2345", "3456"}, bind(equal_to<string>(), status, _1)))
cout << "found it!\n";
Здравствуйте, DenisCh, Вы писали:
DC>Здравствуйте, niXman, Вы писали:
X>> линейная сложность.
DC>А что, это можно сделать быстрее, чем О(n) ? DC>Поделись мудростью.
С помощью trie можно за время, пропорциональное длине проверяемой строки, и не зависящее от n (количества строк-условий). Конечно, это требует препроцессинга, как и с set.
Здравствуйте, Lonely Dog, Вы писали:
LD>Есть следующий код: LD>
LD>if (status == "1234" ||
LD> status == "2345" ||
LD> status == "3456")
LD>{
LD> // do something
LD>}
LD>
LD>А можно ли что-нибудь такое написать на C++, как-нибудь сократить код?
Да:
static const std::set<std::string> validStatuses { "1234", "2345", "3456" };
if (validStatuses.count(status) > 0)
{
// do something
}
Можно в одну строку внутри if (как уже приводили ранее), но будет смотреться странно. Для пущей красоты можно оформить "count() > 0" как отдельную функцию, но так же будет смущать читателей.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[2]: Проверка, что строка равна одному из значений
Здравствуйте, RussianFellow, Вы писали:
RF>Правильно писать:
RF>if ((strcmp(status,"1234")==0)|| RF> (strcmp(status,"2345")==0)|| RF> (strcmp(status,"3456")==0)) RF>{ RF> // do something RF>}
RF>Потому что в C/C++ строковая переменная представляет собой указатель на самый первый (нулевой) элемент строки. И поэтому для сравнения строк надо пользоваться не = , а функцией strcmp, которая возвращает 0 в случае равенства и ненулевое значение в случае неравенства.
В С++ есть класс std::string, и перегруженный operator==(). Если тип status — std::string, то сравнение status == "1234" сравнивает строки. А strcmp нужно использовать для типов char* или char[].
Здравствуйте, Коваленко Дмитрий, Вы писали: КД>В массиве будет строго два элемента. Без терминального нулевого символа.
Да. Но можно инициализировать строкой "ab". В этом случае длина массива будет 3 символа.
Сергей
Re[5]: Проверка, что строка равна одному из значений
Здравствуйте, DenisCh, Вы писали:
DC>А что, это можно сделать быстрее, чем О(n) ? DC>Поделись мудростью.
Не знаю что тут за n, но поиск в боре, например, будет иметь другие асимптотики по сложности...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Проверка, что строка равна одному из значений
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Здравствуйте, AleksandrN, Вы писали:
AN>>А strcmp нужно использовать для типов char* или char[].
КД>Сдается мне, с char[] могут быть траблы...
КД>
КД>const char c[]={'a','b'};
КД>
КД>В массиве будет строго два элемента. Без терминального нулевого символа.
КД>Я все правильно напутал?
Траблы могут быть везде. Си не мешает стрелять себе в ногу. Можно и в char* записать строку без 0-символа в конце. Разработчик должен понимать, что он делает, как строки инициализировать и что использовать для сравнения, strcmp(), strncmp() или свой велосипед. Но все разработчики ошибаются.