|
Программирование >> Унарные и бинарные операторы
где в качестве параметров указаны две ссылки. Это значит, что при вызове функции exchngCx.y) создаются две ссылки: а ссылается на х, а b - на у. И теперь любые изменения а и b внутри функции отразятся на связанных с ПИ.МИ внешних объектах х и у. Хоть передача указателен и передача ссылок приводят к одному и тому же результату, ссылки считаются более удобными и чаще используются в C-I-+. Функцию, принимаюп1ую ссылки, легче нанисать, потому что не нужны бесконечные звездочки перед именами параметров. Но с другой стороны, ука,затели делают работу функции совершенно нро.зрачной, а ссылки скрывают от програ.ммиста то, что происходит на само.м деле. Кроме того, вызов (})ункцин при передаче ссылок смотрится так же, как п при обычной передаче а1)1умептов (ее называют передачей по значению ), что может привести к путанице. Впрочем, выбора - применять и.тп не применять ссылкрг - не сугцествует. Ссылки встречаются в програ.ммах на С++ постоянно. Значит, нужно к ним привыкнуть и умело ими пользоваться. А на самом деле компилятор рассматривает ссылки как указатели, которые нельзя перенаправить на другие объекты. Встретив объявление ссылки int &b=a. компилятор преобразует его в int *Ъ-&а II дал1.П1с всюду, где встречается Ь, ставит *Ь. 6 Разработка программы Алгоритм Отчего у нас никогда нет времени сделать что-либо хорошо, по всегда находится время на переделку? Д. Ван Тассел, *Стиль, разработка, эффективность, отладка и испытание программ Почему В работе, выполненной одним, все так гармонично и так подходит друг к другу, а у другого все трещит по П1вам и разваливается? Вовсе не потому, что кто-то - талант и баловень судьбы. Практически все испытывают трудности, у всех что-то не получается, и если чужая работа напоминают длинную цепь удач, то лишь потому, что автору пришлось много думать, пробовать, переделывать, искать и находить ошибки, быть может, ему немного повезло, а в результате получилось что-то легкое и красивое. В этом разделе я попробую приоткрыть завесу над процессом программирования и попытаюсь у вас на глазах решить довольно простую задачу: создать новый словарь для нахождения анаграмм. В разделе Анаграммы главы 4 мы пользовались словарем, содержащим около 20 ООО слов, что довольно мало. Но где найти больший? Первое, что приходит в голову, - конечно же, Интернет. Чтобы найти там словарь, достаточно поискать документ, в котором есть несколько слов, наугад выбранных из старого, мален1>кого словаря. Если поискать с помощью Google (www.google.com) слова aardvark , aardvarks , аЬаск , abaft , abalone . Первая версия Начинать работу лучше с небольшого, но работаюнхего фрагмента профаммы. Полный текст только что написанной большой профаммы напоминает вражеское минное поле, где мины (ошибки профаммиста) находятся в неизвестных местах и могут сработать в любой момент. Адрес этого словаря весьма красноречив: www.gtoal.com/word-games/cherry/anagram/words, ведь wordgamcs - это игры со словами , а что такое anagram , вы и сами знаете. ТО уже среди первых десяти адресов появится словарь, содержащий почти 90 ООО слов. Но и это не предел. Можно попробовать найти больший словарь, а можно попытаться расширить его собственными силами. Для этого нужно извлекать слова из всех доступных английских текстов и проверять, нет ли их в словаре. Естественно, все новые слова добавляются в словарь, и поиск продолжается. Таков в самых общих чертах план создания словаря. Но чтобы начать программирование, этот план нужно уточнить. Программа должна начаться с чтения текущей версии словаря и превращения ее в некий контейнер (например, тар). Далее программе нужно указать имя читаемого файла. Это может быть другой словарь или какой-либо текст ( Алиса в стране чудес , Пиквикский клуб , Гамлет - что угодно). Затем нужно научиться извлекать слова из выбранного текста и каждое извлеченное слово искать в словаре. Если слово уже есть, переходить к следующему, если нет- включать его в словарь. После проверки всех слов остается только записать новую версию словаря (лучше под другим именем) и закончить работу. Только что описанная профамма похожа на пылесос. Она глотает все доступные ей тексты и постепенно наращивает свой словарный запас. В словаре десятки тысяч строк, и от вывода его на .экран пользы немного. Но операционная система позволяет легко псрспапра вить вывод. Если имя программы 161.cxc, то, записав в командной строке команду I61.exe > z и нажав клавишу Enter, мы перенаправим вывод в файл Z - быстро и удобно. Промежуточные варианты в первом варианте программы гспользовался другой тип контейнера - вектор. Попытка скомпилировать текст профаммы не удалась, потому что я забыл включить заголовок #include <vector>. После включения заголовка, а также исправления мелких опн1бок (.забыл объявить нерсменпую и поставить в одном месте точку сзапятой) выяснилось, что программу все равно нсл1хзя компилировать - из-за того, что для вектора, оказывается, не существует собственной функции findC). Пришлось реатизовывать ее вручную: int dict findCvector<string> d.string s){ for Cunsigned i=0:i < d.sizeC):i++) ifCd[i]==s) return i: return -1; Обратите пнп.мапне, переменная i цикла forC) объявлена как unsigned, потому что именно таков тип значения, возврап1аемого функцией d.sizeC). Если объявить ее как int, некоторые компиляторы откажутся сравнивать разнотипные неременные. После всех onncainibix изменений программа заработала, и тут выяснилось, что контейнер vector не очень приспособлен к нашей задаче, потому что поиск в нем идет слишком долго. Взгляните еще раз на функцию dict find(). В ней строка s сравнивается с каждым из элементов контейнера. Это означает, что в среднем придется при каждом поиске уже известного слова перебрать половину элементов контейнера. А с учетом того, что составление слова1)я потребует перебора сотен тысяч слов (и каждое придется искать в словаре), затраты времени становятся огромными. В этом месте у .многих читателей наверняка возникнет вопрос: а можно ли искать элемент в контейнере Начнем пашу программу с фрагмента, который читает словарь, заполняет контейнер, ищет в нем задан нос (пока вручную) слово и затем выводит измененный словарь на экран. Соответствующий текст показан в листинге 6.1. Листинг 6.1 #inc1ude <iostreatD> #inc1ude <fstream> #include <string> include <map> using namespace std; int mainC){ char b[80]: string w= zzzzzzzzz ; nap<string.string> diet: map<5tring.string>::iterator im; ifstream infileCdiction ); while (1){ infile.getline(b. sizeof(b)): ifCinfile.eofO) break: dict.insert(pair<string.string>(b. )); di ct.i nsert Cpai r<stri ng.stri ng>Cw. n )); forCim=dict.beginC):im != dict.endC):im++) cout (*im).first endl: infile.closeC): return 0: Этот фрагмент кажется очень простым, но у меня он заработал лип1Ь с шестой или седьмой попытки. Едва ли будет интересно смотреть на все промежуточные варианты, поэтому попробуем ограничиться их кратким описанием.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |