Обратный порядок слов на C++17 и Си
HTML-код
- Опубликовано: 29 окт 2020
- ЗАДАЧА: Напишите функцию, меняющую порядок слов в строке на обратный. Пример: "Two wrongs make a right in C++." станет "C++. in right a make wrongs Two".
Алгоритм в Си: переворачиваем всю строку: ".++C ni thgir a ekam sgnorw owT", а потом остается только перевернуть каждое слово.
Алгоритм в C++17: разделяем строку по пробелам, складывая в вектор, и затем меняем местами с помощью reverse.
С++: наша программа больше похожа на псевдокод
Python: 🗿🗿🗿
😂
1:55 Чистенько быстренько.
Python: 🗿🗿🗿
Спасибо за видео, и заряд положительных эмоций! в Obj C - нечто подобное так же писал что бы не забыть.
От лица абсолютно зелёных плюсистов, хочу поблагодарить за опубликованный материал. А также, хотел бы лично попросить осветить тему дружественных классов. Всех неравнодушных прошу поставить лайк, чтобы привлечь внимание автора!
Спасибо огромное!)
Вааав.
Сразу лайк!!!!
Спасибо!!!!!!!!!!!
0:53 Вот ничего не сказала, а такая милота!... 😇 Прямо люблю вас!
На 1:05 так же! 😊
Лайк за новую причёску!
🤣)) Хоть что-то Вам понравилось)).
@@DariaEmacs В действительности многое что нравится и я не только про внешность.
Но не нравится реакция на критику, вопросы, призывы к обсуждению, уж больно близко к сердцу Вы это воспринимаете.
Да, есть такое...
Клёвая
Я перед видео решил сам попробовать написать, и получился довольно простой код. Я почему-то думал что скорее всего сейчас увижу более "оптимизированный" способ чем у меня, без вектора допустим, но нет, оказалось почти также: текст -> массив слов -> reverse -> текст.
Мне очень понравились ваши видео особенно про книги
Спасибо! Я очень рада
Если работаете в области системного програмирования то я хотел бы спросить у вас коечто
Забавное видео. Предлагаю пойти дальше, следующий шаг будет Scala (к примеру), а дальше можно взать Python (например). Но выбор языка, прежде всего, исходит из ограничений среды исполнения (будет код выполняться на маломощном контроллере или на облачном сервере). Во вторую очередь рассматриваются ограничения на скорость исполнения (код запуска срабатывания тормозной системы автомобиля в экстренных ситуациях или игра "Сопер"). Затем учитываеется возможность интеграции (наличие или отсутсвие готовых библиотек, решающих часть потребностей проекта). И только потом учитывается стоимость в человекочасах (причем с учетом различной стоимости часа разработки для разных языков). Поэтому сравнивать языки - это здорово, но не стоит забывать, что каждое сравнение должно происходить в строго определенном контексте. Потому как вне контекста - сравнение двух языков, это все равно что сравнение отвертки и молотка. Дырки можно делать и тем и тем, но иногда лучше взять дрель.
У тебя неверные представления, а вернее однобокая определённой секты. Вся эта херня с молотком - оправдания, не более. Существуют полноценные языки(их полтора) и мусор. Основная задача мусора - снижение порога входа. Рынок представляет из себя пирамиду, почти вся она(за исключением верхушки) писать на полноценном языке что-либо не может в принципе. Вот здесь уже и работают эти молотки и прочая чушь. Недоязычки и их комьюнити слишком узкие. Поэтому они разные и рассованы по областям. Ну и да, полноценный язык не является инструментом. Он является материалом. Из которого и сделана твоя отвёртка, дрель, молоток.
Для программы на С попробуйте обработать строку с размером UINT_MAX. Будте внимальны с микшированием signed unsigned. Хотя поидее об этом должен был предупредить компилятор.
В любом случае делаете полезную работу. Для себя и для других
Спасибо), учту).
Спасибо за видео! Хоть Си в голове освежил) Как-то непривычно без вставок) Или этим режиссерским ходом Вы решили хардкрорность Си подчеркнуть?😂
Да, Александр, Вы извините, мне в последнее время хочется попробовать разнообразные стили. В общем, предупреждаю, если будет что-то совсем не в стиле), это мои эксперименты).
@@DariaEmacs "что-то совсем не в стиле"... Заинтриговали, ждём-с😌
🤣
@@DariaEmacs Я лично только за упор на "полезность хронометража" и минимум не информативных вставок.
@@avazart614 Я мне наоборот нравится) Полно "полезных по хронометражу" каналов. Хочется иногда что-то и для ума и для души посмотреть) Хотя дело тут не в хронометраже и вставках, а в Авторе. Да и о вкусах не спорят)
А вот теперь то же самое, только для utf-8 строки))
В примере ещё разница в том, что в плюсовой версии аллоцируется дополнительная память, а в сишной мы фактически используем только строку, которая иначально дана.
)) да, как хорошо, что хоть кто-то заметил)).
Скажите, плиз, как дойти до такого уровня понимания работы языка C и C++? 😯 Много ль книжек прочитать? Или курсы закончить? Или онлайн какие-то материалы есть?...
Для более-менее нормального уровня я читала и делала упражнения из этих книг (а также курсовые):
1. Б. Керниган, Д. Ритчи "Язык C" (как база для осознания, как всё происходит на низком уровне)
2. Б. Керниган, Р. Пайк "Практика программирования"
3. Брюс Эккель "Философия С++. Введение в стандартный С++"
4. Брюс Эккель, Чак Эллисон "Философия С++. Практическое программирование"
5. Скотт Майерс " Эффективное использование C++. 50 рекомендаций по улучшению ваших программ и проектов."
6. Скотт Майерс "Эффективное использование STL"
и другие книги Маейрса, хоть сейчас уже стандарт другой, но всё равно там разобраны вечные темы.
---------------------
Далее уже более продвинутый уровень:
7. В шаблоны я погружалась с А. Александреску "Современное проектирование на С++".
8. Затем книги по C++17 (Страуструп)
9. С++17 STL. Стандартная библиотека шаблонов. Яцек Галовиц
У меня было видео про книги.
По поводу курсов.. все хвалят "Основы разработки на C++: белый пояс" и другие пояса. Но я сама про них ничего не знаю, я только смотрела выступление Шишкова Ильи Ивановича на youtube (мне понравилось его отношение к предмету, и то, как они построили курс).
@@DariaEmacs Спасибо большое! Благодарю! Достаточно исчерпывающая информация! 🙂
@@Rafael_Santi начните с уроков по си ruclips.net/video/YHl6bNkct-g/видео.html этот мужик лучше всех объясняет суть.
Только в С меньше памяти будет расходоваться. И ещё с++ медленней будет.
А почему бы не сделать алгоритм в C на плюсах? Он же эффективнее. Так-то это 2 разных алгоритма, один модифицирует строку, которую ему выдали, второй по сути создаёт новую. На C тоже можно сохранять промежуточные значения в массив. Для сравнения алгоритм с модификацией исходной строки на C++:
#include
#include
void reverse(std::string &str)
{
const auto str_begin = str.begin();
const auto str_end = str.end();
std::reverse(str_begin, str_end);
auto get_start_of_next_word = [str_end](auto search_from) {
return std::find_if_not(search_from, str_end, [](char c){return c == ' ';});
};
auto word_begin = get_start_of_next_word(str_begin);
while(word_begin != str_end) {
const auto word_end = std::find(std::next(word_begin), str_end, ' ');
std::reverse(word_begin, word_end);
word_begin = get_start_of_next_word(word_end);
}
}
int main()
{
std::string str_to_reverse = "Two wrongs make a right in C++";
std::cout
все, понял в чем разница, в плюсах шрифт больше чем на сях )
Чтоб узнать как внутри, учите Assembler)
У меня проект таков железо на микроконтроллерах на ASM драйвер на C а прога с GUI на C++(QT5).
Ого! Вы на все руки Мастер!
def reverse_words(s):
return " ".join(reversed(s.split()))
может там есть какой-нибудь boost::split и boost::join... не может же быть что такие простые вещи в C++ так сложно делать. можно хотя бы не считать размер вектора лямбда-чудо-юдо конструкцией..
boost, всё-таки, сторонняя библиотека, всегда хочется обойтись стандартом. (А я, вроде, не размер вектора считала, а количество пробелов, размер вектора просто v.size())
И как я помню там есть вопросы к производительности boost::split
Про boost::join не слышал, можно ссылку?
@@DariaEmacs Я бы сказал что никогда не получается обойтись только стандартом.
@@avazart614 Вопросы с производительностью есть у всего подобного дерьма. Это его свойство. Просто за пределеами С++ это никого не волнует. С макак нельзя требовать многого.
Дарья если не секрет где и кем вы работаете сейчас?
Работаю на себя, пишу приложения под андроид и работаю с OpenCV.
Машинное зрение и искуственный интелект opencv если не ошибаюсь
Да, именно.
Решил повторить код, а компилятор говорит, что не знает count_if, и что в std такого нет( В чем ошибаюсь?
Разобрался, надо было #include
Да, всё правильно. У меня компилятор clang, он по умолчанию этот заголовочник включает. :)
@@DariaEmacs на счет компиляторов. Какой лучше всего использовать для windows? Сделать графику через windows.h вне студии это была сущая пытка, пока не попробовал тупо через консоль build tools, по совету сказали слинковать еще две либы и заработало
на с++17 можно еще красивее сделать через string_view
Спасибо большое! Попробую)
std::string reverse(const std::string& str) {
return std::string(str.crbegin(), str.crend());
}
strtok - ом надо было разбить строку и вывести массив в обратном порядке
По мимо того, что string уже массив, так вы еще вектор используете, и поток , вывод в консоль тоже поток...
мне так не нравится...)) вот без функции, на студии 2017:
//---------------------------------------------------------------------------------
#include "pch.h"
#include
//---------------------------------------------------------------------------------
int main()
{
std::string text = "Hello World ...!";
//---------------------------------------------------------------------------------
std::string word = "";
//тут нет пробела.
std::string rev_word = "";
int i2 = strlen(text.c_str());
for (int i = 0; i < i2; i++)
{
if( text.at(i) == ' ') {
rev_word = word + rev_word;
word = " ";
//тут пробел. (если пробел убрать, то будут слова без пробелов, и если много пробелов, то они тоже не будут учитываться).
} else word += text.at(i);
}
if (word != " ") rev_word = word + rev_word; //и тут пробел (или нет если пробелы не нужны).
//---------------------------------------------------------------------------------
std::cout
Ну студия - это студия, там есть много удобных вещей, которые не представлены в чистом С++.
@@aaa__0000 Привет! для GNU gdb 8.1 for MinGW 7.3.0 64-bit
только длинна строки через length, но это и в студии работает, функция std::string. В остальном все тоже самое.
#include
int main()
{ // слова в обратном порядке:
std::string text = "Hello World ...!";
//---------------------------------------------------------------------------------
std::string word = "";
std::string rev_word = "";//тут нет пробела.
unsigned long long i2 = text.length();//.size();//длинна строки.
@@aaa__0000 стандарт он для всех один, оболочка на код не влияет, только на фантазию...))
Доброго времени суток
надо теперь это на ассемблере написать.
Я подумаю).
Нужно просто использовать флаг компилятора -save-temps и на выходе будет код на ассемблере
А в Ассемблере, мелкой моторике вообще обзавидуешся.
Достаточно один раз проморгать при работе со стеклом, сохранить и восстановить значения регистров...
И вот ты уже поуши в отладке.
Меня вот это поражает! Такие разные языки и такие разные подходы, столько областей применения. Когда я об этом думаю, аж внутри что-то радостно загорается)).
@@DariaEmacs ну каждый хорош для своих задач. Си и Си++ мне так же очень нравятся 🙂
@@TheTalants У asm нет никаких задач. К тому же тот плебейский asm, что ты себе представляешь - мусор никому ненужный.
@@rustonelove а я то наивный не знал и досих пор микроконтроллеры время от времени на ассемблере программирую.
От ведь... 😟
в одну строчку на C# :
string result = new StringBuilder().AppendJoin(' ',"abc as bca".Split(" ").Reverse()).ToString();
Ох уж эти Ваши стрингбилдеры ...
Красиво!
@@DariaEmacs я уверен, раза в 3 дольше), если не больше
если вы работаете на Java почему бы вам не освещать темы оттуда?
Я пишу и на C++ и на Java одновременно.
Тем временем JS
str.split(' ').reverse().join(' ')
Тем временем это без дарное, тор мозное, не тайпсейф-го вно. И тем временем это: str | split(' ') | to | shared | reverse | join(' '), на самом деле: str | split(' ') | reverse | join(' '), но то дыра в текущей реализации.
@Никита Титов Где?
@Никита ТитовТы там в школу уже сходил? Что тебе из моих объяснений неясно?
Или посоветуете из знакомых кого то
На ASM по круче но на C проще а C++ для больших и сложных проектов. моё мнение.
На ASM у нас любили программировать пару человек из всего потока. Остальные хотели его скорее сдать и забыть, как страшный сон)). Но он крут, этого никто не отрицает).
У меня беда решил свою ос написать и 3 пк стали кирпичами))
Бывает))), надо потихоньку начинать.
используй virtual box, как Терри Девис
То ли дело Basic.
На эту же задачу, три строчки 😏
Python в одну можно сказать print(reversed(s.split()))
@@avazart614 ну... Питон я не изучал 😏
@@user-yd1zs7nj8m Да точно. Вечно забываю что там не список.
Подразумевалось:
print(list(reversed(s.split())))
@@TheTalants Ну так а про бейсик пора забыть.
@@avazart614 ну незнай... Я ещё на спектруме на нем пишу 🤨 бывает...
Хобби ни кто не отменял 🙄
Ужас. Что С, что С++. Казалось бы такая простая задача и столько кода)
Задача не простая. Она простая если дерьмом обмазаться, ну как в скриптухе.
Как правило задачи на такое подразумевают что слова делятся не только по пробелу, но и по знакам препинания.
Опять же на С++ нет такого метода или алгоритма как split() как например в Python
Кроме того если говорить о Си есть strstok (идр. ф-ции) для разбиения.
Я к тому что более или менее нормальных задачах решение выглядит совсем не так.
В С++ не может быть split как в дристоне. С++ не может превратиться в дерьмо для обезьян. Ну а по поводу "нет" - истории прохладные: godbolt.org/z/KhPdd4 А ну хотя как в дристоне нет, до такого дерьма ещё не доросли.
Нормальные задача на дристне никто не решает. Ну и да, С++ как базовый язык имеет си.
Я никогда не понимал, почему если пишешь на с++ , надо ВСЕГДА использовать stl, , вместо того чтоб писать тот же c код, что и в c, если хочется...
Потому что это неотъемлимая часть языка, стабильная и крутая библиотека, которая понадобится в любом проекте, чтобы не писать свои велосипеды.
@@DariaEmacs ну в зависимости от ситуации, иногда целесообразней использовать чистый c - я считаю. И тебя никто не принуждает писать cout вместо printf
@@andreyua2 stl мусор. Причина по которой используется - оно обобщённое и со всем чем угодно интегрируется. Чистого си не существует. То, что понимается под ним - дерьмо. cout такой же мусор. Есть printf и появился std::format.
@@rustonelove заводи свой канал, выложи уроки - поржем
@@andreyua2 Я не занимаюсь уроками. Для этого есть люди определённого уровня. Да а что ты поржать можешь, дошколёнок? Ты так обделаешься и убежишь на первой же потуге.
Не знаешь C просто во-о-о-обще. Почитай какие-нибудь профессиональные исходники на C, например исходники Git (написаны японцем) или исходники Python.
Зачем там подключен заголовочный файл stdlib.h? "Я просто не знала, что всё это объявлено в stdio.h"
А почему там нет void'а в определении функции main()? "Я просто вообще даже не знала, что C++ отличается от C и определения функции с пустотой переводят C в древний режим определений"
И вот в таком духе всё.
Вот тебе функция оборачивания байтов:
/* bytes_reverse: reverse bytes sequence
return reversed bytes */
void *bytes_reverse(void *bytes, size_t size)
{
unsigned char *p, *q;
unsigned char c;
for (p = bytes, q = (unsigned char *) bytes + size - 1; p < q; p++, q--)
c = *p, *p = *q, *q = c;
return bytes;
}
Никаких массивов тут нет, потому что это просто не принято в C. Есть стандартные идиомы, выработанные десятилетиями.
Конечно, знать надо много, потому что C не скажет тебе, если ты где-то ошиблась, и вылезет это только в продакшене. Поэтому когда пишешь на C, его практически весь надо в голове держать (именно стандарт C, так как никогда не известно, каким компилятором и где программа будет собираться).
Программа несколько раз менялась), что-то осталось подключено от старой версии). И мне не надо было оборачивать байты, мне надо было обернуть слова. Это задание с собеседования и смысл его в том, чтобы посмотреть, как Вы мыслите. Один вариант - с использованием лишнего буфера, а другой - без. Вот и всё).
Здравствуйте, господин (госпожа) main! Имейте, пожалуйста, в виду, что C, в отличие С++ не является профильным языком Автора. В этой связи прошу делать некоторую скидку. Я Вас категорически поздравляю с тем, что Вы настолько мастерски владеете этим языком и находите минуточку для того, чтобы просветить заглянувших в комментарии, но недочеты, на которые Вы столь любезно указали, являются простительными. Тем более, основная задача этого кода - решение задачки, а не демонстрация блестящего владения стандартами.
P.S. Возможно, я, будучи не очень внимательным человеком, упустил момент, где Дарья что-то говорила про оборачивание байтов? Или с какой целью Вы этот код представили?
@@aaa__0000 Заходи лет через десять, поговорим с тобой. Сейчас ты ещё маленький.
@main, Так как Вы, обычно говорят маленькие дети, которые ещё переживают из-за всяких мелочей (О, Боже, здесь должны быть пробелы, а не табы), не понимая ещё, что жизнь многогранна и разнообразна. Чем старше человек, тем спокойней он относится к точке зрения других людей, которая с ним не совпадает. И уж точно взрослый программист не станет никого тыкать носом в ошибки. Так делают только малолетки, которые вчера "это" выучили и сегодня уже ходят петухами. Вы наберите опыта 10+, вырастите. А сейчас Вы повторяйте лишь то, что Вам ещё совсем недавно говорили самому на форумах или старшие коллеги.
@@DariaEmacs
"здесь должны быть пробелы, а не табы"
Там ещё до-о-о-офига чего ещё должно быть. Мы об этом даже не говорим. У тебя стандартное заблуждение - "изучив C++, я изучу C автоматом". И потом ты начинаешь писать, но ты не умеешь пользоваться адресной арифметикой, потому что в C++ она НЕ НУЖНА, и поэтому никто в C++ не будет тебя учить ей. Соответственно, ты пропускаешь этот момент и ты НЕ УМЕЕШЬ ею думать. Поэтому я тебе говорю "прочитай исходники профессионалов", там ты увидишь нормальный сишный код. А профессионал - это не тот, кто пишет программки для собеседований, лишь бы его куда-нибудь взяли ;) , а тот, кто пишет программки, которыми потом миллионы людей пользуются по всему миру, и код свой не прячет, а выкладывает на всеобщее обозрение. Ему не стыдно за свой код.
Уныло, лучше ничего не придумал ))))
#include
#include
#include
int main(void){
char words[] = "Hello darkness, my old friend I've come to talk with you again Because a vision softly creeping Left its seeds while I was sleeping";
int b = strlen(words) ;
char copy[b];
int x = 0;
int w = 0;
for( ; *(words + x++ ) !='\0' ; ){
if( !isgraph( *(words + (x + 1) ) ) ){
for( *(copy + b-- ) = ' ', w = x ; isgraph( *(words + w ) ) ; --w, --b ){
*(copy + b )= *(words + w );
}
}
}
puts(copy);
return 0;
}
Simon & Garfunkel )))