Форум программистов, компьютерный форум, киберфорум
Pascal (Паскаль)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.90/21: Рейтинг темы: голосов - 21, средняя оценка - 4.90
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49

Получение нового текстового файла, в котором все слова во всех предложениях записаны в обратном порядке

24.02.2014, 19:31. Показов 4778. Ответов 39

Студворк — интернет-сервис помощи студентам
Запрограммировать получение нового текстового файла, в котором все слова во всех предложениях записаны в обратном порядке. В программе установить максимальный размер стека равным 10.

Текст большой, поэтому выложу последнее предложение, в котором слов больше 10.

"Тайник я создал пару дней назад, незаконно использовав один из компьютеров транспортного управления з кавказской железной дороги."

Я мучаюсь уже довольно долго с этой проблемой, вот пытался что-то написать, но всё равно переполнение не удается обойти.

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
uses crt;
const
  MaxStek = 10;
var
  a: array[1..MaxStek] of string;
  t, g: text;
  i, n, k, q, st: integer;
  s, m: string;
 
procedure POP;
begin
  write(g, a[q], ' ');
  a[q] := '';
  q := q - 1;
  writeln ('Из стека убрано значение. Текущее количество элементов в стеке: ',q)
end;
 
procedure PUSH(str: string);
begin
  q := q + 1;
  a[q] := str;
  writeln ('В стек помещено значение. Текущее количество элементов в стеке:',q)
end;
 
begin
  assign(g, 'g.txt');
  rewrite(g);
  assign(t, 'k.txt'); {исходный файл}
  reset(t);
 
  m:= '';
 
  while not EOF(t) do begin
    readln(t, s);
    if (Length(s)>0) and (s[Length(s)]<>' ') then s := s + ' ';
    k:= 0;
    n:= 1;
    i:= 0;
    for n:= 1 to length(s) do begin
      i:= n - k; 
 
      if (s[n] = ' ') then begin 
        m := copy(s, k, i);
        k := n; 
      end;
 
      if (m <> '') and (q <= MaxStek) then begin 
        PUSH(m);
        m:= '';
      end;
 
      if q = MaxStek then begin
        for st := 1 to q do
          POP;
        writeln(g);
      end;
 
    end;
 
  end;
 
if q<>0 then begin
for i:=1 to q do
POP()
end;
 
  close(g);
  close(t);
end.
Вот результат выполнения программы, но это неверно:
" из один использовав незаконно назад, дней пару создал я Тайник
дороги. железной кавказской з управления транспортного компьютеров
"
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.02.2014, 19:31
Ответы с готовыми решениями:

Получить новый файл, в котором все слова во всех предложениях исходного файла, записаны в обратном порядке
1)На языке программирования Pascal реализовать процедуры работы со стеком на последовательном распределении памяти: - Создание пустого...

Напечатать все элементы файла, в котором записаны отдельные слова
Напечатать все элементы файла, в котором записаны отдельные слова. Известно, что в существующем файле записаны 12 слов.

Слова в обратном порядке в предложениях
Здравствуйте! Есть задачка, поменять слова в предложениях в обратном порядке при минимальном коде, пока что накидал нечто:...

39
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
01.03.2014, 18:03  [ТС]
Студворк — интернет-сервис помощи студентам
Ругается на 206 строку: "Data := #10#13; {Перевёрнутый перенос строки.}"

Пишет "неверное выражение"
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
01.03.2014, 20:30
Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
Ругается на 206 строку: "Data := #10#13; {Перевёрнутый перенос строки.}"
Пишет "неверное выражение"
Я проверял в Borland/Turbo pascal 7.0 - там компилируется без ошибок. Да и ещё, если та строчка на 206-й строке - значит это первый код. В нём нет ограничения глубины стека. С ограничением длины стека - это второй код. И во втором коде глубина стека сейчас выставлена = 100. Надо поменять на 10, согласно заданию:
Pascal
3
4
const
  aStackMaxSize = 10; {Наибольшая глубина стека.}
Добавлено через 1 минуту
Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
Пишет "неверное выражение"
Эту строку можно поменять на:
Pascal
206
  Data := #10 + #13; {Перевёрнутый перенос строки.}
0
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
01.03.2014, 20:46  [ТС]
поменял 100 на 10, получилось вообще непонятное..
Вложения
Тип файла: txt file_out.txt (806 байт, 2 просмотров)
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
01.03.2014, 21:03
Здесь что-то непонятное, в самом деле. У меня программа совершенно другое выдаёт...
Для начала предлагаю сверить коды. Надо взять второй код вот из этого сообщения.
Вот этот код. С тем отличаем, что здесь я уже поменял глубину стека на 10:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
program Project1;
 
const
  aStackMaxSize = 10; {Наибольшая глубина стека.}
 
type
  {Основные данные элемента стека.}
  TData = String;
  {Указатель на элемент стека.}
  TPElem = ^TElem;
  {Элемент стека.}
  TElem = record
    Data : TData;   {Основные данные.}
    PNext : TPElem; {Указатель на следующий элемент стека.}
  end;
  {Тип, описывающий стек.}
  TStack = record
    PTop : TPElem; {Указатель на вершину стека.}
    Cnt : Integer; {Количество элементов в стеке.}
  end;
 
{Стек.}
 
{Инициализация стека. Эту процедуру можно выполнять только в отношении пустого
стека. Иначе будут утечки памяти.}
procedure Init(var aSt : TStack);
begin
  aSt.PTop := nil;
  aSt.Cnt := 0;
end;
 
{Добавление элемента на вершину стека.
aData - основные данные: слово или междусловие.
Если глубина стека меньше наибольшей допустимой, то новый элемент добавляется
в стек. В этом случае функция возвращает значение True. Если глубина стека
равна наибольшей допустимой, то операция отменяется и функция возвращает
значение False.}
function Push(var aSt : TStack; const aData : TData) : Boolean;
var
  PElem : TPElem;
begin
  Push := False;
  if aSt.Cnt < aStackMaxSize then
  begin
    New(PElem); {Выделение памяти для нового элемента.}
    PElem^.Data := aData; {Записываем основные данные.}
    {Прикрепляем к новому элементу первый элемент стека. Таким образом, новый
    элемент оказывается на вершине стека.}
    PElem^.PNext := aSt.PTop;
    {В переменную стека записываем указатель на вершину стека - т. е., на новый элемент.}
    aSt.PTop := PElem;
    Inc(aSt.Cnt); {Отмечаем, что количество элементов в стеке увеличилось на 1.}
    Push := True;
  end;
end;
 
{Изъятие элемента с вершины стека.
Если стек не пуст, то с вершины стека изымается элемент и его значение
(основные данные) возвращается через параметр aData. В этом случае функция
возвращает значение True. Если стек пуст, то операция отменяется и функция
возвращает значение False.}
function Pop(var aSt : TStack; var aData : TData) : Boolean;
var
  PElem : TPElem;
