IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Задача с использованием файла, нахождение символа в слове
сообщение
Сообщение #1


Гость






Вечер добрый форумчане.
вощем задал препод на первый взгляд не очень сложную задачу , но он у меня вызывает ряд затруднений ...
задание : Подсчитать кол-во слов содержащих хотябы одну букву "m"

вот текст программы , написал что мог

Код

program laba51;
var f1:text;
i:integer;
s:string;
begin
assign(f1,'laba51.txt');
rewrite(f1);
for i:=1 to 5 do begin
readln(s);
writeln(f1,s);
end;
close(f1);
end.

program laba52;
uses crt;
var f1:text;
i,k,l:integer;
s:string;
begin
assign(f1,'laba51.txt');
reset(f1);
k:=0;
while not eof(f1) do
for i:=1 to length(s) do
begin
readln(f1,s);
if s[i]='m' then k:=k+1;
i:=i+1;
end;
writeln ('kol-vo slov = ',k);
close(f1);
READKEY;
end.


если не сложно , исправте пожалуйста ... очень мне поможите

в программе я не реализовал нахождеименно слова ... неполучается это сделать unsure.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






знающие люди , подскажите пожалуйста ... горю , на след. неделе начинается сессия , исправте алгоритм если вам это под силу unsure.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


У тебя проблема в этом фрагменте:

for i:=1 to length(s) do
begin
readln(f1,s);
if s[i]='m' then k:=k+1;
i:=i+1;
end;


Смотри, ты организуешь цикл по всей длине строки ДО того, как ее прочитал. И чтение целой строки у тебя оказалось ВНУТРИ цикла по буквам строки.
Оператор чтения нужно вынести из цикла - поставить его выше, чтобы к моменту начала цикла строка уже была прочитана.
Далее, как только ты переставишь строчку, она окажеся вне begin...end, поэтому для выполнения всего цикла while понадобится еще парочка.
Ну и переопределять переменную цикла внутри этого цикла недопустимо.



Сообщение отредактировано: andriano -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +



for i:=1 to length(s) do
begin
readln(f1,s); //замени на read, иначе будет считываться только 1-й символ каждой строки
if s[i]='m' then k:=k+1;
i:=i+1; //так нельзя делать
end;

А как такой вариант:
program laba52;
uses crt;
const simvol : set of char = [',','.',':',';','-', '!', '?', ' ']; //множество символов-разделителей слов
var f1:text;
k:integer;
l: boolean;
ch: char;
begin
l:=true; //true, если началось новое слово
assign(f1,'laba51.txt');
{$I-}
reset(f1);
{$I+}
if IoResult = 0 then //проверям, найден ли нужный файл
begin
k:=0;
while not eof(f1) do
begin
read(f1,ch); //считываем посимвольно
write(ch); //выводим для нагляности
if ch in simvol then l:=true; //если ch символ-разделитель, то мы в новом слове
if (ch='m') and l then //если ch нужный символ и слово новое, то...
begin
inc(k);
l:=false; //теперь слово уже не новое, это значит, что если в слове несколько 'm',
//то оно считается как одно слово с этой буквой, а не несколько
end;
end;
writeln;
writeln ('kol-vo slov = ',k);
close(f1);
end
else writeln('файл не найден');
end.

если что непонятно, спрашивай smile.gif

Сообщение отредактировано: Айра -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Вообще-то s - это строка, так что проблем с этой строчкой кода быть не должно (кроме того, что она не в том месте)
    readln(f1,s);   //замени на read, иначе будет считываться только 1-й символ каждой строки

А вот эти две строки меня озадачивают:
            if ch in simvol then l:=true;   //если ch символ-разделитель, то мы в новом слове
if (ch='m') and l then //если ch нужный символ и слово новое, то...

Строго говоря, первую строку можно записать в виде:
l := ch in simvol

А их вместе:
            if (ch='m') and (ch in simvol) then  //если  ch нужный символ и слово новое, то...

Что эквивалентно
if FALSE then
т.к. один и тот же символ не может одновременно равняться m и быть разделителем.
Таким образом весь этот блок можно выбросить, оставив только вывод нуля на экран.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 705
Пол: Мужской

Репутация: -  20  +


Цитата(andriano @ 14.12.2007 21:11) *

А вот эти две строки меня озадачивают:

А что если назначение этой строки проявит себя на следующем витке цикла while ? Ее все равно можно сократить ? Коль уж вы взвалили на себя нелегкую миссию цензора, комментирущего код не вопрошающего, а отвечающего, то будьте добры производить наиполнейший анализ всего кода, чтобы от столь пространных умозаключений хотя бы не было вреда.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Да, признаю, в анализе допустил ошибку.
Тогда получается, что если текущий символ m, а предыдущий - разделитель, то учитываем.
И эта возможность учесть у нас сохраняется до первого m, а затем утрачивается до нового разделителя.
Да, получается, что приведенный код может работать. Но логика работы достаточно запутана.
В исходной программе, вроде бы, предполагается, что текст содержит по одному слову на строке. Неплохо бы прояснить этот момент.
Кстати, если учитывать разделители, то мне кажется, в их число необходимо внасти пробел и символ табуляции. А, возможно, даже все символы, явно не описанные как буквы. (опять же - неопределенность условия)
Но не лучше ли поступить по следующему алгоритму:
1. Все разделители заменяются на пробелы.
2. Все двуойные пробелы заменяются на одинарные.
3. Строка режется на фрагменты по пробелам.
4. Каждый фрагмент проверяется на наличие искомого символа.
?
Мне кажется, такой алгоритм более прозрачен и подходящ для учебных целей.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +


