Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методические указания.pdf
Скачиваний:
81
Добавлен:
13.02.2015
Размер:
1.2 Mб
Скачать

13.2 Примеры решения задач с использованием операторов цикла

Проверка корректности введенных данных

Циклы зачастую используются для обеспечения корректного ввода данных пользователем, например листинг 6.1 демонстрирует проверку на корректность ввода числовой переменной x.

Листинг 6.1

Var strTmp:string; code:integer; x:real;

begin repeat

write('x='); readln(strTmp);//Ввод в строковую переменную val(strTmp,x,code); //Преобразование строки в число

if code<>0 then writeln('Error'); until code=0;

. . . //Здесь может быть размещена расчетная часть программы end.

Для проверки корректности ввода целой переменной x можно модифицировать листинг 6.1 так как показано в листинге 6.2. Для этого случая разработаем систему тестов, а затем покажем исполнение алгоритма.

Таблица 6.3 Система тестов Таблица 6.4 Исполнение алгоритма

Номер

Данные

Результат

теста

x

 

1

A

Неверно

2

12.5

Неверно

3

12

Верно

Номер

strTmp

realTmp

code

x

теста

 

 

 

 

 

1

‘A’

0

code<>0

неопред.

2

’12.5’

12.5

code<>0

неопред.

3

‘12’

12

0

12

Листинг 6.2

Var strTmp:string; code:integer; realTmp:real; x:integer;

begin repeat

write( 'x='); readln(strTmp);//Ввод в строковую переменную val(strTmp,realTmp,code); //Преобразование строки в число

if (code=0) and (realTmp=int(realTmp)) then begin

x:=trunc(realTmp); //Приведение вещест. числа к целому break;

end

else writeln('Error') until false;

57

. . . //Здесь может быть размещена расчетная часть программы end.

Для реализации проверки корректности ввода в среде Visual C# имеет смысл создать отдельный метод, возвращающий логическое значение в зависимости от правильности ввода. В качестве побочного эффекта создаваемый нами метод будет изменять значение вводимой переменной.

static bool DblParse(string name, ref double dblX)

{

Console.Write(name);

try { dblX = double.Parse(Console.ReadLine()); } catch

{

Console.WriteLine("Ошибка ввода вещественного числа"); return false;

}

return true;

}

В данном примере параметр name задает строку приглашения к вводу значения некоторой переменной, а параметр dblX передает необходимую нам переменную в метод для изменения ее значения пользователем. В методе solve, приведенном ниже вызов метода помещен в цикл, что позволяет заставить пользователя ввести корректное значение переменной.

static void solve() { double x = 0;

while (!DblParse("x=",ref x)) ; Console.WriteLine("x={0}",x);

}

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

static bool DblParse(string name, ref double dblX)

{

bool isNum; double retNum; string strTmp;

Console.Write(name); strTmp=Console.ReadLine(); try

{

isNum=double.TryParse(strTmp, System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo,

58

out retNum);

if (isNum) dblX = retNum; return isNum;

}

catch

{ return false; }

}

Решение задач с использованием диапазонов чисел

Пример 6.4 Подсчитать сумму всех n-значных чисел кратных 7

Все n-значные числа находятся в диапазоне от 10 n-1 до 10 n-1. Для вычисления границ диапазона можно использовать ли6о формулу 3.1 ли6о функцию power, преобразовав результат вычисления к целому типу, либо можно написать свою функцию вычисления степени целого числа (листинг 6.3).

Листинг 6.3 //Delphi

//Объявление функции

Function intpow(n:byte):longint; Var i:byte; result:longint; begin

result:=1;

for i:=1 to n do result:=result*10;

intpow:=result;

end;

//Основная программа

Var

i, sum, a, b:longint; n:byte; begin

write('n='); readln(n); sum:=0;

a:= intpow(n-1); b:=a*10-1;

for i:=a to b do

if i mod 7 = 0 then sum:=sum+i;

. . . //Здесь может быть размещен вывод результатов end.

//C#

Console.Write("n=");

int n = int.Parse(Console.ReadLine()); int a = 1; //Нижняя граница диапазона int i=1;

while (i++ < n) a *= 10;

int b = a * 10 - 1; //Верхняя граница диапазона

59

long sum=0;

for (i = a; i <= b; i++)

{

if (i % 7 == 0) sum += i;

}

Console.WriteLine("Сумма {0}-значных чисел, кратных 7 равна

{1}",n,sum);

Решение задач полным перебором

Большинство приведенных в этой лабораторной работе задач решается при помощи полного перебора всех возможных сочетаний, однако для части задач возможно провести некоторую оптимизацию, что можно продемонстрировать на примере 6.5.

Пример 6.5 У гусей и кроликов вместе 64 лапы. Сколько может быть кроликов и гусей (указать все сочетания)?

Здесь достаточно проблематично построить систему тестов, т.к существует 17 различных вариантов (64 / 4 +1), однако некоторые из них приведем:

Таблица 6.5 Система тестов Таблица 6.6 Исполнение алгоритма для варианта 2

Номер

гуси

кролики

 

k

результат

варианта

 

 

 

 

 

 

1

0

16

 

16

кроликов=16, гусей=0

2

2

15

 

15

кроликов=15, гусей=2

 

 

 

 

17

32

0

 

0

кроликов=0, гусей=32

Вариант решения 1 (полный перебор)

//Delphi

For g:=0 to 64 div 2 do

For k:=64 div 4 downto 0 do

If k*4+g*2=64 then writeln(‘кроликов=’,k,’гусей=’,g)

//C#

int count = 0;

for (int gus = 0; gus <= 64 / 2; gus++)

for (int krol = 0; krol <= 64 / 4; krol++)

{

if (krol * 4 + gus * 2 == 64) Console.WriteLine("{0}.\t кроликов = {1}\tгусей =

{2}", ++count, krol, gus);

}

Вариант решения 2 (оптимизированный)

//Delphi

For k:=64 div 4 downto 0 do

60