begin
  Pop := False;
  if aSt.PTop <> nil then
  begin
    PElem := aSt.PTop; {Получаем указатель на тот элемент, который находится на вершине стека.}
    aData := PElem^.Data; {Читаем основные данные элемента.}
    {Указатель стека теперь будет указывать на второй элемент. Таким образом,
    второй элемент теперь оказывается на вершине стека.}
    aSt.PTop := PElem^.PNext;
    Dispose(PElem); {Освобождаем память, занятую под элемент, который раньше был на вершине стека.}
    Dec(aSt.Cnt); {Отмечаем, что количество элементов в стеке уменьшилось на 1.}
    Pop := True;
  end;
end;
 
{Освобождение памяти, занятой для стека (очистка стека).}
procedure StFree(var aSt : TStack);
var
  Data : TData;
begin
  while Pop(aSt, Data) do;
end;
 
{Прикладные процедуры.}
 
{Запись содержимого стека в файл.}
procedure StWrite(var aF : Text; var aStW, aStBw : TStack; const aIsWord : Boolean);
var
  St1, St2 : TStack;
  Data : TData;
  Ch : Char;
  i, Len : Integer;
  IsData1, IsData2 : Boolean;
begin
  {Переливаем междусловия в стек St1 и выполняем переворачивания.}
  Init(St1);
  while Pop(aStBw, Data) do {Берём междусловие из стека междусловий.}
  begin
    {Переворачиваем междусловие.}
    Len := Length(Data);
    for i := 1 to Len div 2 do
    begin
      Ch := Data[i];
      Data[i] := Data[Len - i + 1];
      Data[Len - i + 1] := Ch;
    end;
    Push(St1, Data); {Записываем междусловие в стек St1.}
  end;
  {Переливаем междусловия обратно - в стек междусловий.}
  while Pop(St1, Data) do
    Push(aStBw, Data);
 
  {Выбираем очерёдность стеков.}
  if aIsWord then
  begin
    St1 := aStW;
    St2 := aStBw;
  end
  else
  begin
    St1 := aStBw;
    St2 := aStW;
  end;
 
  {Извлекаем из стеков слова и междусловия и записываем их в выходной файл.}
  repeat
    IsData1 := Pop(St1, Data);
    if IsData1 then
      Write(aF, Data);
    IsData2 := Pop(St2, Data);
    if IsData2 then
      Write(aF, Data);
  until not (IsData1 or IsData2);
  {Теперь стеки пусты, выполняем инициализацию представляющих их параметров.}
  Init(aStW);
  Init(aStBw);
end;
 
