Сортировка символьных переменных



Рассмотрим следующую задачу. Дан список фамилий сотрудников предприятия (ограничимся 30 сотрудниками), требуется упорядочить фамилии в соответствии с русским алфавитом и отпечатать два списка. Введем следующие переменные:

1. alf $ - переменная, в которой храниться алфавит (упорядоченный набор букв русского алфавита, за исключением букв: Е, Й, Ы, Ъ, Ь), состоящий из 28 различных букв;

2. fam $ - одномерный символьный массив, состоящий из 30 элементов, в котором находятся не отсортированные по алфавиту фамилий сотрудников;

3. fam 1$ - одномерный символьный массив, состоящий из 30 элементов, в котором находятся отсортированные по алфавиту фамилий сотрудников;

4. i – параметр внешнего цикла, принимает значения от 1 до 28;

5. j – параметр внутреннего цикла, принимает значения от 1 до 30;

6. k – переменная, определяющая порядок заполнения результирующего массива fam 1$.

Для простоты построения программы будем рассматривать упорядочивание только по первой букве фамилии. Идея алгоритма сортировки состоит в следующем. Выделяется первый символ переменной alf $ (работает функция mid $), то есть буква «А» и сравнивается с выделенной первой буквой (также работает функция mid $) фамилии сотрудников (элемент массива fam $). Если буквы совпадают (равны), то данная фамилия переписывается в массив fam1$. Если буквы не совпадают, то организуется цикл просмотра всех остальных фамилий в массиве fam $. Затем выделяется новый символ из alf$ (новая буква), и все повторяется до тех пор, пока не закончится просмотр всех элементов (букв) в алфавите alf $. Таким образом, потребуется использовать два цикла: внешний цикл по параметру i – перебор букв из алфавита alf $, и внутренний цикл по параметру j – перебор фамилий из списка fam $.

Приведем текст программы:

rem сортировка символьных переменных по алфавиту cls dim fam$(30),fam1$(30) for l=1 to 30 read fam$(1) 'ввод исходных фамилий из блока данных next l data Ягодин, Борисов,…, Абрамов 'всего 30 неупорядоченных по алфавиту фамилий k=0 alf$=”АБВГДЕЖЗИК…ЭЮЯ” 'задание алфавита, всего 28 букв for i=1 to 28 'внешний цикл – просмотр букв алфавита for j=1 to 30 'внутренний цикл – перебор фамилий из списка if mid$(alf$,i,1)=mid$(fam$(j),1,1) then k=k+1 fam1$(k)=fam$(j) 'формирование отсортированного массива end if next j next i print “Номер”,”Исходный список”,”Отсортированный список” for l=1 to 30 print l, fam$(1),fam1$(1) next l stop

В результате работы программы на экране монитора появится информация:

Номер    Исходный массив          Отсортированный массив

1             Ягодин                            Абрамов

2             Суриков                         Борисов

……………………………………………………….

30           Абрамов                         Ягодин

 

Редактирование произвольного текста

К редактированию произвольного текста будем относить следующие операции:

1. выделение слов;

2. удаление слова;

3. вставка слова;

4. замена одного слова на другое.

Рассмотрим произвольный текст, состоящий из фразы, длина которой не превосходит 80 позиций. Такая фраза умещается на одной строке стандартного размера формата экрана монитора. Каждое слово отделяется одним символом пробела от другого. В качестве разъединительного признака могут выступать любые знаки: “.”,”,”,”;”,”:”,”-” и т. п. сначала решим задачу о выделении слов во фразе. Введем следующие обозначения:

  1. f $ - символьная переменная, в которой содержится произвольная фраза;
  2. w $ - символьный массив, в который будут записываться отдельные слова (количество элементов предполагаем не более 15);
  3. lw – массив длин выделенных слов;
  4. lf – длинна произвольной фразы;
  5. le $ - символьная переменная, в которой будет записываться выделенный символ из фразы;
  6. kw – количество слов во фразе;
  7. j – параметр, определяющий порядок заполнения массивов w$ и 1w.

Идея алгоритма заключается в следующем. Просматривая каждый символ, из которых состоит фраза (используется функция mid$). Если этот символ не является пробелом, то формируется слово, при этом используется операция конкатенации, то есть каждое слово получается путем присоединения отдельных символов друг к другу. Если рассматриваемый символ является пробелом (либо другим разделительным символом), то происходит переход к заполнению другого элемента массива w$. Представим версию возможной программы:

