0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
1

Список слов распечатать в алфавитном порядке. В Turbo Pascal или Pascal ABC

23.02.2013, 01:18. Показов 5301. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Дана непустая последовательность слов, в каждом из которых содержится от 1 до 6 заглавных латинских букв; соседние слова разделены запятой, за последним словом следует точка. В качестве внутреннего представления последовательности слов использовать массив из 6 списков, в котором хранятся 5-буквенные слова, упорядоченные по алфавиту.
Требуется ввести эту последовательность слов в память ЭВМ, преобразовав ее во внутреннее представление, а затем распечатать в алфавитном порядке: сначала все однобуквенные слова, затем все двубуквенные и т.д.
В программе должны быть определены процедура выделения очередного слова из исходной последовательности и процедура вставки слова в упорядоченный список. Вводить последовательность слов следует посимвольно. Следует упорядочивать списки одновременно с вводом слов: введенное слово следует сразу вставлять в "свое" место в ранее упорядоченный список. Для упрощения рекомендуется использовать списки с заглавными звеньями. В этом случае следует в начале выполнения программы построить список(списки) с одним заглавным звеном. В звеньях списков(вершинах) следует хранить не только слова, но и дополнительную информацию(порядковый номер слова в исходной последовательности или число его вхождений в эту последовательность). Для каждого слова лучше иметь только одно звено, фиксируя в нем число вхождений этого слова в последовательность; при печати же надо продублировать слово данное число раз.

Я понимаю, что условий много))) но без всех этих условий у меня не примут работу. Лично от меня условие написать по возможности комментарии, чтобы мне самой понять ее))))
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.02.2013, 01:18
Ответы с готовыми решениями:

Turbo Pascal, Pascal ABC, Free Pascal, PascalABC.NET - в чем разница?
Всем привет, решил изучать Паскаль, но на форуме увидел 4 его версии - Turbo Pascal, Pascal ABC,...

Нужно перевести код из Turbo Pascal в Pascal ABC.NET
Доброго времени суток. На форуме находил похожие темы, но к сожалению так и не смог разобраться....

Различия трансляторов Pascal ABC.Net и Turbo/Borland Pascal
Пожалуйста, объясните различия между компиляторами Pascal ABC.Net и Turbo/Borland Pascal

Нужно перевести программу с Turbo Pascal в Pascal ABC.NET
Вот есть программный код , но он для турбо паскаля, помогите перевести его в АБС.NET Program...

20
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
23.02.2013, 22:02 2
Лучший ответ Сообщение было отмечено как решение

Решение

Здесь заглавный элемент в списках я не стал использовать - в этом нет особого смысла.
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
program Project1;
 
uses
  Crt;
 
type
  {Тип основных данных списка.}
  TData = record
    S : String; {Слово.}
    Cnt : Integer; {Счётчик - сколько раз слово S присутствует в тексте.}
  end;
  {Тип указателя на элемент списка.}
  TPElem = ^TElem;
  {Тип элемента списка.}
  TElem = record
    Data : TData; {Основные данные элемента.}
    PNext : TPElem; {Указатель на следующий элемент списка.}
  end;
 