Цитата
Но логика работы достаточно запутана.

Женская логика завораживает своей алогичностью (с) blum.gif
Цитата
В исходной программе, вроде бы, предполагается, что текст содержит по одному слову на строке

В исходной программе, но в задании об этом ничего не сказано.. Будем ждать разъяснений автора?..
Цитата
в их число необходимо внасти пробел и символ табуляции

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

Это твое ИМХО, если тебе так понятнее, то делай так, я же сделала как легче мне, тем более каких-то определенных условий по алгоритму в задании нет..

Сообщение отредактировано: Айра -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Табуляция в Паскале обозначается #9.
С точки зрения текстового файла интересна тем, что это СТАНДАРТНЫЙ разделитель для текстовых файлов экспортируемых/импортируемых Excell. То есть пример не учебный, а самый что ни на есть практический. ;)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Предпологается , что в строке символов слов может быть сколько угодно ...
и нужно считать именно те слова (а словом считается набор символов ограниченных с 2 - ух сторон пробелами) в которых есть хотябы 1 буква "m" т.е. слово "mama" будет считаться как 1 слово
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Цитата(-Студент- @ 14.12.2007 23:38) *
словом считается набор символов ограниченных с 2 - ух сторон пробелами
Уточнение:
правильно ли я понял, что в строке "мама мыла раму" содержится только одно слово "мыла", т.к. остальные ограничены пробелами лишь с одной стороны?

И еще:
Цитата
Предпологается , что в строке символов слов может быть сколько угодно ...

в Паскале строка не может содержать более 255 символов. Означает ли это, что программа должна уметь обрабатывать и более длинные строки (это возможно, но тогда весь инструментарий работы с такими строками придется писать самостоятельно)?

Сообщение отредактировано: andriano -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Цитата
весь инструментарий работы с такими строками придется писать самостоятельно
Ты знаешь, если тебе делать особо нечего, можно и System.pas заново переписать, а так - весь инструментарий для работы со строками длиной до 64k находится в модуле Strings, можно его сразу использовать...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


В Паскале строк длиннее 255 символов НЕТ!
Различные компиляторы Паскаля поддерживают разные РАСШИРЕНИЯ языка, несовместимые друг с другом. В ТМТ, напрмер, модуль strings допускает работу в 255-символьными строками, а также с оканчивающимися нулем стоками из одно- и двухбайтовых (unicode) символов. 64К-байтных строк там нет.
А если бы и были, какая разница, если требуется обработка строк ЛЮБОЙ длины?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






2Andriano

Нет , в строке "мама мыла раму" будет 3 слова , слово с двумя и более "m" будет считаться как 1 слово , нужно подсчитать кол-во слов в которых есть хотябы 1 буква "m"
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +


Цитата
ограниченных с 2 - ух сторон пробелами

это предполагает, что других символов в строке нет?

А вообще, программка, которую я выкладывала выше, вроде работает нормально.. Разделяет на слова она, в принципе, так, как мы привыкли разделять (в плане знаков препинания и т.п.).. и считает тоже вроде верно.. Тебе в ней что-то непонятно, что-то неустраивает? Спрашивай. А то мы развели уже тут дискуссию по поводу действительно "не очень сложной задачи" smile.gif

Сообщение отредактировано: Айра -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Цитата(-Студент- @ 15.12.2007 14:41) *

2Andriano

Нет , в строке "мама мыла раму" будет 3 слова , слово с двумя и более "m" будет считаться как 1 слово , нужно подсчитать кол-во слов в которых есть хотябы 1 буква "m"

Это явно противоречит тому, что ты писал выше:
Цитата
словом считается набор символов ограниченных с 2 - ух сторон пробелами

Так что за тобой третья попытка корректно сформулиовать условие задачи.

И, кстати, еще раз прошу уточнить насчет допустимой длины строки: если ограничение есть, целесообразнее читать файл как текст и воспользоваться стандартным набором процедур для работы со строками. Если ограничения нет, лучше читать файл как бинарный и решать задачу при помощи конечного автомата.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость






ну задача для первого курса smile.gif
нечего сверхъестественного в ней быть недолжно , мне только непонятно что за переменная IoResult или это стандартная процедура ? и что за спец. символы {$I-} , такого мы ещё не изучали ... и ещё переменная "Inc" , за что он отвечает ? Объсните пожалуйста smile.gif

2Andriano , допустимая длина строки стандартна , т.е. 255 символов.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Профи
****

Группа: Пользователи
Сообщений: 731
Пол: Женский

Репутация: -  25  +


Цитата
что за переменная IoResult ... и что за спец. символы {$I-}

{$I} - директива компилятора, которая отлавливает ошибки ввода/вывода - если, например, файла, к которому ты обращаешься нет, то компилятор "поругается" и закроет программу. А {$I-} - отключиние этой проверки -> ошибка выскакивать не будет.. {$I+} - включение этой директивы.
А вот функция IOResult возвращает результат последней операции ввода/вывода: 0 - если ошибки не было (файл нашелся) и какое-то положительное число (код ошибки), если операция ввода/вывода потерпела неудачу))

Т.е. для корректной обработки ошибок ввода/вывода я отключила стандартную проверку {$I} и использовала IoResult.

Цитата
переменная "Inc" , за что он отвечает

inc(x) - процедура, которая по умолчанию увеличивает значение аргумента x на 1, если ввести еще один параметр, например inc(x,5), то значение будет увеличиваться на 5.

Вроде объяснила, если еще что-то непонятно, спрашивай, попытаюсь расшифровать smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 24.11.2020 0:24
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name