rem выделение слов из фразы rem формирование массива слов cls dim w$(15),lw(15) print “введите произвольную фразу” input f$ for i=1 to 15 w$(i)=” ” 'предварительное заполнение массива слов символом пробела, чтобы в дальнейшем осуществлялась операция конкатенации (объединения) lw(i)=1      next i lf=len(f$) 'определение длинны фразы, используется функция len j=1 for i=1 to lf 'цикл перебора всех символов из фразы le$=mid$(f$,i,l) 'выделение отдельного символа if le$<>” “ then 'сравнение выделенного символа le $ признака окончания слова (в данном случае – символом пробела) w$(j)=w$(j)+le$ 'операция присоединения символа le $ к тому, что хранится в w $ - формирование отдельных слов lw(j)=lw(j)+1 'подсчет длин каждого слова else j=j+1 'переход к формированию нового слова end if next i print “исходная фраза” print f$ print “та же фраза виде отдельных слов” kw=j-1 'истинное количество слов во фразе for i=1 to kw w$(i)=right$(w$(i),lw(i)-1) 'выделение правых lw ( i )- l символов в каждом слове, так как первым символом первоначально был символ пробел print w$(i) 'вывод на печать массива слов next i stop

 

Введите произвольную фразу ?Был хороший теплый вечер Исходная фраза Был хороший теплый вечер Та же фраза в виде отдельных слов Был хороший теплый вечер  
В результате работы программы на экране появиться следующий диалог:

 

 

Таким образом, в массиве w$ записаны отдельные слова текста, теперь можно записывать фразу в любом порядке, сортировать слова по любому признаку и алфавиту. Остальные функции редактирования можно рассмотреть на примере следующей задачи. Дана произвольная фраза длинной, как и ранее, не более 80 символов. Требуется вместо одного слова вставить другое. Введем следующие обозначения:

1. f $ - символьная переменная, в которой храниться произвольная фраза;

2. w$ - заменяемое слово;

3. wn$ - вставляемое слово;

4. le $ - левая часть исходной фразы до заменяемого слова;

5. ri $ - правая часть исходной фразы после заменяемого слова;

6. l – длинна произвольной фразы;

7. ll – длинна заменяемого слова;

8. n – номер позиции, начиная с которого заменяемое слово находиться во фразе;

9. fl $ - новая фраза с учетом замены одного слова w$ на другое wn$.

Составим программу сложной структуры, вынеся в подпрограмму такие вычисления, которые требуются для реализации задач редактирования, а именно:

- определение длинны исходной фразы,

- определение длинны заменяемого (либо удаляемого) слова,

- выделение левой части фразы до заменяемого (удаляемого) слова,

- выделение правой части фразы после заменяемого (удаляемого) слова.

 

 rem редактирование произвольного текста cls print “введите произвольную фразу” input f$ 13 print “введите вставляемое слово” input wn$ print “введите заменяемое слово” input w$ n=instr(f$,w$) 'определение местоположения заменяемого слова, работает функция instr , n – номер позиции слова w $ в исходной фразе f $ if n=0 then 'проверка на присутствие заменяемого слова в исходной фразе print “заменяемое слово отсутствует в исходной фразе” print “наберите еще раз это слово” goto 13 end if gosub a f1$=le$+” “+wn$+” “+ri$ 'формирование новой фразы, в которой одно слово w $ заменено на другое wn $, исползуется операция объединения print “исходная фраза” print f$ print “новая фраза” print f1$ stop 'конец основной программы  a: rem подпрограмма, в которой вычисляются параметры фразы rem фразы, общие для всех задач редактирования l=len(f$) ' l – длинна исходной фразы ll=len(w$) ' ll – длинна заменяемого (удаляемого) слова le$=left$(f$,n-2) 'левая часть фразы до заменяемого(удаляемого) слова ri$=right$(f$,1-n-ll) 'правая часть фразы после удаляемого слова return 'возврат в основную программу

 

Диалог работы программы:

введите произвольную фразу ?На дворе установилась настоящая русская зима введите вставляемое слово ?морозная введите заменяемое слово ?настоящая исходная фраза На дворе установилась настоящая русская зима новая фраза На дворе установилась морозная русская зима  

 

8.4. Ввод символа с клавиатуры с помощью функции inkey $. Работа встроенной функции instat

 

Для ввода символа (данных) может использоваться зарезервированная функция inkey $. Она содержит символ, считанный с клавиатуры в момент обращения к функции в тексте программы, как правило, в операторе присваивания:

……………

a$=inkey$

…………….