const
  {Имена входного и выходного файлов.}
  FnIn = 'file_in.txt';
  FnOut = 'file_out.txt';
  {Разделители слов.}
  Dw = ['.', ',', ':', ';', '!', '?', '-', '"', ' ', #9, #10, #13];
  {Разделители предложений.}
  Doff = ['.', '!', '?'];
var
  FIn, FOut : Text;
  StW, StBw : TStack; {Стек слов и стек междусловий.}
  Data, DataTmp : TData;
  S : String;
  {Len - длина строки, LenW - длина слова, LenBw - длина междусловия.}
  i, Len, LenW, LenBw : Integer;
  {IsWord = True - последний записанный в стек элемент является словом,
    False - последний записанный в стек элемент является междусловием.
  IsDataW = True - слово успешно добавлено в стек слов. Иначе - False.
  IsDataBw = True - междусловие успешно добавлено в стек междусловий. Иначе - False.}
  IsWord, IsDataW, IsDataBw : Boolean;
begin
  {Начальная инициализация стеков.}
  Init(StW);
  Init(StBw);
  {Связываем файловые переменные с именами файлов.}
  Assign(FIn, FnIn);
  Assign(FOut, FnOut);
 
  repeat
    Writeln('Входной файл: ', FnIn);
    Writeln('Выходной файл: ', FnOut);
    Writeln('Выполнить обработку - д, Д, y, Y. Любой другой символ - выход.');
    Readln(S);
    if (S = '') or not (S[1] in ['д', 'Д', 'y', 'Y']) then
      Break;
 
    {Открываем файлы.}
    Reset(FIn);
    Rewrite(FOut);
    {Обработка файла.}
    IsWord := True;
    IsDataW := True;
    IsDataBw := True;
    while not Eof(FIn) do
    begin
      {Читаем очередную строку из файла (без перехода на следующую сроку).}
      Read(FIn, S);
      Len := Length(S);
      {Обработка строки.}
      LenW := 0;
      LenBw := 0;
      for i := 1 to Len do
      begin
        {Обработка междусловий.}
        {Если символ является разделителем, значит он принадлежит междусловию.}
        if S[i] in Dw then
        begin
          Inc(LenBw); {Учитываем очередной символ в длине междусловия.}
          {Отслеживаем конец междусловия.}
          if (S[i] in Doff) or ((i = Len) or not (S[i + 1] in Dw)) then
          begin
            if IsDataBw then
            begin
              Data := Copy(S, i - LenBw + 1, LenBw); {Берём из строки междусловие.}
              {Если предыдущий элемент строки являлся междусловием, то выполняем склейку.}
              if not IsWord and Pop(StBw, DataTmp) then
                Data := DataTmp + Data;
              IsDataBw := Push(StBw, Data); {Добавление междусловия в стек.}
              if IsDataBw then
                IsWord := False; {Флаг: последний добавленный элемент - междусловие.}
            end;
            LenBw := 0; {Сброс длины междусловия.}
          end;
        end
        {Обработка слов.}
        {Если символ НЕ является разделителем, значит он принадлежит слову.}
        else
        begin
          Inc(LenW); {Учитываем очередной символ в длине слова.}
          {Отслеживаем конец слова.}
          if (i = Len) or (S[i + 1] in Dw) then
          begin
            if IsDataW then
            begin
              IsDataW := Push(StW, Copy(S, i - LenW + 1, LenW)); {Добавление слова в стек.}
              if IsDataBw then
                IsWord := True; {Флаг: последний добавленный элемент - слово.}
            end;
            LenW := 0; {Сброс длины слова.}
          end;
        end;
        {Обработка предложений.}
        {Если обнаружен конец предложения.}
        if (S[i] in Doff) or ((i = Len) and Eof(FIn)) then
        begin
          StWrite(FOut, StW, StBw, IsWord); {Запись содержимого стека в файл.}
          IsDataW := True;
          IsDataBw := True;
        end;
      end;
      {Обработка переносов строк.}
      if Eoln(FIn) and not Eof(FIn) then
      begin
        {Если в стеке междусловий есть свободное место, то добавляем в него
        перевёрнутый перенос строки.}
        if IsDataBw then
        begin
          Data := #10#13; {Перевёрнутый перенос строки.}
          {Если предыдущий элемент строки являлся междусловием, то выполняем склейку.}
          if not IsWord and Pop(StBw, DataTmp) then
            Data := DataTmp + Data;
          IsDataBw := Push(StBw, Data); {Добавление междусловия в стек.}
          if IsDataBw then
            IsWord := False; {Флаг: последний добавленный элемент - междусловие.}
        end;
        Readln(FIn); {Переходим к следующей строке во входном файле.}
      end;
    end;
    {Записываем в файл то, что осталось в стеке.}
    StWrite(FOut, StW, StBw, IsWord);
 
    {Закрываем файлы.}
    Close(FIn);
    Close(FOut);
    {Освобождение памяти, занятой для стеков.}
    StFree(StW);
    StFree(StBw);
    Writeln('Обработка завершена.');
    Writeln('Память, выделенная для стеков, освобождена.');
 
    Writeln('Повторить - Enter. Выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
Вот этот код выдаёт следующий результат:
Исходный текст:
Кликните здесь для просмотра всего текста
- Притормози, - говорю я, когда мы минуем манговые заросли и проезжаем мимо вполне среднерусской чащобы.
- У следующей тропинки.
- До квартала "Аль-Кабар" еще далеко, - говорит водитель.
- Останови.
Машина останавливается. Я открываю дверь, отхожу от лимузина на шаг.
Водитель покорно ждет. И я тоже - просвет на дороге. Зачем нам свидетели?
Вот, наконец-то...
Я целюсь в машину, стреляю. Револьвер бьет негромко, отдача слабая,
но машина мгновенно вспыхивает. Водитель сидит, глядя перед собой.
Несколько секунд - и у "Дип-проводника" становится одним такси меньше.
Хорошо. Пусть все выглядит, как развлечение пьяной шпаны. Я иду в
лес.
- Неэтично... - бормочет из булавок "Виндоус-Хоум".
- Ты оптимизировалась?
- Да.
- Все, теперь мне нужна помощь. Ищи тайник, код "Иван".
- Светящееся дерево, - сообщает программа.
Я озираюсь. Ага. Вот он, огромный дуб, мерцающий колдовским синим
светом. Мерцающий лишь для меня. Я подхожу к нему, засовываю руку в дупло,
вынимаю большой тяжелый сверток. Переодеваюсь в полотняную белую рубаху и
штаны, подпоясываюсь узорчатым поясом. Короткий меч в ножнах, несколько
вещичек в карманах. Тайник я создал пару дней назад, незаконно использовав
один из компьютеров транспортного управления з кавказской железной дороги.

Текст в выходном файле, сформированный программой:
Кликните здесь для просмотра всего текста
проезжаем и заросли манговые минуем мы когда ,я говорю - ,Притормози -.тропинки следующей У -
.водитель говорит - ,далеко еще "Кабар-Аль" квартала До -
.Останови -
.останавливается Машина
.шаг на лимузина от отхожу ,дверь открываю Я .ждет покорно Водитель
.дороге на просвет - тоже я И ?свидетели нам Зачем .то-наконец ,Вот
...стреляю ,машину в целюсь Я
.вспыхивает мгновенно машина но
,слабая отдача ,негромко бьет Револьвер .собой перед глядя ,сидит Водитель меньше такси одним становится "проводника-Дип" у и - секунд Несколько
.Хорошо
.шпаны пьяной развлечение как ,выглядит все Пусть .лес
в иду Я .Неэтично -
..."Хоум-Виндоус" булавок из бормочет - ?оптимизировалась Ты -
.Да -
.помощь нужна мне теперь ,Все -
."Иван" код ,тайник Ищи .программа сообщает - ,дерево Светящееся -
.озираюсь Я
.Ага .светом
синим колдовским мерцающий ,дуб огромный ,он Вот .меня для лишь Мерцающий большой вынимаю
,дупло в руку засовываю ,нему к подхожу Я поясом узорчатым подпоясываюсь ,штаны
и рубаху белую полотняную в Переодеваюсь .карманах в вещичек
несколько ,ножнах в меч Короткий из один
использовав незаконно ,назад дней пару создал я Тайник
0
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
01.03.2014, 21:09  [ТС]
несколько ,ножнах в меч Короткий из один
использовав незаконно ,назад дней пару создал я Тайник
вот тут ведь неправильно.. часть остального предложение как-бы "съедается"
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
01.03.2014, 21:13
Так это правильно, что съедается. Ведь мы глубину стека поставили равной 10. Соответственно, в стеке помещается только 10 слов. Именно это мы и видим. Например, в последнем предложении осталось именно 10 слов (помечены красным цветом):
несколько ,ножнах в меч Короткий из один
использовав незаконно ,назад дней пару создал я Тайник
0
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
02.03.2014, 15:36  [ТС]
Так а по заданию не должно "съедаться".. Должен текст и дальше идти. Ты уже так писал выше.
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
02.03.2014, 16:55
Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
Так а по заданию не должно "съедаться".. Должен текст и дальше идти.
В задании размер стека специально ограничили значением 10 - чтобы было видно, что происходит, когда размер стека недостаточный. Поэтому всё так и должно быть - при глубине стека = 10, в предложениях, содержащих более 10 слов, должны теряться слова с номерами 11, 12 и т. д.
Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
Ты уже так писал выше.
Там, где стек по глубине не ограничен или, где ограничение = 100 - вот там слова не теряются. При глубине = 10, слова с номерами 11, 12, ... - потеряются, потому что они в стеке просто не помещаются. Как я выше уже говорил - это специально сделано, чтобы было наглядное представление ситуации, когда глубина стека недостаточная.

Возможно, в заблуждение вводит часть фразы, где говорится о том, что порядок должны поменять "все" слова:
Запрограммировать получение нового текстового файла, в котором все слова во всех предложениях записаны в обратном порядке.
Это вовсе не означает, что все слова предложения запишутся в выходной файл. В выходной файл запишутся только те слова предложения, которые поместились в стек.

Так что всё нормально. Если всё-же остаются какие-то сомнения, то можно у преподавателя уточнить эти вопросы.
0
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
02.03.2014, 21:02  [ТС]
Я уже спрашивал у преподавателя. Он сказал, что каким-то способом(желательно используя 2 стека) слова записать в обратном порядке да так, чтобы все слова остались.
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
02.03.2014, 21:25
Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
Он сказал, что каким-то способом(желательно используя 2 стека) слова записать в обратном порядке да так, чтобы все слова остались.
А, ну тогда понятно, что требуется в задаче. Здесь имеется в виду следующее. Что новые предложения надо будет составлять по частям. Т. е., читаем слова из предложения, складываем их в первый стек. Как только первый стек заполнился, извлекаем из него слова и составляем из них часть нового предложения. Эту часть кладём во второй стек. Потом читаем дальше слова, опять складываем их в первый стек и затем формируем следующую часть предложения и тоже кладём её во второй стек. Когда чтение исходного предложения завершится, читаем части из второго стека и склеиваем из них новое предложение, в котором слова будут следовать в обратном порядке относительно исходного. Это новое предложение записываем в выходной файл.
Вот так, значит надо действовать.
0
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
02.03.2014, 21:58  [ТС]
Да. Именно так
Можете помочь написать?
Мне во вторник сдавать уже
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
03.03.2014, 11:02
Лучший ответ Сообщение было отмечено CrazyDrummer13 как решение

Решение

Завтра сделаем. Ко вторнику будет готово.

---
Готово. Уже сегодня.

Решение с двумя стеками. В один стек (StW) записываются слова и предложения, в другой стек (StP) записываются части предложений.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
program Project1;
 
const
  aStackMaxSize = 10; {Наибольшая глубина стека.}
 
type
  {Основные данные элемента стека.}
  TData = String;
  {Указатель на элемент стека.}
  TPElem = ^TElem;
  {Элемент стека.}
  TElem = record
    Data : TData;   {Основные данные.}
    PNext : TPElem; {Указатель на следующий элемент стека.}
  end;
  {Тип, описывающий стек.}
  TStack = record
    PTop : TPElem; {Указатель на вершину стека.}
    Cnt : Integer; {Количество элементов в стеке.}
  end;
 
{Стек.}
 
{Инициализация стека. Эту процедуру можно выполнять только в отношении пустого
стека. Иначе будут утечки памяти.}
procedure Init(var aSt : TStack);
begin
  aSt.PTop := nil;
  aSt.Cnt := 0;
end;
 
{Добавление элемента на вершину стека.
aData - основные данные: слово или междусловие.
Если глубина стека меньше наибольшей допустимой, то новый элемент добавляется
в стек. В этом случае функция возвращает значение True. Если глубина стека
равна наибольшей допустимой, то операция отменяется и функция возвращает
значение False.}
function Push(var aSt : TStack; const aData : TData) : Boolean;
var
  PElem : TPElem;
begin
  Push := False;
  if aSt.Cnt < aStackMaxSize then
  begin
    New(PElem); {Выделение памяти для нового элемента.}
    PElem^.Data := aData; {Записываем основные данные.}
    {Прикрепляем к новому элементу первый элемент стека. Таким образом, новый
    элемент оказывается на вершине стека.}
    PElem^.PNext := aSt.PTop;
    {В переменную стека записываем указатель на вершину стека - т. е., на новый элемент.}
    aSt.PTop := PElem;
    Inc(aSt.Cnt); {Отмечаем, что количество элементов в стеке увеличилось на 1.}
    Push := True;
  end;
end;
 
{Изъятие элемента с вершины стека.
Если стек не пуст, то с вершины стека изымается элемент и его значение
(основные данные) возвращается через параметр aData. В этом случае функция
возвращает значение True. Если стек пуст, то операция отменяется и функция
возвращает значение False.}
function Pop(var aSt : TStack; var aData : TData) : Boolean;
var
  PElem : TPElem;
begin
  Pop := False;
  if aSt.PTop <> nil then
  begin
    PElem := aSt.PTop; {Получаем указатель на тот элемент, который находится на вершине стека.}
    aData := PElem^.Data; {Читаем основные данные элемента.}
    {Указатель стека теперь будет указывать на второй элемент. Таким образом,
    второй элемент теперь оказывается на вершине стека.}
    aSt.PTop := PElem^.PNext;
    Dispose(PElem); {Освобождаем память, занятую под элемент, который раньше был на вершине стека.}
    Dec(aSt.Cnt); {Отмечаем, что количество элементов в стеке уменьшилось на 1.}
    Pop := True;
  end;
end;
 
{Освобождение памяти, занятой для стека (очистка стека).}
procedure StFree(var aSt : TStack);
var
  Data : TData;
begin
  while Pop(aSt, Data) do;
end;
 
{Прикладные процедуры.}
 
{Функция формирует из содержимого стека aStW часть предложения и записывает
его в стек aStP.}
function PushPart(var aStP, aStW : TStack; const aIsWord : Boolean) : Boolean;
var
  S, Data : TData;
  Ch : Char;
  i, Len : Integer;
  IsWord : Boolean;
begin
  {Извлекаем из стека aStW слова и междусловия и формируем из них часть предложения.}
  S := '';
  IsWord := aIsWord;
  while Pop(aStW, Data) do
  begin
    if not IsWord then {Если элемент является междусловием.}
    begin
      {Переворачиваем междусловие.}
      Len := Length(Data);
      for i := 1 to Len div 2 do
      begin
        Ch := Data[i];
        Data[i] := Data[Len - i + 1];
        Data[Len - i + 1] := Ch;
      end;
    end;
    S := S + Data;
    IsWord := not IsWord;
  end;
  {Записываем часть предложения в стек aStP.}
  PushPart := True;
  if S <> '' then
    PushPart := Push(aStP, S);
end;
 
{Добавление слова или междусловия в стек.}
procedure PushE(var aStP, aStW : TStack; aData : TData; const aIsWordPred, aIsWord : Boolean);
var
  DataTmp : TData;
begin
  {Если текущий и предыдущий элементы являлся междусловиями, то выполняем склейку.}
  if not aIsWord and not aIsWordPred and Pop(aStW, DataTmp) then
      aData := DataTmp + aData;
  {Добавляем в стек элемент (слово или междусловие.}
  if not Push(aStW, aData) then {Если в стеке aStW нет свободного места, то...}
  begin
    PushPart(aStP, aStW, aIsWordPred); {Формируем часть предложения и записываем эту часть в стек aStP.}
    Push(aStW, aData); {Повторная попытка записи элемента в стек.}
  end;
end;
 
const
  {Имена входного и выходного файлов.}
  FnIn = 'file_in.txt';
  FnOut = 'file_out.txt';
  {Разделители слов.}
  Dw = ['.', ',', ':', ';', '!', '?', '-', '"', ' ', #9, #10, #13];
  {Разделители предложений.}
  Doff = ['.', '!', '?'];
var
  FIn, FOut : Text;
  StW, StP : TStack; {Стек слов и междусловий и стек частей предложения.}
  Data : TData;
  S : String;
  {Len - длина строки, LenW - длина слова, LenBw - длина междусловия.}
  i, Len, LenW, LenBw : Integer;
  {IsWord =
  True - последний записанный в стек элемент является словом,
  False - последний записанный в стек элемент является междусловием.}
  IsWord : Boolean;
begin
  {Начальная инициализация стеков.}
  Init(StW);
  Init(StP);
  {Связываем файловые переменные с именами файлов.}
  Assign(FIn, FnIn);
  Assign(FOut, FnOut);
 
  repeat
    Writeln('Входной файл: ', FnIn);
    Writeln('Выходной файл: ', FnOut);
    Writeln('Выполнить обработку - д, Д, y, Y. Любой другой символ - выход.');
    Readln(S);
    if (S = '') or not (S[1] in ['д', 'Д', 'y', 'Y']) then
      Break;
 
    {Открываем файлы.}
    Reset(FIn);
    Rewrite(FOut);
    {Обработка файла.}
    IsWord := True;
    while not Eof(FIn) do
    begin
      {Читаем очередную строку из файла (без перехода на следующую сроку).}
      Read(FIn, S);
      Len := Length(S);
      {Обработка строки.}
      LenW := 0;
      LenBw := 0;
      for i := 1 to Len do
      begin
        {Обработка междусловий.}
        {Если символ является разделителем, значит он принадлежит междусловию.}
        if S[i] in Dw then
        begin
          Inc(LenBw); {Учитываем очередной символ в длине междусловия.}
          {Отслеживаем конец междусловия.}
          if (S[i] in Doff) or ((i = Len) or not (S[i + 1] in Dw)) then
          begin
            PushE(StP, StW, Copy(S, i - LenBw + 1, LenBw), IsWord, False); {Добавление междусловия в стек.}
            IsWord := False; {Флаг: последний добавленный элемент - междусловие.}
            LenBw := 0; {Сброс длины междусловия.}
          end;
        end
        {Обработка слов.}
        {Если символ НЕ является разделителем, значит он принадлежит слову.}
        else
        begin
          Inc(LenW); {Учитываем очередной символ в длине слова.}
          {Отслеживаем конец слова.}
          if (i = Len) or (S[i + 1] in Dw) then
          begin
            PushE(StP, StW, Copy(S, i - LenW + 1, LenW), IsWord, True); {Добавление слова в стек.}
            IsWord := True; {Флаг: последний добавленный элемент - слово.}
            LenW := 0; {Сброс длины слова.}
          end;
        end;
        {Обработка предложений.}
        {Если обнаружен конец предложения.}
        if (S[i] in Doff) or ((i = Len) and Eof(FIn)) then
        begin
          {Запись содержимого стека в файл.}
          PushPart(StP, StW, IsWord);
          while Pop(StP, Data) do
            Write(FOut, Data);
        end;
      end;
      {Обработка переносов строк.}
      if Eoln(FIn) and not Eof(FIn) then
      begin
        PushE(StP, StW, #10#13, IsWord, False); {Добавляем в стек перевёрнутый перенос строки.}
        IsWord := False; {Флаг: последний добавленный элемент - междусловие.}
        Readln(FIn); {Переходим к следующей строке во входном файле.}
      end;
    end;
    {Записываем в файл то, что осталось в стеке.}
    PushPart(StP, StW, IsWord);
    while Pop(StP, Data) do
      Write(FOut, Data);
 
    {Закрываем файлы.}
    Close(FIn);
    Close(FOut);
    {Освобождение памяти, занятой для стеков.}
    StFree(StW);
    StFree(StP);
    Writeln('Обработка завершена.');
    Writeln('Память, выделенная для стеков, освобождена.');
 
    Writeln('Повторить - Enter. Выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
Пример обработки.
Текст во входном файле:
Кликните здесь для просмотра всего текста
- Притормози, - говорю я, когда мы минуем манговые заросли и проезжаем мимо вполне среднерусской чащобы.
- У следующей тропинки.
- До квартала "Аль-Кабар" еще далеко, - говорит водитель.
- Останови.
Машина останавливается. Я открываю дверь, отхожу от лимузина на шаг.
Водитель покорно ждет. И я тоже - просвет на дороге. Зачем нам свидетели?
Вот, наконец-то...
Я целюсь в машину, стреляю. Револьвер бьет негромко, отдача слабая,
но машина мгновенно вспыхивает. Водитель сидит, глядя перед собой.
Несколько секунд - и у "Дип-проводника" становится одним такси меньше.
Хорошо. Пусть все выглядит, как развлечение пьяной шпаны. Я иду в
лес.
- Неэтично... - бормочет из булавок "Виндоус-Хоум".
- Ты оптимизировалась?
- Да.
- Все, теперь мне нужна помощь. Ищи тайник, код "Иван".
- Светящееся дерево, - сообщает программа.
Я озираюсь. Ага. Вот он, огромный дуб, мерцающий колдовским синим
светом. Мерцающий лишь для меня. Я подхожу к нему, засовываю руку в дупло,
вынимаю большой тяжелый сверток. Переодеваюсь в полотняную белую рубаху и
штаны, подпоясываюсь узорчатым поясом. Короткий меч в ножнах, несколько
вещичек в карманах. Тайник я создал пару дней назад, незаконно использовав
один из компьютеров транспортного управления з кавказской железной дороги.

Текст в выходном файле:
Кликните здесь для просмотра всего текста
.чащобы среднерусской вполне мимо проезжаем и заросли манговые минуем мы когда ,я говорю - ,Притормози -.тропинки следующей У -
.водитель говорит - ,далеко еще "Кабар-Аль" квартала До -
.Останови -
.останавливается Машина
.шаг на лимузина от отхожу ,дверь открываю Я .ждет покорно Водитель
.дороге на просвет - тоже я И ?свидетели нам Зачем .то-наконец ,Вот
...стреляю ,машину в целюсь Я
.вспыхивает мгновенно машина но
,слабая отдача ,негромко бьет Револьвер .собой перед глядя ,сидит Водитель .меньше такси одним становится "проводника-Дип" у и - секунд Несколько
.Хорошо
.шпаны пьяной развлечение как ,выглядит все Пусть .лес
в иду Я .Неэтично -
..."Хоум-Виндоус" булавок из бормочет - ?оптимизировалась Ты -
.Да -
.помощь нужна мне теперь ,Все -
."Иван" код ,тайник Ищи .программа сообщает - ,дерево Светящееся -
.озираюсь Я
.Ага .светом
синим колдовским мерцающий ,дуб огромный ,он Вот .меня для лишь Мерцающий .сверток тяжелый большой вынимаю
,дупло в руку засовываю ,нему к подхожу Я .поясом узорчатым подпоясываюсь ,штаны
и рубаху белую полотняную в Переодеваюсь .карманах в вещичек
несколько ,ножнах в меч Короткий .дороги железной кавказской з управления транспортного компьютеров из один
использовав незаконно ,назад дней пару создал я Тайник


Добавлено через 9 часов 35 минут
Обновил код. Добавление в стек слов и междусловий оформил в виде процедуры.

Добавлено через 1 час 47 минут
Подправил комментарии.
1
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
03.03.2014, 19:31  [ТС]
ДА!!! Это оно!! Именно оно))
Спасибо большое
Завтра буду сдавать и сразу же отпишусь как прошло

Добавлено через 10 минут
Блиииин... там ещё одно задание.. с этим же текстом нужно запрограммировать получение нового текстового файла, в котором в котором буквы каждого слова записаны в обратном порядке. В программе нужно установить максимальный размер стека равным 5.

Добавлено через 7 минут
Можешь хоть вкратце объяснить свой алгоритм получения такого текста?
Мне защищать надо будет эту лабу, я хоть и комментарии прочитал, но всё равно многое непонятно.. Я вообще не так делал и представлял

Добавлено через 20 минут
И ещё.. Где ты обрабатываешь переполнение?
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
03.03.2014, 20:55
Лучший ответ Сообщение было отмечено Kodzaev как решение

Решение

Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
там ещё одно задание.. с этим же текстом нужно запрограммировать получение нового текстового файла, в котором в котором буквы каждого слова записаны в обратном порядке.
Только слова надо перевернуть? Или надо этим заданием дополнить то, что у нас уже сделано? - Т. е., перевернуть последовательность слов предложения и при этом сами слова записать в перевёрнутом виде? В этом случае понадобится изменить только одну функцию PushPart(). Раньше она переворачивала только междусловия, а теперь надо переворачивать всё - и междусловия и слова. Вот так её надо переписать:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{Функция формирует из содержимого стека aStW часть предложения и записывает
его в стек aStP.}
function PushPart(var aStP, aStW : TStack) : Boolean;
var
  S, Data : TData;
  Ch : Char;
  i, Len : Integer;
begin
  {Извлекаем из стека aStW слова и междусловия и формируем из них часть предложения.}
  S := '';
  while Pop(aStW, Data) do
  begin
    {Переворачиваем текст элемента.}
    Len := Length(Data);
    for i := 1 to Len div 2 do
    begin
      Ch := Data[i];
      Data[i] := Data[Len - i + 1];
      Data[Len - i + 1] := Ch;
    end;
    S := S + Data;
  end;
  {Записываем часть предложения в стек aStP.}
  PushPart := True;
  if S <> '' then
    PushPart := Push(aStP, S);
end;
Полностью код получится таким:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
program Project1;
 
const
  aStackMaxSize = 10; {Наибольшая глубина стека.}
 
type
  {Основные данные элемента стека.}
  TData = String;
  {Указатель на элемент стека.}
  TPElem = ^TElem;
  {Элемент стека.}
  TElem = record
    Data : TData;   {Основные данные.}
    PNext : TPElem; {Указатель на следующий элемент стека.}
  end;
  {Тип, описывающий стек.}
  TStack = record
    PTop : TPElem; {Указатель на вершину стека.}
    Cnt : Integer; {Количество элементов в стеке.}
  end;
 
{Стек.}
 
{Инициализация стека. Эту процедуру можно выполнять только в отношении пустого
стека. Иначе будут утечки памяти.}
procedure Init(var aSt : TStack);
begin
  aSt.PTop := nil;
  aSt.Cnt := 0;
end;
 
{Добавление элемента на вершину стека.
aData - основные данные: слово или междусловие.
Если глубина стека меньше наибольшей допустимой, то новый элемент добавляется
в стек. В этом случае функция возвращает значение True. Если глубина стека
равна наибольшей допустимой, то операция отменяется и функция возвращает
значение False.}
function Push(var aSt : TStack; const aData : TData) : Boolean;
var
  PElem : TPElem;
begin
  Push := False;
  if aSt.Cnt < aStackMaxSize then
  begin
    New(PElem); {Выделение памяти для нового элемента.}
    PElem^.Data := aData; {Записываем основные данные.}
    {Прикрепляем к новому элементу первый элемент стека. Таким образом, новый
    элемент оказывается на вершине стека.}
    PElem^.PNext := aSt.PTop;
    {В переменную стека записываем указатель на вершину стека - т. е., на новый элемент.}
    aSt.PTop := PElem;
    Inc(aSt.Cnt); {Отмечаем, что количество элементов в стеке увеличилось на 1.}
    Push := True;
  end;
end;
 
{Изъятие элемента с вершины стека.
Если стек не пуст, то с вершины стека изымается элемент и его значение
(основные данные) возвращается через параметр aData. В этом случае функция
возвращает значение True. Если стек пуст, то операция отменяется и функция
возвращает значение False.}
function Pop(var aSt : TStack; var aData : TData) : Boolean;
var
  PElem : TPElem;
begin
  Pop := False;
  if aSt.PTop <> nil then
  begin
    PElem := aSt.PTop; {Получаем указатель на тот элемент, который находится на вершине стека.}
    aData := PElem^.Data; {Читаем основные данные элемента.}
    {Указатель стека теперь будет указывать на второй элемент. Таким образом,
    второй элемент теперь оказывается на вершине стека.}
    aSt.PTop := PElem^.PNext;
    Dispose(PElem); {Освобождаем память, занятую под элемент, который раньше был на вершине стека.}
    Dec(aSt.Cnt); {Отмечаем, что количество элементов в стеке уменьшилось на 1.}
    Pop := True;
  end;
end;
 
{Освобождение памяти, занятой для стека (очистка стека).}
procedure StFree(var aSt : TStack);
var
  Data : TData;
begin
  while Pop(aSt, Data) do;
end;
 
{Прикладные процедуры.}
 
{Функция формирует из содержимого стека aStW часть предложения и записывает
его в стек aStP.}
function PushPart(var aStP, aStW : TStack) : Boolean;
var
  S, Data : TData;
  Ch : Char;
  i, Len : Integer;
begin
  {Извлекаем из стека aStW слова и междусловия и формируем из них часть предложения.}
  S := '';
  while Pop(aStW, Data) do
  begin
    {Переворачиваем текст элемента.}
    Len := Length(Data);
    for i := 1 to Len div 2 do
    begin
      Ch := Data[i];
      Data[i] := Data[Len - i + 1];
      Data[Len - i + 1] := Ch;
    end;
    S := S + Data;
  end;
  {Записываем часть предложения в стек aStP.}
  PushPart := True;
  if S <> '' then
    PushPart := Push(aStP, S);
end;
 
{Добавление слова или междусловия в стек.}
procedure PushE(var aStP, aStW : TStack; aData : TData; const aIsWordPred, aIsWord : Boolean);
var
  DataTmp : TData;
begin
  {Если текущий и предыдущий элементы являлся междусловиями, то выполняем склейку.}
  if not aIsWord and not aIsWordPred and Pop(aStW, DataTmp) then
      aData := DataTmp + aData;
  {Добавляем в стек элемент (слово или междусловие.}
  if not Push(aStW, aData) then {Если в стеке aStW нет свободного места, то...}
  begin
    PushPart(aStP, aStW); {Формируем часть предложения и записываем эту часть в стек aStP.}
    Push(aStW, aData); {Повторная попытка записи междусловия в стек.}
  end;
end;
 
const
  {Имена входного и выходного файлов.}
  FnIn = 'file_in.txt';
  FnOut = 'file_out.txt';
  {Разделители слов.}
  Dw = ['.', ',', ':', ';', '!', '?', '-', '"', ' ', #9, #10, #13];
  {Разделители предложений.}
  Doff = ['.', '!', '?'];
var
  FIn, FOut : Text;
  StW, StP : TStack; {Стек слов и междусловий и стек частей предложения.}
  Data : TData;
  S : String;
  {Len - длина строки, LenW - длина слова, LenBw - длина междусловия.}
  i, Len, LenW, LenBw : Integer;
  {IsWord =
  True - последний записанный в стек элемент является словом,
  False - последний записанный в стек элемент является междусловием.}
  IsWord : Boolean;
begin
  {Начальная инициализация стеков.}
  Init(StW);
  Init(StP);
  {Связываем файловые переменные с именами файлов.}
  Assign(FIn, FnIn);
  Assign(FOut, FnOut);
 
  repeat
    Writeln('Входной файл: ', FnIn);
    Writeln('Выходной файл: ', FnOut);
    Writeln('Выполнить обработку - д, Д, y, Y. Любой другой символ - выход.');
    Readln(S);
    if (S = '') or not (S[1] in ['д', 'Д', 'y', 'Y']) then
      Break;
 
    {Открываем файлы.}
    Reset(FIn);
    Rewrite(FOut);
    {Обработка файла.}
    IsWord := True;
    while not Eof(FIn) do
    begin
      {Читаем очередную строку из файла (без перехода на следующую сроку).}
      Read(FIn, S);
      Len := Length(S);
      {Обработка строки.}
      LenW := 0;
      LenBw := 0;
      for i := 1 to Len do
      begin
        {Обработка междусловий.}
        {Если символ является разделителем, значит он принадлежит междусловию.}
        if S[i] in Dw then
        begin
          Inc(LenBw); {Учитываем очередной символ в длине междусловия.}
          {Отслеживаем конец междусловия.}
          if (S[i] in Doff) or ((i = Len) or not (S[i + 1] in Dw)) then
          begin
            PushE(StP, StW, Copy(S, i - LenBw + 1, LenBw), IsWord, False); {Добавление междусловия в стек.}
            IsWord := False; {Флаг: последний добавленный элемент - междусловие.}
            LenBw := 0; {Сброс длины междусловия.}
          end;
        end
        {Обработка слов.}
        {Если символ НЕ является разделителем, значит он принадлежит слову.}
        else
        begin
          Inc(LenW); {Учитываем очередной символ в длине слова.}
          {Отслеживаем конец слова.}
          if (i = Len) or (S[i + 1] in Dw) then
          begin
            PushE(StP, StW, Copy(S, i - LenW + 1, LenW), IsWord, True); {Добавление слова в стек.}
            IsWord := True; {Флаг: последний добавленный элемент - слово.}
            LenW := 0; {Сброс длины слова.}
          end;
        end;
        {Обработка предложений.}
        {Если обнаружен конец предложения.}
        if (S[i] in Doff) or ((i = Len) and Eof(FIn)) then
        begin
          {Запись содержимого стека в файл.}
          PushPart(StP, StW);
          while Pop(StP, Data) do
            Write(FOut, Data);
        end;
      end;
      {Обработка переносов строк.}
      if Eoln(FIn) and not Eof(FIn) then
      begin
        PushE(StP, StW, #10#13, IsWord, False); {Добавляем в стек перевёрнутый перенос строки.}
        IsWord := False; {Флаг: последний добавленный элемент - междусловие.}
        Readln(FIn); {Переходим к следующей строке во входном файле.}
      end;
    end;
    {Записываем в файл то, что осталось в стеке.}
    PushPart(StP, StW);
    while Pop(StP, Data) do
      Write(FOut, Data);
 
    {Закрываем файлы.}
    Close(FIn);
    Close(FOut);
    {Освобождение памяти, занятой для стеков.}
    StFree(StW);
    StFree(StP);
    Writeln('Обработка завершена.');
    Writeln('Память, выделенная для стеков, освобождена.');
 
    Writeln('Повторить - Enter. Выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
Результат обработки.
Текст во входном файле:
Кликните здесь для просмотра всего текста
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- Притормози, - говорю я, когда мы минуем манговые заросли и проезжаем мимо вполне среднерусской чащобы.
- У следующей тропинки.
- До квартала "Аль-Кабар" еще далеко, - говорит водитель.
- Останови.
Машина останавливается. Я открываю дверь, отхожу от лимузина на шаг.
Водитель покорно ждет. И я тоже - просвет на дороге. Зачем нам свидетели?
Вот, наконец-то...
Я целюсь в машину, стреляю. Револьвер бьет негромко, отдача слабая,
но машина мгновенно вспыхивает. Водитель сидит, глядя перед собой.
Несколько секунд - и у "Дип-проводника" становится одним такси меньше.
Хорошо. Пусть все выглядит, как развлечение пьяной шпаны. Я иду в
лес.
- Неэтично... - бормочет из булавок "Виндоус-Хоум".
- Ты оптимизировалась?
- Да.
- Все, теперь мне нужна помощь. Ищи тайник, код "Иван".
- Светящееся дерево, - сообщает программа.
Я озираюсь. Ага. Вот он, огромный дуб, мерцающий колдовским синим
светом. Мерцающий лишь для меня. Я подхожу к нему, засовываю руку в дупло,
вынимаю большой тяжелый сверток. Переодеваюсь в полотняную белую рубаху и
штаны, подпоясываюсь узорчатым поясом. Короткий меч в ножнах, несколько
вещичек в карманах. Тайник я создал пару дней назад, незаконно использовав
один из компьютеров транспортного управления з кавказской железной дороги.

Текст, сформированный программой в выходном файле:
Кликните здесь для просмотра всего текста
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.ыбощач йокссурендерс енлопв омим меажзеорп и илсораз еывогнам меуним ым адгок ,я юровог - ,и*****тирП -.икнипорт йещюуделс У -
.ьлетидов тировог - ,окелад еще "рабаК-ьлА" алатравк оД -
.ивонатсО -
.ястеавилванатсо анишаМ
.гаш ан анизумил то ужохто ,ьревд юавыркто Я .тедж онрокоп ьлетидоВ
.егород ан тевсорп - ежот я И ?илетедивс ман мечаЗ .от-ценокан ,тоВ
...юялертс ,унишам в ьсюлец Я
.теавихыпсв онневонгм анишам он
,яабалс ачадто ,окморген теьб ревьловеР .йобос дереп ядялг ,тидис ьлетидоВ .ешьнем искат миндо ястивонатс "акиндоворп-пиД" у и - днукес окьлоксеН
.ошороХ
.ынапш йоняьп еинечелвзар как ,тидялгыв есв ьтсуП .сел
в уди Я .ончитэеН -
..."муоХ-суодниВ" ковалуб зи течомроб - ?ьсалаворизимитпо ыТ -
.аД -
.ьщомоп анжун енм ьрепет ,есВ -
."навИ" док ,кинйат ищИ .аммаргорп теащбоос - ,оверед ясеещятевС -
.ьсюаризо Я
.агА .мотевс
минис миксводлок йищюацрем ,буд йынморго ,но тоВ .янем ялд ьшил йищюацреМ .котревс йылежят йошьлоб юаминыв
,олпуд в укур юавывосаз ,умен к ужохдоп Я .мосяоп мытачрозу ьсюавысяопдоп ,ынатш
и ухабур юулеб юунянтолоп в ьсюаведоереП .ханамрак в кечищев
окьлоксен ,ханжон в чем йиктороК .игород йонзележ йоксзаквак з яинелварпу огонтропснарт воретюьпмок зи нидо
вавозьлопси онноказен ,дазан йенд урап ладзос я кинйаТ

Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
И ещё.. Где ты обрабатываешь переполнение?
Обрабатывается переполнение того стека, в который мы записываем слова и междусловия - это стек StW. Переполнение обрабатывается в процедуре PushE():
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{Добавление слова или междусловия в стек.}
procedure PushE(var aStP, aStW : TStack; aData : TData; const aIsWordPred, aIsWord : Boolean);
var
  DataTmp : TData;
begin
  {Если текущий и предыдущий элементы являлся междусловиями, то выполняем склейку.}
  if not aIsWord and not aIsWordPred and Pop(aStW, DataTmp) then
      aData := DataTmp + aData;
  {Добавляем в стек элемент (слово или междусловие.}
  if not Push(aStW, aData) then {Если в стеке aStW нет свободного места, то...}
  begin
    PushPart(aStP, aStW); {Формируем часть предложения и записываем эту часть в стек aStP.}
    Push(aStW, aData); {Повторная попытка записи междусловия в стек.}
  end;
end;
Конкретно обработка переполнения вот в этом коде:
Pascal
1
2
3
4
5
6
  {Добавляем в стек элемент (слово или междусловие.}
  if not Push(aStW, aData) then {Если в стеке aStW нет свободного места, то...}
  begin
    PushPart(aStP, aStW); {Формируем часть предложения и записываем эту часть в стек aStP.}
    Push(aStW, aData); {Повторная попытка записи междусловия в стек.}
  end;
Здесь, если в стеке нет места, т. е., если возниколо переполнение:
Pascal
1
if not Push(aStW, aData) then {Если в стеке aStW нет свободного места, то...}
то выполняется следующий код:
Pascal
1
2
PushPart(aStP, aStW); {Формируем часть предложения и записываем эту часть в стек aStP.}
Push(aStW, aData); {Повторная попытка записи междусловия в стек.}
Здесь делается следующее. Если возникло переполнение стека StW, то мы вызваем процедуру PushPart(aStP, aStW). Эта процедура извлекает из стека StW все записанные в него слова и междусловия, составляет из них часть нового предложения и эту часть записывает в стек StP. После этого у нас стек StW оказывается очищенным и мы добавляем в него элемент, который раньше у нас не удалось добавить из-за переполнения:
Pascal
1
Push(aStW, aData); {Повторная попытка записи междусловия в стек.}
Добавлено через 6 минут
Цитата Сообщение от CrazyDrummer13 Посмотреть сообщение
Можешь хоть вкратце объяснить свой алгоритм получения такого текста?
Смысл алгоритма в следующем. У нас есть 2 стека - StW и StP. В стек StW мы записываем слова и междусловия. Как только стек StW переполняется или как только мы встретили конец предложения, мы делаем следующее. Извлекаем из стека StW все слова и междусловия и составляем из них кусок нового предложения, в котором слова и междусловия следуют в обратном порядке относительно исходного предложения. Этот кусок (часть предложения или полное предложение) мы записываем в стек StP. Как только встречается конец предложения или конец файла, мы извлекаем куски предложения из стека StP и склеиваем из них полное предложение. И это полученное предложение записываем в выходной файл.
1
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
03.03.2014, 21:20  [ТС]
Спасибо большое.. Буду готовиться, разбираться, завтра отпишусь с результатами
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
03.03.2014, 21:30
Вот как будет выглядеть обработка.
Исходное предложение:
Code
1
Слово1,слово2,слово3,слово4,слово5,слово6,слово7.
Мы начинаем просматривать это предложение. Извлекаем из него слова и междусловия и складываем из в стек StW. Когда в стеке StW возникнет переполнение, то вот что будет внутри этого стека:
Code
1
2
3
4
5
6
7
8
9
10
,
слово5
,
слово4
,
слово3
,
слово2
,
Слово1
Раз возникло переполнение, то мы вызываем процедуру PushPart(). Эта процедура сделает следующее:
1. Извлечёт из стека StW все слова и междусловия и склеит их в порядке извлечения из стека StW. При этом междусловия ещё и запишет задом наперёд. Но здесь все междусловия состоят из одного символа, поэтому это они останутся такими же, как в исходном предложении. Получится следующий текст:
Code
1
,слово5,слово4,слово3,слово2,Слово1
Этот кусок предложения будет записан в стек StP. Затем программ продолжит обрабатывать текст дальше. До конца предложения у нас остаётся следующая часть:
Code
1
слово6,слово7.
Программа будет дальше извлекать слова и междусловия и будет складывать их в стек StW. Когда встретится конец предложения (в данном случае - это символ ".") в стеке StW будет следующее:
Code
1
2
3
4
.
слово7
,
слово6
При обнаружении конца предложения опять будет вызвана процедура PushPart(). Она извлечёт последовательно слова и междусловия из стека StW, склеит из них следующий кусок предложения:
Code
1
.слово7,слово6
И этот кусок запишет в стек StP. Теперь в стеке StP у нас будет следующее:
Code
1
2
.слово7,слово6
,слово5,слово4,слово3,слово2,Слово1
И так как программа обнаружила конец предложения, то из стека StP будут извлечены содержащиеся в нём части и они будут склеены в новое предложение:
Code
1
.слово7,слово6,слово5,слово4,слово3,слово2,Слово1
Это предложение будет записано в выходной файл.
1
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
03.03.2014, 21:35  [ТС]
Теперь стало совсем понятно. Спасибо!
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
03.03.2014, 21:43
Ещё про вызовы функций. Схема такая. Если мы выделили из предложения слово или междусловие, то мы вызываем процедуру PushE(). Эта процедура пытается добавить это слово или междусловие в стек StW. Если оказывается, что при этом произошло переполнение стека StW, то внутри процедуры PushE() вызывается функция PushPart(). PushPart() извлекает из стека StW слова и междусловия и склеивает из них часть нового предложения. Эта полученная часть записывается в стек StP. После этого в стек StW записывается то слово или междусловие, которое не удалось записать во время переполнения стека StW. И т. д. это продолжается до момента, когда программа обнаружит конец предложения.
При обнаружении конца предложения опять будет вызвана процедура PushPart(); - чтобы сформировать последнюю часть предложения и записать её в стек StP. И затем из стека StP будут извлечены все собранные части предложения и из них будет склеено полное предложение. И это предложение будет записано в выходной файл.
1
3 / 3 / 1
Регистрация: 07.11.2013
Сообщений: 49
05.03.2014, 17:58  [ТС]
Всё!!! Я сдал!! Единственный со всего потока смог защитить и сдать
Спасибо вам, если бы не вы, не знаю, сколько ещё мучался бы я)
1
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
05.03.2014, 19:17
Хорошо! Поздравляю!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.03.2014, 19:17
Помогаю со студенческими работами здесь

Сформировать второй массив, в котором элементы записаны в обратном порядке
помогите сформулировать второй массив, в котором элементы записаны в обратном порядке соответственно элементов первого массива. Вот...

Используя стек, распечатать слова из текстового файла в обратном порядке
помогите решить задачу. используя стек распечатать слова в текстовом файле в обратном порядке. заранее спасибо !!:(

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

Вывести слова каждого предложения текстового файла на экран в обратном порядке
Помогите пожалуйста Задание: Написать программу, выводящую слова каждого предложения текстового файла на экран в обратном порядке, т.е....

Имеется типизированный файл, в котором записаны 18 целых чисел. Переписать все положительные числа файла в массив в том же порядке
program viweglavnoidiagonaali; var f:file of integer; i,bi,k,d,z,z1,a,b,x,y:integer; begin writeln('x '); for I:=1 to 2 do begin...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 01.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 31.01.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru