|
По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. |
Использование языка Free Pascal для обработки массивов
ЗАДАЧА 5.10. Задан массив вещественных чисел. Перевести все элементы массива в
-ричную систему счисления.
Перед решением всей задачи давайте разберёмся с алгоритмом перевода ве-щественного числа из десятичной в другую систему счисления. Этот алгоритм можно разделить на следующие этапы:
- Выделение целой и дробной частей числа.
- Перевод целой части числа в другую систему счисления.
- Перевод дробной части числа в другую систему счисления.
- Объединение целой и дробной частей числа в новой системе счисления.
Алгоритм перевода целого числа в другую систему счисления
Разделить нацело число на основание новой системы счисления. Получим остаток и частное. Остаток от деления будет младшим разрядом числа. Его необходимо будет умножить на 10 в нулевой степени. Если частное не равно нулю, то продолжим деление; новый остаток даст нам следующий разряд числа, который надо будет умножить на десять в первой степени и т. д. Деление будем продолжать до тех пор, пока частное не станет равным 0. Особенностью алгоритма является то, что число формируется в обратном порядке от младшего разряда к старшему, что позволит в один проход собрать число в новой системе счисления.
Алгоритм перевода дробной части числа в другую систему счисления
Умножить дробную часть числа на основание системы счисления. В полученном произведении выделить целую часть числа, это будет старший разряд числа, который необходимо будет умножить на
. Дробную часть опять умножить на основание системы счисления. В произведении целая часть будет очередным разрядом (его надо будет умножить на
), а дробную часть необходимо опять умножить на основание системы счисления до получения необходимого количества разрядов исходного числа.
Блок-схема функции перевода вещественного числа
из десятичной системы счисления в другую систему представлена на рис. 5.42.
Обратите внимание, как в блок-схеме и в функции реализовано возведение в степень. В связи с тем, что при переводе целой части числа последовательно используются степени
, начиная с
, для формирования степеней десяти вводится переменная
, которая вначале равна
, а затем в цикле последовательно умножается на
. При переводе дробной части числа последовательно нужны отрицательные степени
Поэтому при формировании дробной части числа переменная
, которая в цикле последовательно делится на
.
Ниже приведён текст консольной программы решения задачи 5.10 с комментариями.
{Функция перевода вещественного числа в p-ричную систему счисления.}
{Входные параметры функции: вещественное число N, основание системы}
{счисления - целое число p, kvo - количество разрядов в дробной части}
{формируемого числа.}
function perevod (N: real; P : word; kvo : word ) : real;
var i,N1, ost : word;
s1, N2, r, s2 : real;
q : real;
begin
{Если исходное число отрицательно, то для его перевода рекурсивно}
{обращаемся к функции perevod, передавая в качестве параметра модуль}
{числа.}
if N<0 then r:=- perevod ( abs (N),P, kvo )
else
begin
{Выделяем целую N1 и дробную N2 части вещественного числа N.}
N1:= trunc (N); N2:= frac (N);
s1 : = 0; s2 : = 0;
{В переменной q будем последовательно хранить степени десяти, вначале}
{туда записываем 1 - десять в 0 степени, а затем в цикле будем}
{последовательно умножать q на 10.}
q : = 1;
{Перевод целой части числа, пока число не станет равным 0.}
while (N1<>0) do
begin
{Вычисляем ost - очередной разряд числа - как остаток от деления N1 на}
{основание системы счисления.}
ost :=N1 mod P;
{Очередной разряд числа умножаем на 10 в степени i и добавляем к}
{формируемому числу s1.}
s1 := s1+ost * q;
{Уменьшаем число N1 в p раз путем целочисленного деления на p.}
N1:=N1 div P;
{Формируем следующую степень десятки.}
q:=q * 1 0;
end;
{В переменной q будем последовательно хранить отрицательные степени}
{десяти, вначале туда записываем 0.1 - десять в минус первой}
{степени, а затем в цикле будем последовательно делить q на 10.}
q : = 0.1;
for i :=1 to kvo do
begin
{Умножаем дробную часть на 10.}
N2:=N2* p;
{Вычисляем очередной разряд числа как целую часть от умножения N2 на}
{основание системы счисления. Очередной разряд числа умножаем на 10 в}
{степени i и добавляем к формируемому числу s2.}
s2 := s2+trunc (N2) * q;
{Выделяем дробную часть от сформированного числа}
N2:= frac (N2 );
{Формируем очередную отрицательную степень 10.}
q:=q / 10;
end;
{Суммируем целую и дробную часть числа в p-ричной системе счисления.}
r := s1+s2;
end;
perevod := r;
end;
var C: array [ 1.. 100 ] of real; p, i, n : word;
begin
{Ввод размера массива.}
Write( ’ n= ’ ); readln ( n );
{Ввод массива.}
writeln ( ’Массив C ’ );
for i :=1 to n do read (C[ i ] );
{Ввод системы счисления.}
writeln ( ’Введите основание системы счисления ’ ); readln ( p );
{Перевод всех элементов массива в другую систему счисления.}
for i :=1 to n do
c [ i ] : = perevod (C[ i ], p, 5 );
{Вывод преобразованного массива.}
writeln ( ’Преобразованный массив C ’ );
for i :=1 to n do
write (C[ i ] : 1 : 5, ’ ’ );
end.
удалить 3 последних числа, цифры которых в восьмеричном представлении образуют убывающую последовательность.Для решения этой задачи понадобится функция, которая будет проверять, образуют ли цифры числа в восьмеричном представлении убывающую последовательность цифр.
Заголовок этой функции будет иметь вид:
function vosem (N: word ) : boolean;
На вход функции vosem приходит целое десятичное число (формальный параметр N). Функция возвращает true, если цифры числа в восьмеричном представлении образуют убывающую последовательность, и false в противном случае.
При разработке алгоритма этой задачи следует помнить, что при переводе числа из десятичной системы в восьмеричную разряды числа мы будем получать в обратном порядке. Значит, получаемые восьмеричные разряды наоборот должны формировать возрастающую последовательность цифр.
Текст функции с комментариями приведён ниже.
function vosem (N: word ) : boolean;
var pr : boolean;
tsifra, tsifra_s t : word; i : integer;
begin
i : = 0;
{Предположим, что цифры числа N в восьмеричном представлении образуют}
{убывающую последовательность.}
pr := true;
{Пока число N не равно 0,}
while N<>0 do
begin
{Достаём очередной разряд числа в восьмеричной системе.}
tsifra:=N mod 8;
{Уменьшаем число в 8 раз.}
N:=N div 8;
i := i +1;
{Если разряд не первый}
if i >1 then
{И текущий разряд меньше или равен предыдущему, цифры числа N в}
{восьмеричном представлении не образуют убывающую последовательность}
{(pr:=false) - аварийно покидаем цикл.}
if tsifra <=tsifra_st then
begin
pr := false;
break;
end;
tsifra_st:= tsifra;
end;
vosem:= pr; end;
Алгоритм решения задачи следующий. Перебираем все числа в массиве в обратном порядке. Проверяем, образуют ли цифры текущего элемента массива в восьмеричном представлении убывающую последовательность. Если образуют, то количество таких чисел (
) увеличиваем на 1. Если
, то удаляем текущий элемент массива.
Создадим визуальное приложение, предназначенное для решения задачи 5.11. Расположим на форме следующие компоненты: три кнопки, три метки, одно поле ввода и две таблицы строк. Расположим их примерно так, как показано на рис. 5.44.
Свойства основных компонентов представлены в таблицах 5.9—5.10.
| Name | Caption (Text) | Width | Visible | Left | Top |
|---|---|---|---|---|---|
| label1 | Введите размер массива | 153 | true | 120 | 46 |
| label2 | Исходный массив | 110 | false | 192 | 96 |
| label3 | Преобразованный массив | 157 | false | 192 | 210 |
| Edit1 | 7 | 40 | true | 288 | 40 |
| Button1 | OK | 75 | true | 376 | 35 |
| Button2 | Удалить числа из файла | 185 | false | 160 | 448 |
| Button3 | Выход из программы | 185 | false | 568 | 448 |
| Name | ColCount | RowCount | Visible | FixedCols | FixedRows | Options.goEditing |
|---|---|---|---|---|---|---|
| StringGrid1 | 7 | 1 | false | 0 | 0 | true |
| StringGrid2 | 7 | 1 | false | 0 | 0 | false |
При запуске приложения видимы метка Label1, поле для ввода размера массива Edit1 и кнопка Button1.
При щелчке по кнопке OK (Button1) из поля ввода Edit1 считывается размер массива и становятся видимыми две другие кнопки, метка label2, таблица строк StringGrid1 для ввода элементов массива. Метка Label1, поле для ввода размера массива Edit1 и кнопка Button1 становятся невидимыми. Окно приложения после щелчка по кнопке OK станет подобным представленному на рис. 5.45.
При щелчке по кнопке Удалить числа из массива происходят следующие действия:
- считывание массива из StringGrid1;
- удаление из массива 3-х последних чисел, цифры которых в восьмеричном представлении образуют убывающую последовательность;
- становятся видимыми метка label3 и таблица строк StringGrid2 для вывода элементов преобразованного массива.
Ниже приведён текст модуля с необходимыми комментариями.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics,
Dialogs, StdCtrls, Grids;
{Описание формы.}
type
{ TForm1 }
TForm1 = class (TForm)
Button1 : TButton;
Button2 : TButton;
Button3 : TButton;
Edit1 : TEdit;
Label1 : TLabel;
Label2 : TLabel;
Label3 : TLabel;
StringGrid1 : TStringGrid;
StringGrid2 : TStringGrid;
procedure Button1Click ( Sender : TObject );
procedure Button2Click ( Sender : TObject );
procedure Button3Click ( Sender : TObject );
private
{private declarations}
public
{public declarations}
end;
type massiv=array [ 1.. 1 0 0 ] of word;
var
Form1 : TForm1;
N: word;
X: massiv;
implementation
{TForm1}
{Функция vosem проверки, образуют ли цифры числа N в восьмеричном}
{представлении убывающую последовательность.}
function vosem (N: word ) : boolean;
var pr : boolean;
tsifra, tsifra_st : word;
i : word;
begin
i : = 0;
{Предположим, что цифры числа N в восьмеричном представлении образуют}
{убывающую последовательность.}
pr := true;
{Пока число N не равно 0,}
while N<>0 do
begin
{Достаем очередной разряд числа в восьмеричной системе.}
tsifra:=N mod 8;
{Уменьшаем число в 8 раз.}
N:=N div 8;
i := i +1;
{Если разряд не первый}
if i >1 then
{и текущий разряд меньше или равен предыдущему, цифры числа N в}
{восьмеричном представлении не образуют убывающую последовательность}
{(pr:=false) - аварийно покидаем цикл.}
if t s if r a <=t s if r a _ s t then
begin
pr := false;
break;
end;
tsifra_st:= tsifra;
end;
vosem:= pr;
end;
{Функция удаления из массива X(N) элемента c номером m.}
procedure udal ( var X: Massiv; m: word; var N: word );
var i : word;
begin
for i :=m to N _1 do
x [ i ] : = x [ i + 1 ];
N:=N-1;
end;
{Обработчик щелчка по кнопке ОК.}
procedure TForm1. Button1Click ( Sender : TObject );
begin
{Считываем размер массива из поля ввода.}
N:= StrToInt ( Edit1. Text );
{Делаем невидимыми первую метку, поле ввода и кнопку ОК.}
Label1. Visible := False;
Edit1. Visible := False;
Button1. Visible := False;
{Делаем видимыми вторую метку и таблицу строк.}
label2. Visible := True;
StringGrid1.Visible :=True;
{Устанавливаем количество элементов в таблице строк.}
StringGrid1.ColCount :=N;
{Делаем видимыми вторую и третью кнопки.}
Button2. Visible :=True;
Button3. Visible :=True;
end;
{Обработчик событий кнопки "Удалить числа из массива"}
procedure TForm1. Button2Click ( Sender : TObject );
var k, i : word;
begin
{Считываем массив из таблицы строк.}
for i :=0 to N -1 do
X[ i +1]:= StrToInt ( StringGrid1.Cells [ i, 0 ] );
k : = 0;
{Перебираем все элементы массива в обратном порядке.}
for i :=N -1 downto 0 do
{Если цифры очередного элемента массива в восьмеричном представлении}
{образуют убывающую последовательность,}
if vosem ( x [ i ] ) then
begin
{увеличиваем счетчик таких чисел на 1.}
k:=k+1;
{Если это первое, второе или третье число, удовлетворяющее условию, то}
{удаляем его из массива.}
if k<=3 then
udal ( x, i,N);
end;
{Делаем видимыми третью кнопку и вторую таблицу строк.}
label3.Visible := True;
StringGrid2.Visible :=True;
StringGrid2. ColCount :=N;
{Вывод преобразованного массива.}
for i :=0 to N _1 do
StringGrid2. Cells [ i, 0 ] : = IntToStr (X[ i + 1 ] );
end;
{Обработчик кнопки закрытия окна.}
procedure TForm1. Button3Click ( Sender : TObject );
begin
Close;
end;
initialization
{$I unit1.lrs}
end.
В результате работы программы решения задачи 5.11 окно приложения примет вид, представленный на рис. 5.46.
Этой задачей мы заканчиваем раздел, посвящённый обработке массивов, и предлагаем читателю самостоятельно решить несколько задач.