Обращение к функции inkey $ не приводит к остановке выполнения программы, при этом не наступает режим ожидания, как это было в случае с оператором input, и не высвечивается приглашение “?”. Если ни одна клавиша не нажата, то в переменную a$ передается пустая строка нулевой длинны (на самом деле будет считываться символ, переданной из буфера клавиатуры, хранящийся там о нажатии какой-либо клавиши до этого момента), а работа программы продолжается. Возникает вопрос, как остановить программу в этом месте, сообщить Пользователю о необходимости ввода в переменную a$ того или иного символа с клавиатуры, проще говоря, уведомить его, какую клавишу нажать для продолжения работы программы. В дальнейшем будем называть приостановку работы программы (без прерывания) в режиме выполнения для ввода символа (нажатия клавиши) “зависанием” программы. Различные приемы программирования будут представлены в следующем параграфе. Здесь более подробно остановимся на функциях inkey $ и instat. Функция inkey $ не имеет аргументов и возвращает символьную строку длинной 0, 1 или 2 байта, представляющую содержимое буфера клавиатуры. Пустая строка означает ( len ( inkey $)=0), что буфер чист. Буфер клавиатуры очищается автоматически каждый раз при запуске программы на выполнение. Разные длины символов в буфере определяются нажатием клавиш. Так, алфавитно-цифровая клавиатура содержит простые символы длинной 1 байт. Например, клавиша с цифрой 1 содержит код в соответствии с ASCII 49, клавиша Esc – код 27; клавиша Enter – код 13. Если длинна символьной строки в буфере равна 2, то это означает, что нажата специальная клавиша (insert, home и т. п., в том числе и функциональные F1 – А12), или комбинация клавиш (как правило, с клавишами shift, ctrl,alt). Первый символ (левый байт) имеет код, равный 0, а второй символ (правый байт) – так называемый расширенный код клавиши. Коды простых (стандартных) символов в соответствии с ASCII и расширенные коды специальных клавиш и клавиш в комбинации с shift, ctrl,alt приводятся в виде приложений в литературе [3,6,8]. Рассмотрим пример. Иллюстрирующий работу функций inkey$ и встроенной функции Asc по определению кодов различных символов, введенных с клавиатуры:

rem ввод различных символов с клавиатуры - работа функции inkey $ rem определение кодов символов ASCII – работа функции asc cls a: c$= inkey$ 'ввод символа из буфера с клавиатуры в переменную c $ if len(c$)=0 then goto a 'проверка на наличие какого либо символа в буфере клавиатуры. Если не нажата ни одна из клавиш, то управление передается метке a , то есть происходит “зависание” программы в этом месте if len(c$)=2 then gosub 1000 'переход в п/п по обработке символов от нажатия специальных клавиш и в комбинации else gosub 900 'переход в п/п по обработке символов от нажатия стандартных клавиш end if if cod l=13 then print “конец программы” else goto a 'в случае нажатия клавиши Enter (код - 13) программа заканчивается, при нажатии любой другой управление передается в начало для ввода следующего символа end if stop  900 rem подпрограмма обработки стандартных клавиш codl=asc(c$) ‘ определение кода print “код нажатой клавиши - ”;codl return 1000 rem подпрограмма обработки специальных клавиш cod1=asc(left(c$,l)) 'выделение кода левого символа (байта) cod2=asc(right(c$,1)) 'выделение кода правого символа (байта) print “код нажатой клавиши - ”;cod1;cod2 return

В результате выполнения данной программы в окне Run появится следующий диалог работы пользователя:

код нажатой клавиши – 49                   (нажата клавиша 1)

код нажатой клавиши – 97                   (нажата клавиша a – лат.)

код нажатой клавиши – 0 71                (нажата клавиша Home)

код нажатой клавиши – 0 73                (нажата клавиша Page Up)

код нажатой клавиши – 13                   (нажата клавиша Enter)

конец программы

 

Функция inkey$ обрабатывает все нажатия клавиш за исключением:

- Ctrl + Break (завершение программы);

- Ctrl + Alt + Del (перезагрузка DOS);

- Shift + PrnSc (печать содержимого экрана)

Функция instat

Функция instat возвращает статус клавиатуры, точнее буфера, клавиатуры. С ее помощью можно определить, нажата или не нажата какая-либо клавиша. Если клавиша нажата, то функция принимает значение «истина» (1), в противном случае – «ложь» (0). После нажатия клавиши функция instat будет возвращать значение истины (1) до тех пор, пока символ клавиши не будет удален из буфера клавиатуры, например, функцией чтения inkey$.

 


Дата добавления: 2021-11-30; просмотров: 20; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!