{Добавление элемента в однонаправленный упорядоченный список.
Список упорядочен по возрастанию (т. е. по алфавиту в соответствие
с действующей кодировочной таблицей.}
procedure Add(var aPList : TPElem; const aStr : String);
var
  PNew, PPrev, PCur : TPElem;
begin
  {Указатель на предыдущий элемент.}
  PPrev := nil;
  {Указатель на текущий элемент.}
  PCur := aPList;
  {Ищем позицию для вставки нового элемента. Новый элемент вставляется
  между элементами PPrev и PCur.}
  while (PCur <> nil) and (PCur^.Data.S < aStr) do begin
    {Переходим к следующему элементу.}
    PPrev := PCur;
    PCur := PCur^.PNext;
  end;
  {Вставка элемента в список.}
  {Вставка элемента в конец списка. В этом случае PPrev является указателем
  на последний элемент списка.}
  if PCur = nil then begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := nil;
    {Если список пуст, то новый элемент становится единственным
    элементом списка.}
    if PPrev = nil then
      aPlist := PNew
    {Если список непустой, то новый элемент добавляем после последнего
    элемента списка.}
    else
      PPrev^.PNext := PNew;
  {Найдено такое же слово. В этом случае вместо вставки выполняем
  увеличение счётчика по этому слову.}
  end else if PCur^.Data.S = aStr then
    Inc(PCur^.Data.Cnt)
  {Вставка вначале или внутри списка. В этом случае мы должны вставить новый
  элемент между элементами PPrev и PCur}
  else begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := PCur;
    if PPrev = nil then {Если вставка в начало списка.}
      aPList := PNew
    else                {Если вставка внутри списка.}
      PPrev^.PNext := PNew;
  end;
end;
 
{Освобождение памяти, занятой под список и инициализация списка.}
procedure Free(var aPList : TPElem);
var
  PDel : TPElem;
begin
  while aPList <> nil do begin
    PDel := aPList;
    aPList := aPList^.PNext;
    Dispose(PDel);
  end;
end;
 
{Распечатка однонаправленного списка.}
procedure WritelnList(const aPList : TPElem);
var
  PElem : TPElem;
  i, j : Integer;
begin
  if aPList = nil then begin
    Writeln('Список пуст.');
    Exit;
  end;
 
  PElem := aPList;
  i := 0;
  while PElem <> nil do begin
    {Распечатываем текущее слово PElem^.Data.Cnt раз.}
    for j := 1 to PElem^.Data.Cnt do begin
      Inc(i); {Счётчик распечатанных слов.}
      if i > 1 then Write(', ');
      Write(PElem^.Data.S);
    end;
    PElem := PElem^.PNext;
  end;
  Writeln;
end;
 
{Выделение слова из входной последовательности.
Функция работает так. Если введён символ отличный от разделителя, то
этот символ добавляется к строке aStr и распечатывается на экране.
После этого выполняется чтение следующего символа с консоли ввода.
Если введён разделитель, то он обрабатывается, затем функция завершает
работу и возвращает в качестве своего значения этот разделитель.
Через параметр aStr функция возвращает слово - непрерывную последовательность
символов, отличных от разделителей.}
function GetWord(var aStr : String) : Char;
const
  {Множество разделителей слов.}
  D = ['.', ',', ':', ';', '!', '?', '-', ' ', #0, #8, #9, #10, #13, #27];
var
  Ch : Char;
begin
  aStr := '';
  repeat
    Ch := Readkey;
    if not (Ch in D) then begin
      aStr := aStr + Ch;
      Write(Ch);
    end else if Ch = #13 then
      Writeln
    else if Ch = #0 then
      Readkey
    else if not (Ch in [#8, #27]) then
      Write(Ch);
  until Ch in D;
  GetWord := Ch;
end;
 
const
  M = 6;
var
  Arr : array[1..M] of TPElem;
  Ch : Char;
  i : Integer;
  S : String;
begin
  {Начальная инициализация массива.}
  for i := 1 to M do Arr[i] := nil;
 
  repeat
    {Обработка текста, выделение слов, создание списков.}
    Writeln('Задайте текст. Обработаны будут только те слова, которые состоят');
    Writeln('не более, чем из ', M, ' букв. Прекратить ввод - ESC.');
    repeat
      Ch := GetWord(S);
      i := Length(S);
      case i of
        1..M: Add(Arr[i], S);
      end;
    until Ch = #27;
    Writeln;
 
    {Распечатка результатов.}
    Writeln('Результаты:');
    for i := 1 to M do begin
      Writeln('Слова с длиной ', i, ':');
      WritelnList(Arr[i]);
    end;
    Writeln;
 
    {Освобождение памяти, занятой под списки.}
    for i := 1 to M do Free(Arr[i]);
    Writeln('Память, занятая под списки, освобождена.');
 
    Writeln('Повторить - Enter, выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
3
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
23.02.2013, 22:25  [ТС] 3
Mawrat, спасибооо большоее))) оперативно))) а остальные условия учтены?
0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
23.02.2013, 23:02 4
Пожалуйста.
Цитата Сообщение от ST2502 Посмотреть сообщение
а остальные условия учтены?
Да, учтены. По порядку:
Цитата Сообщение от ST2502 Посмотреть сообщение
В качестве внутреннего представления последовательности слов использовать массив из 6 списков, в котором хранятся 5-буквенные слова, упорядоченные по алфавиту.
Это сделано. Только формулировка здесь неверная. Правильно: "... в котором хранятся слова с длинами от 1 до 6, соответственно в списках: Arr[1]..Arr[6]. В каждом списке слова упорядочены по алфавиту."
И ещё уточню - слова хранятся почти по алфавиту. - Согласно кодировочной таблице. Если работа и идёт в Borland/Turbo Pascal, то действует кодировочная таблица CP866.
Цитата Сообщение от ST2502 Посмотреть сообщение
Требуется ввести эту последовательность слов в память ЭВМ, преобразовав ее во внутреннее представление, а затем распечатать в алфавитном порядке: сначала все однобуквенные слова, затем все двубуквенные и т.д.
Сделано.
Цитата Сообщение от ST2502 Посмотреть сообщение
В программе должны быть определены процедура выделения очередного слова из исходной последовательности и процедура вставки слова в упорядоченный список.
Сделано.
Цитата Сообщение от ST2502 Посмотреть сообщение
Вводить последовательность слов следует посимвольно.
Это тоже реализовано - применена функция Readkey().
Цитата Сообщение от ST2502 Посмотреть сообщение
Следует упорядочивать списки одновременно с вводом слов: введенное слово следует сразу вставлять в "свое" место в ранее упорядоченный список.
Сделано.
Цитата Сообщение от ST2502 Посмотреть сообщение
Для упрощения рекомендуется использовать списки с заглавными звеньями. В этом случае следует в начале выполнения программы построить список(списки) с одним заглавным звеном.
Заглавное звено я не стал делать.
Цитата Сообщение от ST2502 Посмотреть сообщение
В звеньях списков(вершинах) следует хранить не только слова, но и дополнительную информацию(порядковый номер слова в исходной последовательности или число его вхождений в эту последовательность). Для каждого слова лучше иметь только одно звено, фиксируя в нем число вхождений этого слова в последовательность;
Сделано.
Цитата Сообщение от ST2502 Посмотреть сообщение
при печати же надо продублировать слово данное число раз.
И это тоже сделано.

