Сформировать на экране таблицу ASCII
Задание 3.01. Формирование таблицы ASCII
Сформировать на экране таблицу ASCII таким образом, чтобы в ней были представлены все отображаемые символы 866-й кодовой страницы и их числовые коды. Один из возможных вариантов заполнения экрана такой таблицей представлен на рис. 3.1.
Совет 1 (общий)

Рис. 3.1. Таблица ASCII
Программа 3_01.bas
RЕМ Вывод таблицы ASCII
CLS : PRINT TAB(31); "Таблица ASCII"
FOR I=32 TO 52: LOCATE I-29,1
FOR J=I TO 255 STEP 21
PRINT USING "! ### ";CHR$(J);J;
NEXT J
NEXT I
Программа 3_01.с
/* Вывод таблицы ASCII */
#include <stdio.h>
main() {
int i,j;
clrscr ();
gotoxy(31,1);
printf("Таблица ASCII");
for (i=32; i<=52; i++) {
gotoxy(1,i —2 9) ;
for (j=i; j<=255; j+=21)
printf("%c %3d ",j,j);
} getch();
}
Программа 3_01.pas
program ASCII; {Вывод таблицы ASCII} uses Crt; var
i,j:word; begin clrscr;
gotoxy(31,1);
write('Таблица ASCII');
for i:=32 to 52 do
begin
gotoxy(l,i-29);
j:=i;
repeat
write(chr(j) :l,j:4, ' ');
j:=j+21;
until j>255;
end;
readln;
end.
Задание 3.02. Преобразование строк к верхнему регистру
Составить подпрограмму (функцию) up (s), которая заменяет в строке s коды малых букв кодами аналогичных больших букв с учетом их расположения в таблице ASCII.
Совет 1 (общий)
По этой же таблице можно установить, что смещения в кодах между выделенными группами малых букв и их прописными эквивалентами, соответственно, равны 32, 32, 80 и 1 позициям.
Совет 2 (QBasic)
В приводимых ниже двух вариантах программы преобразование к верхнему регистру выполнено в виде подпрограммы UP и функции UP$. Чтобы не портить аргумент функции и другие глобальные переменные головной программы, в теле функции объявлены свои локальные переменные в и j.
Совет 3 (Си)
Совет 4 (Паскаль)
Программа 3_02.bas
REM Замена малых русских букв большими
DECLARE SUB UP (A$)
PRINT "Введите строку, содержащую малые и большие буквы"
INPUT "",A$
UP A$
PRINT A$ END
SUB UP(A$)
FOR j=l TO LEN(A$)
SELECT CASE MID$(A$,j,l)
CASE "a" TO "z": MID$(A$,j,1)=CHR$(ASC(MID$(A$, j , 1) )-32)
CASE "a" TO "n": MID$(A$,j,l)=CHR$(ASC(MID$(A$,j,l))-32)
CASE "p" TO "я": MID$(A$,j,1)=CHR$(ASC(MID$(A$,j,1))-90)
CASE "e": MID$(A$,j,l)="E"
END SELECT
NEXT j
END SUB
Программа 3_02a.bas
RЕМ Замена малых русских букв большими
DECLARE FUNCTION UP$(A$)
PRINT "Введите строку, содержащую малые и большие буквы"
INPUT "",A$
B$=UP$(A$)
PRINT A$
PRINT B$
END
FUNCTION UP$(A$)
'Чтобы не испортить аргумент А$, введена локальная переменная
DIM В AS STRING
В=А$
FOR J=l TO LEN(A$)
SELECT CASE MID$(В,J,1)
CASE "a" TO "z": MID$ (B, J, 1) =CHR$ (ASC (MID$ (B, J, 1) )-32)
CASE "a" TO "n": MID$ (B, J, 1)=CHR$ (ASC (MID$ (B, J, 1) ) -32)
CASE "p" TO "я": MID$(B,J,1)=CHR$(ASC(MID$(B,J,1))-80)
CASE "e": MID$(B,J,1)="E"
END SELECT
NEXT J
UP$=B
END FUNCTION
Программа 3_02.с
/* Замена малых русских букв большими */
# include <stdio.h>
#include <conio.h>
#include <string.h>
char *up(char *a);
void main() {
char a[80],*b;
printf("\n Введите строку, содержащую малые и большие буквы\n");
gets(a);
b=up(а);
printf("\na=%s",a);
printf("\nb=%s",b);
getch (); }
char *up(char *a) {
unsigned char b[80]; int j ;
strcpy(b,a);
for(j=0; j<strlen(a); j++) {
if ( 97<=b[j] && b[j]<=122) b[j]-=32;
if (160<=b[j] && b[j]<=175) b[j]-=32;
if (224<=b[j] && b[j]<=239) b[j]-=80;
if (241==b[j]) b[j]— ; }
return b; }
Программа 3_02.pas
program UperCase;
{ Замена малых русских букв большими }
var
a,b>:string[80] ; function up(a:string):string; var
j:integer;
begin
for j:=1 to length(a) do
case a[j] of
'a1..'z': a[j] :=chr (ord (a [ j ] )-32) ;
'a'.,'n'; a[j]:=chr(ord(a[j])-32);
'р'.'я': a[j]:=chr(ord(a[j])-80);
'ё': a[j]:='Ё'; end;
up:=a; end; begin
writeln('Введите строку, содержащую малые и большие буквы ');
readln(a);
b:=uр(а);
writeln(a);
writeln(b);
readln;
end.
Задание 3.03. Сортировка-фамилий
Составить программу, которая запрашивает у пользователя 10 фамилий, сортирует их по алфавиту и выводит отсортированный список. Пока сортируемый массив мал, мы не будем обращать внимание на эффективность алгоритма сортировки. Один из следующих разделов специально будет посвящен этому достаточно сложному и важному вопросу.
Так как программа должна сортировать фамилии, то следует установить правила их набора на клавиатуре, исключающие неоднозначность результатов сравнений:
Такие правила позволят вам не обращать внимания на различие между кодами больших и малых букв, т. к. сравниваться между собой, как правило, будут буквы одного регистра, коды которых соответствуют лексикографическому порядку. Коды инициалов и символы-разделители (точки, пробелы, тире) в таблице ASCII расположены раныпе кодов малых букв и поэтому на результаты сравнений не повлияют.
Совет 1 (общий)
Совет 2 (QBasic)
Совет 3 (Си)
В программе 3_03а. с для размещения фамилий использованы динамически запрашиваемые строки, на начало которых "смотрят" элементы массива указателей типа char (см. обращение к функции malloc). Вместо перестановки фамилий, расположенных не в алфавитном порядке, меняются местами соответствующие 4-байтовые указатели.
Перевод курсора в начало очередной строки списка осуществляется функцией gotoxy (col, row), последовательность параметров которой прямо противоположна соответствующему оператору QBasic.
Программа 3_03b!с построена менее замысловато. В ней использован двумерный массив для хранения фамилий, да и вывод результатов оформлен попроще.
Программа 3_03.bas
RЕМ Сортировка фамилий DIM NAMES(10)
N=10
CLS
FOR J=l TO 10
INPUT "Введи очередную фамилию - ", NAMES(J)
NEXT J CLS
PRINT "Фамилии до упорядочения : " FOR J=l TO N
LOCATE J+2,1: PRINT NAMES(J)
NEXT J
FOR J=l TO N-l
FOR K=J+1 TO N
IF NAME$(J)>NAME$(K) THEN
TMP$=NAME$(J)
NAME$(J)=NAME$(K)
NAMES(K)=TMP$
END IF
NEXT К
NEXT J
LOCATE 1,40
PRINT "Фамилии после упорядочения :"
FOR J=l TO N
LOCATE J+2,40: PRINT NAME$(J)
NEXT J
END
Программа 3_03а.с
/* Сортировка фамилий */
#include <stdio.h>
#include <alloc.h>
#include <conio.h>
#include <string.h>
main()
{
#define n_max 10
#define len_max 20
int j,k;
char tmp[len_max], *names[n_max], *p;
clrscr();
for(j=0; j< n_max; j++) {
printf("\n Введи очередную фамилию - ");
scanf("%s",tmp);
names[j]=(char *)malloc(len_max);
strcpy(names[j],tmp); }
clrscr () ;
printf("Фамилии до упорядочения :");
for(j=0; j<n_max; j++) {
gotoxyd, j+2) ;
printf("%s",names[j]); }
for(j=0; j<n_max-l; j++)
for(k=j+l; k<n_max; k++) {
if (strcmp(names[j],names[k]) > 0} {
p=names[j];
names[j]=names[k] ;
names[k]=p; } }
gotoxy(40,1);
printf("Фамилии после упорядочения :");
for(j=0; j<n_max; j++) {
gotoxy(40,j+2);
printf("%s",names[j]) ; }
getch(); }
Программа 3_03b.c
/* Сортировка фамилий */
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define N 10
main () {
cnar a[N][20],tmp[20];
int i,j; Clrscr () ;
puts(" Введите 10 фамилий по одной в строке");
for(i=0; i<N; i++)
gets(&a[i][0]);
for(1=0; i<N-l; 1++)
for(j=i+l; j<N; j++)
if(strcmp(&a[i] [0], &a[j] [0])>0) {
strcpy(tmp,&a[i][0]);
strcpy(&a[i][0],&a[j][0]);
strcpy(&a[j][0],tmp); }
puts("А теперь они же по алфавиту");
for (1=0; i<N; i++)
puts(&a[i][0]);
getch(); }
Программа 3_03.pas
program sort;
{ Сортировка фамилий }
uses crt;
const
n=10; var
j,k:integer; tmp:string[20];
name:array [l..n] of string[20];
begin cirscr;
for j:=1 to n do begin
writeln('Введи очередную фамилию');
readln(name[j]); end;
clrscr;
writeln('Фамилии до упорядочения :');
for j :=1 to n do
begin
gotoxy(1,j+2);
write(name[j]);
end;
for j:=1 to n-1 do
{
for k:=j+l to n do
begin
if name[j]>name[k] then
begin
tmp:=name [j];
name[j]:=name[k];
name[k]:=tmp;
end
end;
gotoxy(40,l);
writeln('Фамилии после упорядочения :');
for j:=1 to n do
begin
gotoxy (40,j+2);
write(name[j]);
end;
readln;
end.
Задание 3.04. Подсчет числа слов в строке
Предполагая, что вводимая строка содержит не более 80-ти символов и состоит из "слов", разделенных одним или более пробелами, подсчитать количество слов в строке. Обратите внимание на критические ситуации — строка пуста, строка состоит из одних пробелов, строка содержит единственное слово, слова могут содержать единственный символ, отличный от пробела.
Совет 1 (общий)
Программа 3_04.bas
RЕМ Подсчет числа слов в строке
CLS
SPACE=1: WORDS=0
PRINT "Введите строку"
INPUT "",S$
LENS=LEN(S$)
IF LENS=0 THEN GOTO RET
IF LEFT$(S$,1)<>" " THEN SPACE=0: WORDS=1
FOR J=2 TO LENS
IF SPACE=1 AND MID$(S$,J,1)<>" " THEN SPACE=0: WORDS=WORDS+1
IF SPACE=0 AND MID$(S$,J,1)=" " THEN SPACE=1
NEXT J
RET:
PRINT "Число слов в строке = "; WORDS
END
Программа 3_04.с
/* Подсчет числа слов в строке */
#include <stdio.h>
#include <conio.h>
#include <string.h>
main() {
char s[81], space=l, words=0, i,len;
clrscr ();
puts("Введите строку");
gets (s) ;
len=strlen(s);
if (len=0) goto ret;
if (s[0]!=' ') {
space=0;
words=l; }
for(i=l; i<len; i++) (
if (space==l &&, s[i]! = ' ') {
space=0; words++; }
if (space==0 && s[i]==' ')space=l; } ret:
printf("\n Число слов в строке = %d",words);
getch () ; }
Программа 3_04.pas
program num_words;
{ Подсчет числа слов в строке }
label ret;
var
s:string[81];
space:boolean;
words:byte;
i,len:byte; begin
writeln('Введите строку');
readln(s);
len:=length(s);
if len=0 then goto ret;
space:=(s[1]=' ');
if not space then words:=1;
for i:=2 to len do
begin
if (not space)and(s[i]=' ') then space:=true;
if (space)and(s[i]<>' ') then
Degin
space;=false; inc(words);
end;
end;
ret:
writeln('Число слов в строке = ',words);
readln;
end.
Задание 3.05. Анализ нажатой клавиши
Составить программу, которая анализирует код нажатой клавиши и выводит его на экран. Программа должна завершать свою работу после нажатия клавиши <Esc> (код клавиши равен 27).
Совет 1 (общий)
Совет 2 (QBasic)
Совет 3 (Си)
Совет 4 (Паскаль)
Программа 3_05.bas
RЕМ Анализ кода нажатой клавиши CLS
GETKEY: A$=INKEY$: IF A$="" THEN GOTO GETKEY
IF ASC(A$)=27 THEN STOP
IF LEN(A$)=1 THEN
IF ASC(A$)=13 THEN
PRINT "Нажата клавиша Enter с кодом = 13": GOTO GETKEY
END IF
PRINT "Нажата обычная клавиша ' "; A$; " ' с кодом ="; ASC(A$)
ELSE
PRINT "Нажата управляющая клавиша с кодом ";ASC(RIGHT$(A$,1))
END IF
GOTO GETKEY
Программа 3_05.с
/* Анализ кода нажатой клавиши */ #include <stdio.h>
main() { unsigned char ch;
clrscr(); getkey:
ch=getch();
if(ch==27) exit(0);
if(ch==13) {
printf("\n Нажата клавиша Enter с кодом = 13");
goto getkey; }
if(ch==0) {
ch=getch();
printf("\n Нажата управляющая клавиша с кодом = %d",ch); }
else printf("\n Нажата обычная клавиша %с с кодом=%d",ch,ch);
goto getkey;
}
Программа 3_05.pas
program keyboard;
( Анализ кода нажатой клавиши }
uses Crt;
label getkey;
var
ch:char;
begin
clrscr; getkey:
ch:=readkey;
if ord(ch)=27 then exit;
if ord(ch)=13 then
begin
writeln('Нажата обычная клавиша Enter с кодом = 13');
goto getkey;
end;
if ord(ch)=0 then
begin
ch:=readkey;
writeln('Нажата управляющая клавиша с кодом = ',ord(ch));
end else
writeln('Нажата обычная клавиша "',ch,'" с кодом=',ord(ch));
goto getkey; end.
Программа 3_05a.pas
program keyboard;
{ Анализ кода нажатой клавиши }
uses Crt;
var
ch:char; begin clrscr; repeat
ch:=readkey;
if ord(ch)=13 then
writeln('Нажата обычная клавиша Enter с кодом =13') else
if ord(ch)=0 then
begin
ch:=readkey;
writeln { 'Нажата управляющая клавиша с кодом = ' ,ord(ch) } ;
end else
writeln('Нажата обычная клавиша "',ch,'" с кодом = ',ord(ch});
until ord(ch)=27;
end.
Задание 3.06. Три цвета радуги
Мнемоническая фраза " Каждый охотник желает знать, где сидят фазаны" используется для запоминания последовательности цветовых оттенков радуги — красный, оранжевый, желтый, зеленый, голубой, синий, фиолетовый. Составить программу, которая вводит три слова, представляющие разные цвета радуги, и выводит их на экран в том порядке, в каком они должны быть расположены в описанной выше цветовой гамме. Например, введены слова желтый, красный и синий. На экран их следует вывести в "правильном" порядке — красный, желтый, синий.
Совет 1 (общий)
Программа 3_06.bas
REM Упорядочение цветов радуги
DATA "красный","оранжевый","желтый","зеленый"
DATA "голубой","синий","фиолетовый"
DIM А$ (7) , В$ (3)
FOR I=0 ТО 6: READ A$(I): NEXT I
PRINT "Введите по одному в строке 3 цвета радуги"
FOR I=0 ТО 2: INPUT B$ (I): NEXT I
PRINT "В радуге эти цвета следуют в таком порядке:"
FOR J=0 TO 6: FOR I=0 TO 2
IF A$(J)=B$(I) THEN PRINT A$(J)
NEXT I: NEXT J
END
Программа 3_06.c
/* Упорядочение цветов радуги */
#include <stdio.h>
#include <conio.h>
#include <string.h> main()
{
char a[7][11]={"красный","оранжевый",
"желтый","зеленый","голубой","синий","фиолетовый"};
char b[3][11]; int i,j;
printf("\n Введите по одному в строке 3 цвета радуги\n");
for (i=0; КЗ; i++) gets (&b[i] [0] ) ;
printf("\ nB радуге эти цвета следуют в таком порядке:\n");
for(j=0; j<7; j++) for(i=0; i<3; i++)
if(strcmp(&a[j][0],&b[i][0])==0)
puts(&a[j][0]); getch(); }
Программа 3_06.pas
program raduga;
{ Упорядочение цветов радуги }
const
a:array [1..7] of string[10]=('красный','оранжевый',
' желтый', ' зеленый', ' голубой', ' синий', ' фиолетовый') ;
var
b:array [1..3] of string[10];
i,j:byte; begin
writeln('Введите по одному в строке 3 цвета радуги');
for i:=l to 3 do readln(b[i]);
writeln('В радуге эти цвета следуют в таком порядке:');
for j:=1 to 7 do
for i:=l to 3 do
if a[j]=b[i] then writeln(a[j]);
readln;
end.
Задание 3.07. Левый и правый прижим, центрирование текста при выводе
Составить программу, которая запрашивает у пользователя текст, содержащий не более 20-ти символов, и выводит его в рамках колонки, расположенной с 10-й по 50-ю позиции с разными вариантами прижима. Для контроля правильности работы программы можно ограничиться вводом единственного символа и выдачей на экран строки, маркирующей номера колонок.
Совет 1 (QBasic)
Совет 2 (Си, Паскаль)
Программа 3_07.bas
CLS
PRINT "Введите строку, содержащую не более 20 символов"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
INPUT "", A$
PRINT "Вывод, начиная с 10-й позиции :"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
PRINT TAB(10); A$
PRINT "Вывод по центру между 10-й и 50-й позициями :"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
PRINT TAB(10 + (50 - 10) / 2 - LEN(A$) / 2); A$
PRINT "Вывод с прижимом к 50-й позиции :"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
PRINT TAB(51 - LEN(A$)); A$
END
Программа 3_07.с
#include <stdio.h>
#include <conio.h>
#include <string. h>
main()
{
char str[20], rule [] ="1234567890";
int i;
clrscr () ;
puts(" Введите строку, содержащую не более 20 символов");
for(i=0; i<8; i++)
printf("%s",rule);
gets (str) ;
puts("Вывод, начиная с 10-й позиции :");
for(i=0; i<8; i++) printf("%s",rule);
gotoxy(10,wherey()); puts (str) ;
puts("Вывод по центру между 10-й и 50-й позициями :");
for(i=0; i<8; i++) printf("%s",rule);
gotoxy(10+(50-10)/2-strlen(str)/2,wherey());
puts(str);
puts("Вывод с прижимом к 50-й позиции :");
for (i=0; i<8; i++) printf("%s", rule);
gotoxy(51-strlen(str),wherey());
puts(str);
getch(); }
Программа 3_07.pas
program text_justify;
uses Crt;
const
rule:string='1234567890'; var
s:string[20];
i:integer; begin
clrscr;
writeln('Введите строку, содержащую не более 20 символов');
for i:=0 to 7 do write(rule);
readln(s);
writeln('Вывод, начиная с 10-й позиции :');
for i:=0 to 7 do write(rule);
gotoxy(10,wherey); writeln(s);
writeln('Вывод по центру между 10-й и 50-й позициями :');
for i:=0 to 7 do write(rule);
#include <string.h>
main() {
char str[20], rule[]="1234567890";
int i ;
clrscr();
puts("Введите строку, содержащую не более 20 символов");
for(i=0; i<8; i++)
printf("%s",rule);
gets (str) ;
puts("Вывод, начиная с 10-й позиции :");
for(i=0; i<8; i++) printf("%s",rule);
gotoxy(10,wherey()); puts (str) ;
puts("Вывод по центру между 10-й и 50-й позициями :");
for (i=0; i<8; i++) printf("%s",rule);
gotoxy(10+(50-10)/2-strlen(str)/2,wherey());
puts(str); puts("Вывод с прижимом к 50-й позиции :");
for (i=0; i<8; i++)
printf("%s",rule);
gotoxy(51-strlen(str),wherey());
puts(str);
getch(); }
Программа 3_07.pas
program text justify;
uses Crt;
const
rule:string='1234567890'; var
s:string[20];
i:integer; begin
clrscr;
writeln(' Введите строку, содержащую не более 20 символов');
for i:=0 to 7 do write(rule);
readln(s);
writeln('Вывод, начиная с 10-й позиции :');
for i:=0 to 7 do write(rule);
gotoxy(10,wherey); writeln(s);
writeln('Вывод по центру между 10-й и 50-й позициями :');
for i:=0 to 7 do write(rule);
gotoxy(10+(50-10) div 2 - length(s) div 2,wherey);
writeln(s); writeln{'Вывод с прижимом к 50-й позиции :');
for i:=0 to 7 do write(rule);
gotoxy(51-length(s),wherey);
writeln(s);
readln; end.
Задание 3.08. Сравнение строк с игнорированием пробелов
Написать подпрограмму-функцию compare, имеющую своими аргументами две строки, которая сравнивает их, игнорируя пробелы между словами и разницу между кодами больших и малых букв. Функция должна возвращать следующие значения: 1, если первая строка "больше" второй; -1, если первая строка "меньше" второй; о, если обе строки равны.
Совет 1 (общий)
Программа 3_08.bas
REM Сравнение строк с игнорированием пробелов
DECLARE SUB UP(A$)
DECLARE FUNCTION COMPARE(B$, C$)
PRINT "Введите первую строку"
INPUT "",A1$
PRINT "Введите вторую строку"
INPUT "", A2$
K=COMPARE(A1$,A2$)
IF K=l THEN PRINT "Первая строка 'больше'"
IF K=-l THEN PRINT "Первая строка 'меньше'"
IF K=G THEN PRINT "Обе строки равны"
END
FUNCTION COMPARE(B$,C$) DIM B1$,C1$
UP B$: UP C$
FOR J=l TO LEN(B$)
IF MID$ (B$, J, 1)<>" " THEN B1$=B1$+MID$ (B$,J, 1 )
NEXT J
FOR J=l TO LEN(C$)
IF MID$(C$,J,1)<>" " THEN C1$=C1$+MID$(C$,J,1) NEXT J
IF B1$>C1$ THEN COMPARE=1 IF B1$=C1$ THEN COMPARE=0
IF B1$<C1$ THEN COMPARE=-1 END FUNCTION
SUB UP(A$)
FOR J=l TO LEN(A$)
SELECT CASE MID$(A$,J,1)
CASE "a" TO "z": MID$ (A$, J, 1) =CHR$ (ASC (MID$ (A$, J, 1) )-32)
CASE "a" TO "n": MID$(A$,J,1)=CHR$(ASC(MID$(A$,J,1))-32)
CASE "p" TO "я": MID$(A$,J,1)=CHR$(ASC(MID$(A$,J,1))-80)
CASE "ё": MID$(A$,J,1)="Ё" END SELECT
NEXT J
END SUB
Программа 3_08.с
/* Сравнение строк с игнорированием пробелов */
#include <stdio.h>
#include <conio.h>
#include <string.h>
char *up(char *a);
int compare(char *s1, char *s2);
void main() {
char s1[80],s2[80];
puts("Введите первую строку");
gets (s1);
puts("Введите вторую строку");
gets(s2);
switch(compare(s1,s2)) {
case 1: puts("Первая строка 'больше'");break;
case -1: puts("Первая строка 'меньше'");break;
case 0: puts("Обе строки равны");
}
getch(); }
char *up(char *a)
{
/* Замена кодов малых букв кодами больших */
static unsigned char b[80]; int j ;
strcpy (b, a) ;
for(j=0; j<strlen(a); j++) {
if(97<=b[j] && b[j]<=122) b[j]-=32;
if(160<=b[j] && b[j]<=175) b[j]-=32;
if (224<=b[j] && b[j]<=239) b[j]-=80;
if (241==b[j]) b[j]—; }
return b; }
int compare(char *s1,char *s2) {
char ssl[80],ss2[80]; char j,k;
strcpy(s1,up(s1)};
/* Замена малых букв большими */
strcpy (s2*, up (s2) );
/* с записью на то же место */
for(j=0,k=0; j<strlen(sl); j++)
if (sl[j] != ' ') ssl[k++]=sl[j];
/* Извлекаем непробелы */
ssl[k]=0x0; /* Добавили признак конца */
for(j=0,k=0;
j<strlen(s2); j++)
if(s2[j]!=' ') ss2[k++]=s2[j];
ss2[k]=0x0;
k=atrcmp(ss1.ss2) /* Cравнили преобразованные строки */
if(k>0)return 1;
if(k<0)return 1;
return 0;
}
Программа 3_08.pas
program comp_string;
{ Сравнение строк с игнорированием пробелов }
var
s1,s2:string;
function up (a:string):string; var
j:integer; begin
for j:=l to length(a) do
case a[j] of
'a'..'z': a[j] :=chr(ord(a[j])-32) ;
'a'..'n': a[j]:= chr(ord(a[j])-32} ;
'р'..'я': a[j]:= chr(ord(a[j])-80} ;
'ё': a[j]:='E'; end; up:=a; end;
function compare(s1,s2:string):integer;
var
ssl,ss2:string; j:byte;
begin
sl:=up(s1);
s2:=up(s2);
ssl:=' ';
for j:=l to length(s1) do
if sl[j]<>' ' then ssl:=ssl+sl[j];
ss2:=' ';
for j:=l to length(s2) do
if s2[j]<>' ' then ss2:=ss2+s2[j];
compare:=0;
if ssl>ss2 then compare:=1;
if ssl<ss2 then compare:=-!;
end;
begin
writeln('Введите первую строку');
readln(s1);
writeln('Введите вторую строку');
readln(s2);
case compare(s1,s2) of
1: writeln('Первая строка "больше"');
-1: writeln('Первая строка "меньше"');
0: writeln('06e строки равны');
end;
readln;
end.
Задание 3.09. Разноцветный текст
Написать программу, которая выводит на экран текст, меняя цвет букв и цвет фона.
Совет 1 (общий)
Программа 3_09.bas
RЕМ Разноцветный текст А$ = "ПРОГРАММИРОВАНИЕ"
CLS
' Отображение разноцветных букв на допустимой фоновой гамме
FOR CF=0 TO 7
FOR CS=0 TO 15
COLOR CS,CF LOCATE CF+1,2*CF+CS+1
PRINT MID$(A$,CS+1,1)
NEXT CS
NEXT CF
'Отображение мигающих разноцветных букв
FOR CF=0 TO 7
FOR CS=0 TO 15
COLOR CS+16,CF
LOCATE CF+1,2*CF+CS+41
PRINT MID$(A$,CS+1,1)
NEXT CS
NEXT CF
Программа 3_09.с
/* Разноцветный текст */
#include <conio.h>
main() {
int i ;
textbackground(0);
clrscr () ;
for(i=0; i<24; i++) {
gotoxy(2*i+l,i+l);
textcolor(128+i);
textbackground(i+2);
cprintf("Цветовая гамма в текстовом режиме"); }
getch(); }
Программа 3_09а.с
/* Разноцветный текст */
#include <conio.h>
main() {
int i;
textbackground(0) ;
clrscr();
for(i=0; i<24; i++) {
gotoxy(2*i+l,i+1);
textattr(128+i + ((i+1) « 4));
cprintf("Цветовая гамма в текстовом режиме");
}
getch (); }
Программа 3_09.pas
program colorl;
{ Разноцветный текст }
uses crt;
var
i:integer; begin
textbackground(0); clrscr;
for i:=0 to 23 do
begin
gotoxy(2*i+l,i+l);
textcolor(128+i);
textbackground(i+l);
writeln('Тест цветовой гаммы ');
end;
readln;
end.
Задание 3.10. Преобразование обычной дроби в десятичную
Составить функцию символьного (строкового) типа, преобразующую два своих целочисленных аргумента — числитель m и знаменатель п правильной дроби (m < n < 100) в строку, представляющую запись десятичной дроби. Для бесконечной дроби период следует заключить в круглые скобки. Например:
m=3 n=5 значение функции - "0.6"
m=1 n=6 значение функции - "0.1(6)"
Совет 1 (общий)
Совет 2 (Си)
Программа 3_10.bas
RЕМ Преобразование обычной дроби в десятичную
DECLARE FUNCTION FRAC2STR$(M%, N%)
CLS : DEFINT A-Z
INPUT "Введите числитель и знаменатель дроби : ",M,N
PRINT M;"/";N;"= ";FRAC2STR$(M,N)
END
DEFSNG A-Z
FUNCTION FRAC2STR$(M AS INTEGER,N AS INTEGER)
DIM S AS STRING, REST(100) AS INTEGER
DEFINT A-Z
I=3: S="0."
DO
Q=M*10\N : P=M*10 MOD N: REST(I)=P
IF P=0 THEN
FRAC2STR=S+CHR$(Q+48) EXIT FUNCTION
END IF
FOR J=3 TO 1-1
IF REST(J)=P THEN
FRAC2STR=LEFT$(S, J-l}+"("+RIGHT$(S,LEN(S)-J+l)+")"
EXIT FUNCTION
END IF
NEXT J
S=S+CHR$(Q+48): I=1+1: M=P LOOP UNTIL P=0
END FUNCTION
Программа 3_10.с
/* Преобразование обычной дроби в десятичную */
#include <stdio.h>
#include <conio.h>
char *frac_to_str(char m,char n);
main() {
char m,n;
printf("\n Введите числитель и знаменатель дроби : ");
scanf("%d %d",sm,&n) ;
printf("\n%d/%d=%s",m,n,frac_to_str(m,n));
getch();
}
/ *-----------------------------------------------* /
char *frac_to_str(char m,char n) {
int i=2,j,p,q;
char rest[100];
static char s [100]="0.";
do {
q=m*10/n; p=m*10%n; rest[i]=p;
if(p==0) { s[i]=q+48;
s[i+l]=0x0;
return s; }
for(j=2; j<i; j++)
if(rest[j]==p) {
for(p=i; p>=j; p--)
s[p+l]=s[p];
s[j]='(';
s[i+l]=')';
s [i+2]=0x0 ;
return s ; }
s[i]=q+48;
i++;
m=p; }
while (p!=0); }
Программа 3_10.pas
program drobi;
{ Преобразование обычной дроби в десятичную }
var
m, n:byte;
function frac_to_str(m,n:byte):string;
var
i,j,p,q:word;
s:string;
rest:array [1..100] of byte;
begin
s:='0.';
i:=l;
repeat
q:=m*10 div n;
p:=m*10 mod n;
rest[i]:=p;
if p=0 then begin
frac_to_str:==s+chr (q+48) ;
exit;
end;
for j:=l to i-1 do
if p=rest[j] then
begin insert(' (',s,j+2); frac_to_str:=s+')';
exit;
end;
inc(i);
s:=s+chr(q+48);
m:=p;
until p=0;
end;
begin
writeln('Введите числитель и знаменатель дроби :');
readln(m,n);
writeln(m,'/',n, ' = ', frac_to_str(m,n));
readln; end.
Задание 3.11. Перевод чисел в римскую систему счисления
Составить функцию символьного (строкового) типа, аргументом которой является натуральное число из интервала [1, 3999]. Функция должна возвращать строку с эквивалентным значением в формате римской системы счисления. Напомним, что в римской системе счисления используются большие латинские буквы — M(1000), O (500), C(100), L (50), X(10), V(5) и I(1). Если меньшая "цифра" находится левее "большей", то она вычитается (например: IV == V-I = 4, IX= X- I= 9, XL = L - X- 40). Если меньшая "цифра" расположена правее, то она прибавляется (например: VI = = V+ I= б, XI = X+ I= I I, LX = L + X = 60). Для некоторых "цифр" римская система допускает наличие до трех идущих подряд одинаковых
цифр —
I I= I + I = 2,
I I I = I + I+ I= 3,
XXX = X + X + X = 30,
ССС == C+ C+ C= 300,
MMM = M+ M+ M + 3000.
Совет 1 (общий)
Таблица 3.1. Расположение массива в порядке убывания числовых названий
Индекс элемента |
Символьный массив |
Числовой массив |
||
0 |
M |
1000 |
||
1 |
CM |
900 |
||
2 |
D |
500 |
||
3 |
CD |
400 |
||
4 |
С |
100 |
||
5 |
ХС |
90 |
||
6 |
L |
50 |
||
7 |
XL |
40 |
||
8 |
X |
10 |
||
9 |
IX |
9 |
||
10 |
V |
5 |
||
11 |
IV |
4 |
||
12 |
I |
1 |
||
Начинаем вычитать из переводимого числа первый элемент числового массива и вычитаем до тех пор, пока результат остается положительным. Каждый раз, когда вычитание возможно, к результирующей строке присоединяем соответствующее символьное значение. И так продолжаем экспериментировать с каждым элементом числового массива. Кстати, сумма всех элементов равна 3999, чем и объясняется ограничение на допустимый диапазон обрабатываемых чисел.
Программа 3_11.bas
RЕМ Перевод чисел в римскую систему
DECLARE FUNCTION torome$ (M%)
КЕМ Перевод арабских чисел в римскую систему счисления
DEFINT A-Z
COMMON SHARED ND()
COMMON SHARED SD$()
DATA 1,4,5,9,10,40,50., 90,100,400,500,900,1000
DIM ND(13)
FOR J=0 TO 12: READ ND(J): NEXT J
DATA I, IV, V, IX, X, XL, L, XC, C, CD, D, CM, M
DIM SD$(13)
FOR J=0 TO 12: READ SD$(J): NEXT J
INPUT "Введите целое число от 1 до 3999 : ", N
IF N<1 OR N>3999 THEN PRINT "Число вне диапазона":
END
PRINT "В римской системе счисления "; N;" = ";torome$(N)
END
FUNCTION torome$ (M)
SHARED ND(), SD$()
S$=""
FOR K=12 TO 0 STEP -1
WHILE ND(K)<=M
M=M-ND(K): S$=S$+SD$(K)
IF M=0 THEN EXIT FOR
WEND
NEXT К
torome$=S$
END FUNCTION
Программа 3_11.с
/* Перевод чисел в римскую систему счисления */
#include <stdio.h>.
#include <conio.h>
#include <string.h>
char *to_rome(int n) ;
main() {
int N;
printf("\n Введите целое число от 1 до 3999 : ");
scanf("%d",&N); if (N<0 | | N>3999) {
printf("\n Число вне диапазона");
getch();
exit(0); }
printf("\n B римской системе счисления %d = %s",N,to_rome(N));
getch();
}
/*-------------------------------*/
char *to_rome(int n) {
int k;
static char s[20]="";
int nd[13]={l,4,5,9,10,40,50,90,100,400,_500,900,1000};
char *sd[13]={"I","IV","V","IX","X","XL",
"L","XC","C","CD","D","CM","M"}; for(k=12; k>=0; k—) {
while(nd[k]<=n) {
n=n-nd[k]; strcat(s,sd[k]);
if(n==0) break;
} }
return s; }
Программа 3_11.pas
program in_rome;
{Перевод чисел в римскую систему счисления}
var
N:1..3999;
function to_rome(n:integer): string;
const
nd:array [1..13] of integer=
(1,4,5,9,10,40,50,90,100,400,500,900,1000) ;
sd:array [1..13] of string=
( 'I', 'IV, 'V, 'IХ', 'X', 'XL',
'L', 'XC', 'C','CD','D','CM', 'M');
var
k:integer;
s:string;
begin s : = " ;
for k:=13 downto 1 do
while nd[k]<=n do begin
n:=n-nd[k];
s:=s+sd[k];
if n=0 then break;
end;
to_rome:=s;
end; begin
write ('Введите целое число от 1 до 3999 : ' ).; readln(N);
writeln('B римской системе счисления ',N, ' = ', to_rome (N) ) ;
readln;
end.
Задание 3.12. Перевод чисел из римской системы счисления
Составить программу обратного преобразования из строки с записью числа в римской системе счисления в обычное число.
Программа 3_12.bas
REM Перевод чисел из римской системы счисления в арабскую
DEFINT A-Z
DATA 1,4,5,9,10,40,50,90,100,400,500,900,1000
DIM ND(13)
FOR J=0 TO 12: READ ND(J): NEXT J
DATA I,IV,V,IX,X,XL,L,XC,C,CD,D,CM,M
DIM SD$(13)
FOR J=0 TO 12: READ SD$(J): NEXT J
INPUT "Введите число в римской системе счисления : ", R$
J=l: M=0
100 :
FOR К=12 ТО 0 STEP -1
N=LEN(SD$(К))
IF MID$(R$,J,N)=SD$(К) THEN M=M+ND(K): J=J+N: GOTO 100
END IF
IF J>LEN(R$) THEN EXIT FOR
NEXT К
PRINT "В арабской системе счисления ";R$;" = ";M
END
Программа 3_12a.bas
REM Перевод чисел из римской системы счисления в арабскую
DATA 1000,900,500,400,100,90,50,40,10,9,5,4,1
DIM ND(13):
FOR J=0 TO 12: READ ND(J): NEXT J
DATA M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I
DIM SD$(13): FOR J=0 TO 12: READ SD$(J): NEXT J
INPUT "Введите число в римской системе счисления : ",R$
FOR J=l TO LEN(R$)
FOR K=0 TO 12
N=LEN(SD$(K))
IF MID$(R$,J,N)=SD$(К) THEN M=M+ND(K): J=J+1: K=K-1
END IF NEXT К NEXT J
PRINT "В арабской системе счисления ";R$;" = ";M
END
Программа 3_12.с
/* Перевод чисел из римской системы счисления в арабскую */
#include <stdio.h>
#include <conio.h>
#include <string.h>
main() {
int nd[13]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
char *sd[13]={"M","CM","D","CD","C","XC","L","XL","X",
"IX","V","IV","I"}; char r[20],s[3]; int j,k,n,m=0;
printf("ХпВведите число в римской системе счисления : ");
scanf("%s", r);
for(j=0; j<strlen(r); j++)
for(k=0; k<13; k++) {
n=strlen(sd[k]);
strncpyfs, &r.[j] ,n) ;
s[n]=0;
if(strcmp(s,sd[k])==0)
{ m += nd[k]; j++; k—; } }
printf("\nB арабской системе счисления %s = %d",r,m);
getch(); }
Программа 3_12.pas
{ Перевод чисел из римской системы счисления в арабскую }
program from rome;
const
nd:array [1..13] of integer=(1000,900,500,400,100,
90,50,40,10,9,5,4,1);
sd:array [1..13] of string=('M','CM','D','CD','C',
'XC' , 'L', 'XL', 'X', 'IX1, 'V, 'IV, 'I' ) ; var
r,s:string;
j,k,n,m: integer; begin
m:=0;
write('Введите число в римской системе счисления : ');
readln(r);
J:=l;
while j<=length(r) do begin k:=l;
while k<=13 do begin
n:=length(sd[k]);
s:=copy(r,j,n);
if s=sd[k] then begin
inc(m,nd[k]); inc(j);
dec(k);
end;
inc(k);
end;
inc(j);
end;
writeln('B арабской системе счисления ',r,' = ',m);
readln;
end.
Задание 3.13. Вхождение строки с разрядкой
Строка S2 может входить в более длинную строку S1 в общепринятом смысле, когда непрерывная подпоследовательность символов строки S1совпадает с цепочкой символов S2. Однако возможна и другая ситуация, когда строка S2 входит в строку S1 с разрядкой. При этом символы S2 с равномерным шагом через 1, 2, 3 или более символов встречаются в строке S1.
Например, для строк S1="ABCBEEC" и S2="ABC" имеют место обычное (с нулевым шагом разрядки) вхождение (символы 1, 2 и 3 в строке si) и вхождение с разрядкой в 2 символа (символы 1, 4 и 7 в строке S1).
Составить программу, которая:
Задача программы — определить все возможные варианты вхождения S2 в S1.
Совет 1 (общий)
сравнение надо с символа S1[I], совпадающего с первым символом S2. Однако реализация этой идеи может быть разной. Например, из строки si можно извлечь с заданной разрядкой нужное число символов и результат сравнить с S2. Более эффективно совместить эти две операции и сравнивать извлекаемый из S1 символ с очередным символом S2, прекращая выборку при первом несовпадении. Указанный подход был реализован победителем областной студенческой олимпиады В. Мартьяновым (апрель 2000 г.), на базе программы которого и построены приведенные ниже примеры. Наиболее оригинальной, на наш взгляд, является проверка условия (h=l) или (L2>1). Здесь L2—длина второй строки.
Программа 3_13.bas
RЕМ Поиск вхождения S2 в S1 с разрядкой
CLS
INPUT "Введите S1: ", Sl$: L1=LEN(S1$)
INPUT "Введите S2: ", 32$: L2=LEN(S2$)
FOR H=l TO L1
IF (H=l) OR (L2>1) THEN
FOR I=1 TO Ll-(L2-l)*H
IF MID$(S1$,I,1)=MID$(S2$,l,l) THEN
FOR J=2 TO L2,
IF MID$(S1$,I+(J-1)*H,1)<>MID$(32$,J,1) THEN GOTO ml
NEXT J
PRINT "Шаг: ";Н-1,"Позиции: ";I;
FOR К = 1 TO L2 - 1: PRINT "-"; I + К * H; : NEXT K: PRINT
К = 1 ml:
END IF
NEXT I
END IF
NEXT H
IF К = 0 THEN PRINT "Строка S2 не входит в S1"
END
Программа 3_13.с
/* Поиск вхождения S2 в S1 с разрядкой */
#include <stdio.h>
#include <conio.h>
#include <string.h> main{)
{
char s1 [80],s2[80];
int i,j,k=0,h,Ll,L2;
clrscr();
printf("Введите S1: ");
scanf("%s",s1);
Ll=strlen(s1);
printf("Введите S2: ");
scanf("%s",s2);
L2=strlen(s2);
for(h=l; h<=Ll; h++)
{
if(h==l || L2>1
}
{
for(i=0; i<Ll-(L2-l)*h; i++)
{
if (sl[i]=s2[0])
{
for(j=l; j<L2; j++)
if(si[i+j*h]!=s2[j]) goto ml;
printf("\n Шаг: %2d Позиции: %d",h-l,i+1);
for(k=l; k<L2; k++)
printf("-%d",i+i+k*h);
ml:;
}
} } }
if(k==0) printf(" Строка S2 не входит в S1");
getch () ; }
Программа 3_13.pas
program red_str;
(Поиск вхождения S2 в S1 с разрядкой}
uses crt;
var
s1,s2:string;
i,j,k,h,L1,L2:integer;
label 1;
begin
clrscr;
write('Введите S1: ');
readln (si);
Ll:=length(sl);
write('Введите S2: ');
readln (s2);
L2:=length(s2);
k:=0;
for h:=l to L1 do
if (h=l)or(L2>1) then
for i:=l to L1-(L2-1)*h do
if s1[i]=s2[l] then begin
for j:=2 to L2 do
if s1[i+(j-l)*h]os2[j] then goto 1;
write ('Шаг: ',h-l:2,' Позиции: ',i);
for k:=l to L2-1 do
write('-',i+k*h);
writeln;
k:=l;
1:
end;
if k=0 then writeln('Строка 32 не входит в S1');
readln;
end.