Ю12.34

Задача.

«Балда». Для заданного достаточно длинного слова найти в имеющемся словаре все слова, в которых использованы только буквы, имеющиеся в заданном слове (с учетом кратности вхождения).

Тесты.

Ввод Вывод Комментарий
programming a in on go no an man am or arm air ring ago pain grin rain mom main among roar grip pair rip map nor aim iron program pin ma moan groan gang gain rag pig piano ramp gin ram rig Пройден
polymorphism is his him my so or room sir ship lip slip mom shop simply pop rip poor pool sip oil holy hip limp hop prop spy loom Пройден

В качестве словаря используется список 2500 наиболее употребительных английских слов (составлен Александром Васильевым).

Код(string).

Используем ввод как условие цикла while. Вводим вспомогательную строку temp, в которую записываем исходное слово. Символы строки temp, которые совпадают с символами данного слова из словаря, заменяем на точки (подходят любые символы, кроме английских букв), учитывая, таким образом, кратность вхождения. Также для проверки вводим логические переменные b1(содержатся ли все символы из строки dict в temp?) и b2(содержится ли j-ый символ из dict в temp?).

Данный код на ideone.

Код(c-string).

Решение аналогично.

Данный код на ideone.

Related Images:

6 thoughts on “Ю12.34

  1. Со string вариантом все нормально. Можно (и желательно) его немного оптимизировать, выходя из цикла, как только выполнено условие if (!b2), т.е. как только не удалось найти очередную букву слова из словаря. Ну еще на Ваши циклы компилятор будет жаловаться про сравнение знаковых, беззнаковых чисел — индексы можно сделать unsigned или size_t — чисто технический момент.

    Конечно, если говорить об оптимальности алгоритма, можно было сделать эффективнее, у Вас приходится искать ( за O(n) ) очередную букву слова из словаря в нашем слове temp — для коротких слов ( n — длина слова) впрочем это быстро.

    Но, главное, прокомментирован код очень неудачно
    //описание переменных и ввод исходных данных
    каких переменных, для чего они используются
    ввод исходных данных — в каком формате — формат исходных данных остается только угадывать из кода программы
    у Вас записаны очевидные вещи в комментарии, но упущены неочевидные
    //проверка условия
    опять же такой комментарий уместен, только если из контекста понятно какого условия, т.е. это условие явно упомянуто ранее, т.е. условно говоря может быть комментарий на англ. checking THE condition, но не может checking A condition.
    Еще и имена переменных подобраны b1,b2 — мало о чем говорящие (temp тоже мало что говорить — но использование этой переменной пояснено в отчете).

  2. А вот по варианту с Си-строками есть замечания:
    1. i<strlen(word) — очень плохое (неэффективное) условие продолжения перебора символов строки — ведь каждый раз приходится пересчитывать длину строки заново (если оптимизатор не постарается). Оптимальное по скорости — идти, пока не наткнетесь на ноль-символ.

    for (int i=0;i<strlen(temp);i++)     {      if(temp[i]=='.') temp[i]=word[i];     }
    тут вообще странно мы вначале проверяем, а заменен наш символ на точку, и если да, так уж и быть запишем его на место. Такой стиль уместен если быстродействие записи (модификации) информации намного меньше, чем чтения — что для оперативной памяти неверно. В C++-варианте строк вообще стояло присваивание — не логичнее использовать тогда здесь функцию strcpy.

    Ну и последнее — скорее информация к размышлению: а вдруг пользователь введет слово длиннее чем 100 символов? Как от этого защитится?

  3. Извините, сразу не заметил, но у Вас получается, что в самом внутреннем цикле уже условие b2 истинно — т.е. буква найдена, тем не менее цикл продолжается, и приходится дописывать в условие if(dict[j]==temp[i] && !b2) вторую часть !b2, чтобы не удалить еще одну букву — классический случай, где оператор break поможет упростить программу и сделать ее более эффективной. Если не нравится использование break в данном случае — то добавьте && !b2 в условие продолжения цикла и не будет бесполезной работы — хотя по идее вариант с break чуть эффективнее.

    Исправите и C++-string вариант засчитаю.
    А в С-варианте ерунда написана word[i]!='', j<dict[j]!=''???? На ideone чуть лучше: word[i]!='\0' — вот это верно, j<dict[j]!='\0' — часть j< абсолютно лишняя. Будьте внимательнее. Комментарии сейчас намного лучше, но неидеальны. Да и имена переменных неудачные - но эта видимо наша проблема, как преподавателей - что не научили правильно называть переменные и наверное где-то показывали сами примеры плохого именования. Меня в свое время тоже не научили правильно называть переменные - и сейчас это ОЧЕНЬ мешает. Но уж комментарии постарайтесь писать подходящие. Почитайте «Совершенный код» Макконнела, начиная со страницы 768 (768 — стр. книги, в приведенном документе стр. 787) докуда хватит сил (хотя бы 2-3 стр.) Вообще книга для профессионального (в будущем) программиста очень полезная.

    • Спасибо.
      Добавил break-и.
      В отчете изначально было написано word[i]!='/ 0'(без пробела заменяет на ''), но после обновления Crayon заменяет запись на word[i]!=''.
      Прочитал раздел о комментировании до конца, но всё равно возникают некоторые сложности. В ближайшее время обещаю подойти к этому вопросу серьезнее.

  4. Вот это да, нашли глюк компонента Crayon !
    Пока засчитаю работу, 10 баллов + 10 баллов, в следующем семестре уделим больше внимания именованию переменных и написанию комментариев.

Добавить комментарий