Добавлено через 6 минут
Сейчас ещё проверю...

Добавлено через 1 минуту
Есть проблемы. Сейчас подправлю...

Добавлено через 17 минут
Исправил. Исправленный код в том же сообщении, выше..

Добавлено через 28 секунд
Проверяй.
2
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
23.02.2013, 23:02  [ТС] 5
Mawrat, *______* боже, что я бы делала без вас))) еще раз огромное спасибооо)))
0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
23.02.2013, 23:07 6
Если в программе что-то непонятно - спрашивай. Расскажу. Вообще, что касается списков, желательно рисовать элементы и их связи на бумаге - так легче разобраться, что происходит при действиях со списком.
2
HighPredator
23.02.2013, 23:08
  #7

Не по теме:

Цитата Сообщение от ST2502 Посмотреть сообщение
что я бы делала без вас)
Сидели бы без работы.

0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
23.02.2013, 23:14 8
Цитата Сообщение от ST2502 Посмотреть сообщение
Mawrat, *______* боже, что я бы делала без вас))) еще раз огромное спасибооо)))
Цитата Сообщение от HighPredator Посмотреть сообщение
Сидели бы без работы.
На самом деле, может выпасть ещё одно испытание - если работодатель попросит дать разъяснения по действиям в программе. Поэтому в коде надо постараться разобраться.
0
6044 / 2159 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
23.02.2013, 23:15 9
Цитата Сообщение от Mawrat Посмотреть сообщение
На самом деле, может выпасть ещё одно испытание - если работодатель попросит дать разъяснения по действиям программы. Поэтому в коде надо постараться разобраться.
Тоже верно.
2
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
23.02.2013, 23:23  [ТС] 10
Цитата Сообщение от HighPredator Посмотреть сообщение

Не по теме:


Сидели бы без работы.

не сидела бы)))
Цитата Сообщение от Mawrat Посмотреть сообщение
На самом деле, может выпасть ещё одно испытание - если работодатель попросит дать разъяснения по действиям в программе. Поэтому в коде надо постараться разобраться.
он попросит)) разберусь, вроде все понятно)))
0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
23.02.2013, 23:45 11
ST2502, например, может быть такой вопрос: в функции GetWord() пояснить назначение строк:
Pascal
1
2
3
4
5
6
    end else if Ch = #13 then
      Writeln
    else if Ch = #0 then
      Readkey
    else if Ch <> #8 then
      Write(Ch);
