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

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

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

 
 Ответить  Открыть новую тему 
> Задача с использованием файла, нахождение символа в слове
-Студент-
сообщение 13.12.2007 19:09
Сообщение #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
 К началу страницы 
+ Ответить 
-Студент-
сообщение 14.12.2007 20:18
Сообщение #2


Гость






знающие люди , подскажите пожалуйста ... горю , на след. неделе начинается сессия , исправте алгоритм если вам это под силу unsure.gif
 К началу страницы 
+ Ответить 
andriano
сообщение 14.12.2007 20:46
Сообщение #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 - 14.12.2007 20:54
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Айра
сообщение 14.12.2007 20:58
Сообщение #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

Сообщение отредактировано: Айра - 14.12.2007 22:21
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
andriano
сообщение 14.12.2007 21:11
Сообщение #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 
 К началу страницы 
+ Ответить 
Malice
сообщение 14.12.2007 21:24
Сообщение #6


Профи
****

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

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


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

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

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


Гуру
*****

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

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


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


Профи
****

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

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


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

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

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

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

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

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


Гуру
*****

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

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


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


Гость






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


Гуру
*****

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

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


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

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

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

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


Гость






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


Гуру
*****

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

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


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


Гость






2Andriano

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


Профи
****

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

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


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

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

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

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


Гуру
*****

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

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


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

2Andriano

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

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

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

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


Гость






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

2Andriano , допустимая длина строки стандартна , т.е. 255 символов.
 К началу страницы 
+ Ответить 
Айра
сообщение 15.12.2007 21:25
Сообщение #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.06.2025 10:46
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"