По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. |
Использование языка 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.
Для решения этой задачи понадобится функция, которая будет проверять, образуют ли цифры числа в восьмеричном представлении убывающую последовательность цифр.
Заголовок этой функции будет иметь вид:
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.
Этой задачей мы заканчиваем раздел, посвящённый обработке массивов, и предлагаем читателю самостоятельно решить несколько задач.