Ответ.
Если введён символ с кодом #13 - то это перевод каретки. Т. е., переход на новую строку. Поэтому мы выполняем вызов Writeln.
Если спросят - а почему бы в этом случае не написать так: Write(Ch) или так: Write(#13)?
Ответ: потому что на самом деле перевод каретки состоит из двух знаков: #13#10 - переход на новую строку и конец строки. Поэтому вместо Writeln можно написать так: Write(#13#10).
Теперь что касается знака #0. Если пользователь нажмёт какую-нибудь функциональную клавишу F1, F2 и т. д., то в этом случае Readkey() вернёт код #0. А при следующем вызове Readkey() вернёт скан-код нажатой клавиши. Поэтому в программе, если вызов Readkey() вернул #0, то значит произошло нажатие функциональной клавиши. В этом случае мы ещё раз вызываем Readkey(), чтобы прочитать скан-код клавиши. Далее этот скан код мы никак не используем, т. к., он нам не нужен.
Знак #8 - это нажатие клавиши BackSpace.

Добавлено через 19 минут
И ещё немного подправил - чтобы символ #27 (ESC) не распечатывался на экране.
Т. е., заменил:
Pascal
1
2
    else if Ch <> #8 then
      Write(Ch);
на:
Pascal
1
2
    else if not (Ch in [#8, #27]) then
      Write(Ch);
Полностью:
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
{Выделение слова из входной последовательности.
Функция работает так. Если введён символ отличный от разделителя, то
этот символ добавляется к строке aStr и распечатывается на экране.
После этого выполняется чтение следующего символа с консоли ввода.
Если введён разделитель, то он обрабатывается, затем функция завершает
работу и возвращает в качестве своего значения этот разделитель.
Через параметр aStr функция возвращает слово - непрерывную последовательность
символов, отличных от разделителей.}
function GetWord(var aStr : String) : Char;
const
  {Множество разделителей слов.}
  D = ['.', ',', ':', ';', '!', '?', '-', ' ', #0, #8, #9, #10, #13, #27];
var
  Ch : Char;
begin
  aStr := '';
  repeat
    Ch := Readkey;
    if not (Ch in D) then begin
      aStr := aStr + Ch;
      Write(Ch);
    end else if Ch = #13 then
      Writeln
    else if Ch = #0 then
      Readkey
    else if not (Ch in [#8, #27]) then
      Write(Ch);
  until Ch in D;
  GetWord := Ch;
end;
И ещё добавил Writeln перед распечаткой результатов.
Исправленный код в прежнем сообщении.
2
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
24.02.2013, 12:19  [ТС] 12
Mawrat, а можно функцию GetWord без этих символов( #0, #8, #9, #10, #13, #27)? так как я не мастер в проге и препод догадается, что я не сама это сделала)))) + "прекратить ввод - esc" можно его заменить просто enter? "Память занятая под списки освобождена" для чего это было сделано? обязателен ли он? "повторить - enter" это тоже не понадобится думаю)) также он читает любые слова менее 6 букв, например, "f f f", "qw//", "а**", "wer**/", хотя он должен читать только слова с латинскими буквами без других символов. можете исправить?))
0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
24.02.2013, 12:46 13
Цитата Сообщение от ST2502 Посмотреть сообщение
а можно функцию GetWord без этих символов( #0, #8, #9, #10, #13, #27)?
Ну в общем, если пользователь обязуется не нажимать функциональные клавиши (F1, F2, и др.), то можно убрать код #0. Код #8 - это клавиша BackSpace - пользователь может попытаться стереть какие-нибудь символы. Поэтому эту клавишу желательно перехватывать. Код #10 можно убрать. #13 - это Enter. А #27 - это ESC.
Цитата Сообщение от ST2502 Посмотреть сообщение
"прекратить ввод - esc" можно его заменить просто enter?
Да, можно и по Enter завершение ввода сделать.
Цитата Сообщение от ST2502 Посмотреть сообщение
"Память занятая под списки освобождена" для чего это было сделано? обязателен ли он?
Раз мы память выделили, то её надо позже освободить. Т. е., раз мы у системы (или у менеджера памяти) взяли память, то потом её надо возвратить. Иначе будут утечки памяти. Т. е. память будет помечена, как используемая в программе, хотя программа к ней уже не будет иметь доступа. Таким образом эту память не сможет использовать менеджер памяти и соответственно, она не будет отдана системе. Ещё такие участки памяти называют "мёртвыми".
Вообще, когда проверяется код программы, где идёт работа с динамической памятью, первое что делается, смотрят - ага есть вызов New(), теперь смотрим - есть ли вызов Dispose()? Нет Dispose() - всё, это уже серьёзный недочёт. Чаще всего, убедившись в отсутствии Dispose(), проверка сразу же и заканчивается.
Цитата Сообщение от ST2502 Посмотреть сообщение
он читает любые слова менее 6 букв, например, "f f f", "qw//", "а**", "wer**/", хотя он должен читать только слова с латинскими буквами без других символов.
Да сейчас "буквами" считаются любые символы, отличные от разделителей. Можно изменить код таким образом, чтобы только буквы латиницы учитывались.
---
В общем я сейчас подправлю. И выложу здесь код чуть позже.
1
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
24.02.2013, 13:06  [ТС] 14
Цитата Сообщение от Mawrat Посмотреть сообщение
Ну в общем, если пользователь обязуется не нажимать функциональные клавиши (F1, F2, и др.), то можно убрать код #0.
обязуюсь))
Цитата Сообщение от Mawrat Посмотреть сообщение
Код #8 - это клавиша BackSpace - пользователь может попытаться стереть какие-нибудь символы. Поэтому эту клавишу желательно перехватывать.
наоборот, мне легче было бы если при неправильном вводе смогла стереть ненужное)))
0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
24.02.2013, 13:45 15
Цитата Сообщение от ST2502 Посмотреть сообщение
наоборот, мне легче было бы если при неправильном вводе смогла стереть ненужное)))
Тогда понадобится поменять алгоритм ввода. И здесь уже надо будет уточнить тогда. У нас есть два условия:
Цитата Сообщение от ST2502 Посмотреть сообщение
Вводить последовательность слов следует посимвольно.
Цитата Сообщение от ST2502 Посмотреть сообщение
В программе должны быть определены процедура выделения очередного слова из исходной последовательности
У нас сейчас есть функция GetWord(), которая извлекает слова из посимвольного ввода с консоли. И таким образом у нас выполняются оба условия - у нас есть процедура, которая обеспечивает посимвольный ввод и извлечение слов.
Сейчас у пользователя нет возможности редактирования текста, который он вводит. Если мы такую возможность предоставим, то нам понадобится отслеживать изменения, сделанные пользователем. Это сделать можно - мы должны будем хранить всё введённые символы в буфере - в символьном массиве. Если пользователь нажмёт BackSpace (#8), то мы уменьшим значимую длину буфера на 1 - тем самым, удалим последний символ. В течение всего времени ввода текста мы не должны извлекать слова, потому что нам не известно окончательное состояние текста (ведь пользователь может часть слов стереть). Только когда пользователь завершит ввод (нажмёт Enter (#13), например) - вот тогда мы начнём извлекать слова из буфера.
Устроит такой вариант?

Добавлено через 2 минуты
Клавиши стрелок запретим - потому что логика с их участием усложнится.
0
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
24.02.2013, 15:19  [ТС] 16
Mawrat, окей) не будем тогда усложнять пусть останется как есть)))
0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
24.02.2013, 16:03 17
Ну я сейчас тогда два варианта программы выложу. Без буфера и с буфером. И можно будет выбрать.
1
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
24.02.2013, 16:21  [ТС] 18
ок
0
13100 / 5881 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
24.02.2013, 16:48 19
В программе с буфером ввод всё-таки не очень красивым получился. При нажатии BackSpace предыдущие символы не стираются на экране, а только перемещается влево курсор. Но на самом деле они стираются - в буфере. И если опять начать вводить символы, то новые символы будут на экране затирать старые. В общем, визуально это как-то не очень... Плюс к этому, если на экране началась новая строка, то при нажатии BackSpace курсор на предыдущую строку не возвращается. Хотя при обычном вводе тоже так - на предыдущую строку курсор не возвращается.
Но тем не менее программу с буфером тоже выложил - под номером 2.
---
1. Без буфера, с завершением ввода по нажатию ENTER:
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
program Project1;
 
uses
  Crt;
 
type
  {Тип основных данных списка.}
  TData = record
    S : String; {Слово.}
    Cnt : Integer; {Счётчик - сколько раз слово S присутствует в тексте.}
  end;
  {Тип указателя на элемент списка.}
  TPElem = ^TElem;
  {Тип элемента списка.}
  TElem = record
    Data : TData; {Основные данные элемента.}
    PNext : TPElem; {Указатель на следующий элемент списка.}
  end;
 
{Добавление элемента в однонаправленный упорядоченный список.
Список упорядочен по возрастанию (т. е. по алфавиту в соответствие
с действующей кодировочной таблицей.}
procedure Add(var aPList : TPElem; const aStr : String);
var
  PNew, PPrev, PCur : TPElem;
begin
  {Указатель на предыдущий элемент.}
  PPrev := nil;
  {Указатель на текущий элемент.}
  PCur := aPList;
  {Ищем позицию для вставки нового элемента. Новый элемент вставляется
  между элементами PPrev и PCur.}
  while (PCur <> nil) and (PCur^.Data.S < aStr) do begin
    {Переходим к следующему элементу.}
    PPrev := PCur;
    PCur := PCur^.PNext;
  end;
  {Вставка элемента в список.}
  {Вставка элемента в конец списка. В этом случае PPrev является указателем
  на последний элемент списка.}
  if PCur = nil then begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := nil;
    {Если список пуст, то новый элемент становится единственным
    элементом списка.}
    if PPrev = nil then
      aPlist := PNew
    {Если список непустой, то новый элемент добавляем после последнего
    элемента списка.}
    else
      PPrev^.PNext := PNew;
  {Найдено такое же слово. В этом случае вместо вставки выполняем
  увеличение счётчика по этому слову.}
  end else if PCur^.Data.S = aStr then
    Inc(PCur^.Data.Cnt)
  {Вставка вначале или внутри списка. В этом случае мы должны вставить новый
  элемент между элементами PPrev и PCur}
  else begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := PCur;
    if PPrev = nil then {Если вставка в начало списка.}
      aPList := PNew
    else                {Если вставка внутри списка.}
      PPrev^.PNext := PNew;
  end;
end;
 
{Освобождение памяти, занятой под список и инициализация списка.}
procedure Free(var aPList : TPElem);
var
  PDel : TPElem;
begin
  while aPList <> nil do begin
    PDel := aPList;
    aPList := aPList^.PNext;
    Dispose(PDel);
  end;
end;
 
{Распечатка однонаправленного списка.}
procedure WritelnList(const aPList : TPElem);
var
  PElem : TPElem;
  i, j : Integer;
begin
  if aPList = nil then begin
    Writeln('Список пуст.');
    Exit;
  end;
 
  PElem := aPList;
  i := 0;
  while PElem <> nil do begin
    {Распечатываем текущее слово PElem^.Data.Cnt раз.}
    for j := 1 to PElem^.Data.Cnt do begin
      Inc(i); {Счётчик распечатанных слов.}
      if i > 1 then Write(', ');
      Write(PElem^.Data.S);
    end;
    PElem := PElem^.PNext;
  end;
  Writeln;
end;
 
{Выделение слова из входной последовательности.
Функция работает так. Если введён символ из множества Da, то этот символ
добавляется к строке aStr и распечатывается на экране. После этого выполняется
чтение следующего символа с консоли ввода. Если введён символ,
не принадлежащий множеству Da, то он дополнительно обрабатывается, если
требуется. Затем функция завершает работу и возвращает в качестве своего
значения этот символ.
Через параметр aStr функция возвращает слово - непрерывную последовательность
символов, принадлежащих множеству Da.}
function GetWord(var aStr : String) : Char;
const
  {Множество букв латиницы.}
  Da = ['A'..'Z', 'a'..'z'];
var
  Ch : Char;
  F : Boolean;
begin
  aStr := '';
  repeat
    Ch := Readkey;
    F := True; {Завершить цикл чтения с консоли.}
    if Ch in Da then begin
      aStr := aStr + Ch;
      Write(Ch);
      F := False; {Продолжить цикл чтения с консоли.}
    end else if Ch in [#8, #27] then
      F := False  {Продолжить цикл чтения с консоли.}
    else if Ch in [#0] then begin
      Readkey;
      F := False; {Продолжить цикл чтения с консоли.}
    end else if Ch = #13 then
      Writeln
    else
      Write(Ch);
  until F;
  GetWord := Ch;
end;
 
const
  M = 6;
var
  Arr : array[1..M] of TPElem;
  Ch : Char;
  i : Integer;
  S : String;
begin
  {Начальная инициализация массива.}
  for i := 1 to M do Arr[i] := nil;
 
  repeat
    {Обработка текста, выделение слов, создание списков.}
    Writeln('Задайте текст. Обработаны будут только те слова, которые состоят');
    Writeln('не более, чем из ', M, ' букв. Прекратить ввод - ESC.');
    repeat
      Ch := GetWord(S);
      i := Length(S);
      case i of
        1..M: Add(Arr[i], S);
      end;
    until Ch = #13;
    Writeln;
 
    {Распечатка результатов.}
    Writeln('Результаты:');
    for i := 1 to M do begin
      Writeln('Слова с длиной ', i, ':');
      WritelnList(Arr[i]);
    end;
    Writeln;
 
    {Освобождение памяти, занятой под списки.}
    for i := 1 to M do Free(Arr[i]);
    Writeln('Память, занятая под списки, освобождена.');
 
    Writeln('Повторить - Enter, выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
2. С буфером. Завершение ввода по нажатию ENTER. BackSpace работает, но визуально символы не стираются.
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
program Project1;
 
uses
  Crt;
 
type
  {Тип основных данных списка.}
  TData = record
    S : String; {Слово.}
    Cnt : Integer; {Счётчик - сколько раз слово S присутствует в тексте.}
  end;
  {Тип указателя на элемент списка.}
  TPElem = ^TElem;
  {Тип элемента списка.}
  TElem = record
    Data : TData; {Основные данные элемента.}
    PNext : TPElem; {Указатель на следующий элемент списка.}
  end;
 
{Добавление элемента в однонаправленный упорядоченный список.
Список упорядочен по возрастанию (т. е. по алфавиту в соответствие
с действующей кодировочной таблицей.}
procedure Add(var aPList : TPElem; const aStr : String);
var
  PNew, PPrev, PCur : TPElem;
begin
  {Указатель на предыдущий элемент.}
  PPrev := nil;
  {Указатель на текущий элемент.}
  PCur := aPList;
  {Ищем позицию для вставки нового элемента. Новый элемент вставляется
  между элементами PPrev и PCur.}
  while (PCur <> nil) and (PCur^.Data.S < aStr) do begin
    {Переходим к следующему элементу.}
    PPrev := PCur;
    PCur := PCur^.PNext;
  end;
  {Вставка элемента в список.}
  {Вставка элемента в конец списка. В этом случае PPrev является указателем
  на последний элемент списка.}
  if PCur = nil then begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := nil;
    {Если список пуст, то новый элемент становится единственным
    элементом списка.}
    if PPrev = nil then
      aPlist := PNew
    {Если список непустой, то новый элемент добавляем после последнего
    элемента списка.}
    else
      PPrev^.PNext := PNew;
  {Найдено такое же слово. В этом случае вместо вставки выполняем
  увеличение счётчика по этому слову.}
  end else if PCur^.Data.S = aStr then
    Inc(PCur^.Data.Cnt)
  {Вставка вначале или внутри списка. В этом случае мы должны вставить новый
  элемент между элементами PPrev и PCur}
  else begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := PCur;
    if PPrev = nil then {Если вставка в начало списка.}
      aPList := PNew
    else                {Если вставка внутри списка.}
      PPrev^.PNext := PNew;
  end;
end;
 
{Освобождение памяти, занятой под список и инициализация списка.}
procedure Free(var aPList : TPElem);
var
  PDel : TPElem;
begin
  while aPList <> nil do begin
    PDel := aPList;
    aPList := aPList^.PNext;
    Dispose(PDel);
  end;
end;
 
{Распечатка однонаправленного списка.}
procedure WritelnList(const aPList : TPElem);
var
  PElem : TPElem;
  i, j : Integer;
begin
  if aPList = nil then begin
    Writeln('Список пуст.');
    Exit;
  end;
 
  PElem := aPList;
  i := 0;
  while PElem <> nil do begin
    {Распечатываем текущее слово PElem^.Data.Cnt раз.}
    for j := 1 to PElem^.Data.Cnt do begin
      Inc(i); {Счётчик распечатанных слов.}
      if i > 1 then Write(', ');
      Write(PElem^.Data.S);
    end;
    PElem := PElem^.PNext;
  end;
  Writeln;
end;
 
const
  N = 10000; {Размер текстового буфера.}
type
  TArrTxt = array[1..N] of Char; {Тип текстового буфера.}
 
procedure InputText(var aArr : TArrTxt; var aSize : Integer);
var
  Ch : Char;
  h : Integer;
  F : Boolean;
begin
  h := High(aArr); {Верхний индекс массива.}
  repeat
    Ch := Readkey;
    F := True; {Завершить цикл чтения с консоли.}
    if Ch = #8 then begin
      Write(Ch);
      if aSize > 0 then Dec(aSize);
    end else if Ch = #0 then
      Readkey
    else if Ch = #13 then
      Writeln
    else begin
      if aSize < h then begin
        Write(Ch);
        Inc(aSize);
        aArr[aSize] := Ch;
      end;
    end;
  until Ch in [#10, #13];
end;
 
{Выделение очередного слова из входной последовательности.}
function GetWord(const aArr : TArrTxt; var aSize, aInd : Integer) : String;
const
  {Множество букв латиницы.}
  Da = ['A'..'Z', 'a'..'z'];
var
  i : Integer;
  S : String;
  F : Boolean;
begin
  F := True;
  S := '';
  while (aInd <= aSize) and F do begin
    {Если обнаружена буква, то добавляем её к слову.}
    if aArr[aInd] in Da then
      S := S + aArr[aInd]
    {Если символ не является буквой и слово непустое,
    значит найден конец    слова.}
    else if S <> '' then
      F := False;
    Inc(aInd);
  end;
  GetWord := S;
end;
 
const
  M = 6;
var
  Arr : array[1..M] of TPElem;
  ArrTxt : TArrTxt; {Текстовый буфер.}
  i, Size, Len : Integer;
  S : String;
begin
  {Начальная инициализация массива.}
  for i := 1 to M do Arr[i] := nil;
 
  repeat
    {Ввод текста.}
    Writeln('Задайте текст. Обработаны будут только те слова, которые состоят');
    Writeln('не более, чем из ', M, ' букв. Прекратить ввод - ENTER.');
    Size := 0;
    InputText(ArrTxt, Size);
 
    {Обработка текста, выделение слов, создание списков.}
    i := 1;
    repeat
      S := GetWord(ArrTxt, Size, i);
      Len := Length(S);
      case Len of
        1..M: Add(Arr[Len], S);
      end;
    until Len = 0;
 
    {Распечатка результатов.}
    Writeln('Результаты:');
    for i := 1 to M do begin
      Writeln('Слова с длиной ', i, ':');
      WritelnList(Arr[i]);
    end;
    Writeln;
 
    {Освобождение памяти, занятой под списки.}
    for i := 1 to M do Free(Arr[i]);
    Writeln('Память, занятая под списки, освобождена.');
 
    Writeln('Повторить - Enter, выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
3. С обыкновенным вводом. Т. е., здесь вводится вся строка целиком и ввод не является посимвольным.
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
program Project1;
 
uses
  Crt;
 
type
  {Тип основных данных списка.}
  TData = record
    S : String; {Слово.}
    Cnt : Integer; {Счётчик - сколько раз слово S присутствует в тексте.}
  end;
  {Тип указателя на элемент списка.}
  TPElem = ^TElem;
  {Тип элемента списка.}
  TElem = record
    Data : TData; {Основные данные элемента.}
    PNext : TPElem; {Указатель на следующий элемент списка.}
  end;
 
{Добавление элемента в однонаправленный упорядоченный список.
Список упорядочен по возрастанию (т. е. по алфавиту в соответствие
с действующей кодировочной таблицей.}
procedure Add(var aPList : TPElem; const aStr : String);
var
  PNew, PPrev, PCur : TPElem;
begin
  {Указатель на предыдущий элемент.}
  PPrev := nil;
  {Указатель на текущий элемент.}
  PCur := aPList;
  {Ищем позицию для вставки нового элемента. Новый элемент вставляется
  между элементами PPrev и PCur.}
  while (PCur <> nil) and (PCur^.Data.S < aStr) do begin
    {Переходим к следующему элементу.}
    PPrev := PCur;
    PCur := PCur^.PNext;
  end;
  {Вставка элемента в список.}
  {Вставка элемента в конец списка. В этом случае PPrev является указателем
  на последний элемент списка.}
  if PCur = nil then begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := nil;
    {Если список пуст, то новый элемент становится единственным
    элементом списка.}
    if PPrev = nil then
      aPlist := PNew
    {Если список непустой, то новый элемент добавляем после последнего
    элемента списка.}
    else
      PPrev^.PNext := PNew;
  {Найдено такое же слово. В этом случае вместо вставки выполняем
  увеличение счётчика по этому слову.}
  end else if PCur^.Data.S = aStr then
    Inc(PCur^.Data.Cnt)
  {Вставка вначале или внутри списка. В этом случае мы должны вставить новый
  элемент между элементами PPrev и PCur}
  else begin
    New(PNew);
    PNew^.Data.S := aStr;
    PNew^.Data.Cnt := 1;
    PNew^.PNext := PCur;
    if PPrev = nil then {Если вставка в начало списка.}
      aPList := PNew
    else                {Если вставка внутри списка.}
      PPrev^.PNext := PNew;
  end;
end;
 
{Освобождение памяти, занятой под список и инициализация списка.}
procedure Free(var aPList : TPElem);
var
  PDel : TPElem;
begin
  while aPList <> nil do begin
    PDel := aPList;
    aPList := aPList^.PNext;
    Dispose(PDel);
  end;
end;
 
{Распечатка однонаправленного списка.}
procedure WritelnList(const aPList : TPElem);
var
  PElem : TPElem;
  i, j : Integer;
begin
  if aPList = nil then begin
    Writeln('Список пуст.');
    Exit;
  end;
 
  PElem := aPList;
  i := 0;
  while PElem <> nil do begin
    {Распечатываем текущее слово PElem^.Data.Cnt раз.}
    for j := 1 to PElem^.Data.Cnt do begin
      Inc(i); {Счётчик распечатанных слов.}
      if i > 1 then Write(', ');
      Write(PElem^.Data.S);
    end;
    PElem := PElem^.PNext;
  end;
  Writeln;
end;
 
{Выделение очередного слова из входной последовательности.}
function GetWord(const aStr : String; var aSize, aInd : Integer) : String;
const
  {Множество букв латиницы.}
  Da = ['A'..'Z', 'a'..'z'];
var
  i : Integer;
  S : String;
  F : Boolean;
begin
  F := True;
  S := '';
  while (aInd <= aSize) and F do begin
    {Если обнаружена буква, то добавляем её к слову.}
    if aStr[aInd] in Da then
      S := S + aStr[aInd]
    {Если символ не является буквой и слово непустое,
    значит найден конец    слова.}
    else if S <> '' then
      F := False;
    Inc(aInd);
  end;
  GetWord := S;
end;
 
const
  M = 6;
var
  Arr : array[1..M] of TPElem;
  Txt : String; {Текст, заданный пользователем.}
  i, Size, Len : Integer;
  S : String;
begin
  {Начальная инициализация массива.}
  for i := 1 to M do Arr[i] := nil;
 
  repeat
    {Ввод текста.}
    Writeln('Задайте текст. Обработаны будут только те слова, которые состоят');
    Writeln('не более, чем из ', M, ' букв. Прекратить ввод - ENTER.');
    Readln(Txt);
    Size := Length(Txt);
 
    {Обработка текста, выделение слов, создание списков.}
    i := 1;
    repeat
      S := GetWord(Txt, Size, i);
      Len := Length(S);
      case Len of
        1..M: Add(Arr[Len], S);
      end;
    until Len = 0;
 
    {Распечатка результатов.}
    Writeln('Результаты:');
    for i := 1 to M do begin
      Writeln('Слова с длиной ', i, ':');
      WritelnList(Arr[i]);
    end;
    Writeln;
 
    {Освобождение памяти, занятой под списки.}
    for i := 1 to M do Free(Arr[i]);
    Writeln('Память, занятая под списки, освобождена.');
 
    Writeln('Повторить - Enter, выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
Добавлено через 4 минуты
Обработку функциональных клавиш я всё-таки оставил. - Чтобы клавиши "стрелки" перехватывать. Если стрелки нажиматься гарантированно не будут, то надо просто в функции GetWord() убрать часть с условием:
Pascal
1
else if Ch in [#0] then begin
В программе с буфером этот код расположен в процедуре InputText().
1
0 / 0 / 0
Регистрация: 23.02.2013
Сообщений: 12
24.02.2013, 17:26  [ТС] 20
Mawrat, *_____* самое то для меня это 3 вариант)))) спасибо огромное-огромное)))

Добавлено через 3 минуты
Mawrat, можете посмотреть еще эту задачку? она похожая)) мб это через чур))) но все же)) Задача на списки
0
24.02.2013, 17:26
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.02.2013, 17:26
Помогаю со студенческими работами здесь

Нужно перевести код с Pascal ABC на Turbo Pascal - рисование работающей мельницы
Вот код, он должен рисовать работающею мельницу. uses graphABC,crt; type point=record ...

Можно как-то переделать код из Turbo Pascal чтобы он работал в pascal abc.net?
Сделайте пожалуйста, я просто не вникаю uses Graph, Crt; var grDriver: integer; grMode:...

Нужно перевести код из Turbo Pascal в Pascal ABC
Program n5; { Задача. Описать функцию less(f) от непустого файла f ...

Перевод программы с Turbo Pascal на Pascal ABC.NET
написала программу в паскаль турбо на рабочем компьютере. перенесла в паскаль авсNet так как дома...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru