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

Обработка числовых последовательностей

Последовательная обработка

Вряде задач применяется последовательная обработка данных, если:

1.необходимо вводить и обрабатывать последовательность элементов исходных данных в том порядке, в каком она размещена в файле на внешнем носителе;

2.каждый элемент последовательности используется не более одного

раза.

Такие задачи называют (однопроходной) последовательной обработкой данных. В этом случае не требуется хранения сразу всех элементов. Достаточно иметь одну переменную, содержащую текущий (очередной) элемент входной последовательности.

Внекоторых случаях используются несколько текущих элементов (например, два-три соседних).

Элементами данных последовательности могут быть:

-числа;

-символы, строки;

-записи файла и др.

Последовательность исходных данных может задаваться:

1.с указанием количества элементов;

2.с признаком конца последовательности;

3.обрабатываться до конца входного файла.

Обработка числовых последовательностей

22.Числовая последовательность задается с указанием количества вводимых чисел:

n, A1 , A2 , ..., An .

53

На языке С процесс обработки можно записать с помощью оператора цикла while или лучше оператора цикла for:

а)

scanf("%d", &n); i=1;

while (i<=n)

{

scanf ("%f", &a);

/* обработка a */

. . .

i++;

}

б)

scanf ("%d", &n); for (i=1; i<=n; i++)

{

scanf ("%f", &a); /* обработка a */

. . .

}

В этих фрагментах предполагается, что переменная a вещественного типа (float), поэтому указан формат %f. Если же последовательность состоит из целых чисел типа int, то следует выбрать формат %d.

Обработка очередного числа может иметь линейную структуру (состоять из нескольких последовательно выполняемых операторов) или структуру ветвления, которая программируется с помощью оператора if.

23.Последовательность задается в виде

A1 , A2 , ... , An , W

(n заранее неизвестно, W - признак конца последовательности), тогда процесс обработки в общем виде можно представить одной из двух схем, представленных на рис. 5.2.

Фрагменты программ на языке С, соответствующие этим схемам: а)

scanf ("%f", &a); do

{/* обработка a */

. . .

scanf ("%f", &a);

54

}

while (a!=W);

б)

scanf ("%f", &a); while (a!=W)

{/* обработка a */

. . .

scanf ("%f", &a);

}

W - символическая константа, которая должна быть определена с помощью директивы #define. Если а принимает целые значения, формат в операторе ввода нужно поменять на %d.

24.Входная последовательность A1, A2, ... , An продолжается до конца входного файла, n - неизвестное заранее количество элементов (n >=0), признак конца отсутствует.

Ввод A;

While (не конец входного файла)

{Обработка A;

Ввод A;

}

Конец файла при вводе с клавиатуры задается комбинацией клавиш

Ctrl-Z и Enter.

В программе на языке С конец входного файла можно обнаружить после попытки ввода данных за пределами файла.

Например, значением функции scanf() является количество фактически введенных элементов. Если не удалось ввести ни одного элемента, значение функции равно константе EOF, определенной в файле stdio.h как число -1.

Иногда в языке C можно обойтись одной операцией ввода A, поместив ее внутри условия цикла.

while (ввод A и A != W)

Обработка A;

или

while (ввод A и не конец входного файла) Обработка A;

55

Фрагмент программы на С:

while (scanf(“%f”, &A) != EOF)

{/* обработка A */

. . .

}

Примеры

Задача 1. Даны целые числа n, A1 ,A2 , ... ,An . Вычислить сумму тех чисел последовательности, которые удовлетворяют условию |Ai | < i2.

Тесты для проверки программы:

 

 

n

Исходная последовательность

 

Ожидаемый результат

 

 

п/п

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

6

 

1 -2 3 16 -5 40

 

 

сумма=-4

 

 

 

2

 

4

 

-1 5 10 -20

 

 

сумма=0

 

 

 

 

 

 

 

 

 

 

 

 

 

Программа:

 

 

 

 

 

 

 

#include <stdio.h>

 

 

 

 

 

 

 

#include <math.h>

 

 

 

 

 

 

 

main()

 

 

 

 

 

 

 

 

{

int

n;

/* количество чисел

*/

 

 

 

 

 

 

 

 

int

a,

/* очередное число

*/

 

 

 

 

 

 

s=0,

/* сумма

 

 

*/

 

 

 

 

 

 

i;

/* порядковый номер числа в

последовательностити */

 

 

 

 

 

 

 

 

printf ("\nВведите количество чисел: ");

 

 

 

scanf ("%d", &n);

 

последовательность:\n");

 

 

 

printf ("Введите числовую

 

 

 

for (i=1; i<=n; i++)

 

 

 

 

 

 

{

scanf ("%d", &a);

 

 

 

 

 

 

 

 

 

 

 

 

 

if (abs(a) < i*i) s=s+a;

}

printf ("сумма=%d\n", s); return 0;

}

Результаты тестирования программы:

Введите

количество чисел: 6

Введите

числовую

последовательность:

1 -2

3 16

-5

40

сумма=-4

 

 

 

Введите

количество чисел: 4

Введите

числовую

последовательность:

56

-1 5 10 -20

сумма=0

Задача 2. Дана последовательность чисел в виде A1, A2, ... , An, W. (W=0). Определить сумму и среднее арифметическое значение элементов A1,

A2, ... , An.

 

Тест. Вход:

2 3.5 1.5 5 0

Выход:

Сумма = 12.00

 

Среднее арифметическое = 3.00

Используем алгоритм, представленный на рис. 5.2 б, для определения суммы элементов числовой последовательности. Для вычисления среднего арифметического значения последовательности необходимо подсчитать не только сумму, но и количество элементов.

Программа:

#include <stdio.h>

0

/* признак конца

 

#define

W

 

последовательности */

 

 

 

main( )

 

 

 

 

 

{

a,

 

 

/* текущее число

 

float

 

 

 

*/

s = 0;

 

/*

сумма чисел

*/

 

 

int n = 0;

 

/*

количество чисел

*/

printf("\n Введите последовательность чисел, заканчивающуюся нулем\n");

scanf ("%f", &a); while (a != W)

{ s += a; n++;

scanf("%f", &a);

}

if (n != 0)

{printf ("Сумма = %.2f\n", s);

printf ("Среднее арифметическое = %.2f\n ", s/n);

}

else printf ("Пустая последовательность"); return 0;

}

Результаты тестирования программы:

Введите последовательность

чисел, заканчивающуюся нулем

2

3.5

1.5

5

0

57

Сумма = 12.00

Среднее арифметическое = 3.00

Введите последовательность чисел, заканчивающуюся нулем

0

Пустая последовательность

Задача 3. Дана числовая последовательность. Конец ввода данных отмечается нажатием клавиш Ctrl – Z (конец файла). Определить наибольшее число последовательности.

Тесты:

 

Исходная последовательность

Ожидаемый результат

п/п

 

 

 

 

 

 

 

 

 

 

 

1

 

1

-2

16.5 -5.3 40

Максимум = 40

2

 

-1

15.5

10

Максимум = 15.5

3

 

5

-7

2.5

Максимум = 5

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

а– текущий элемент последовательности,

max – максимум просмотренной части последовательности.

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

Программа:

/*

Определение максимального элемента

*/

/*

числовой последовательности

*/

#include <stdio.h>

 

 

main( )

/* Текущее число, текущий максимум

{

float a, max;

 

*/

/* Количество введенных чисел

 

int k;

*/

 

 

printf ("\nВведите последовательность чисел\n");

числа

k = scanf("%f", &max);

/* ввод 1-го

*/

 

пуста\n");

if (k < 1) printf ("\nВходная последовательность

else

 

 

{while (scanf("%f", &x) != EOF )

if (x > max) max = x; printf ("\nМаксимум= %f\n", max);

}

58

return 0;

}

 

 

 

 

 

 

 

 

 

 

Задача 4. Задана числовая последовательность, содержащая не менее

двух

элементов.

Определить,

является

ли

последовательность

знакочередующейся.

 

 

 

 

 

 

 

 

Тест 1.

Вход:

-5

3.1

-2

1 -7

 

 

 

Выход:

Знаки чередуются.

 

 

 

 

 

Тест 2.

Вход:

-5

3.1

-2

-1 7

 

 

 

Выход:

Знаки не чередуются.

 

 

 

Используем алгоритм 5.3. для обработки последовательности. Но одного текущего элемента последовательности недостаточно, будем сохранять два соседних текущих элемента:

аpred – предыдущий элемент последовательности,

а– текущий элемент последовательности.

При обработке последовательности необходимо искать нарушение чередования знаков (например, по значению произведения двух соседних элементов). Используем дополнительную переменную flag:

flag = 1 – последовательность знакочередующаяся, 0 – нет, инициализация: flag =1.

Программа:

#include <stdio.h>

 

 

main( )

apred, a;

/* предыдущее и текущее числа

{

float

 

int

*/

 

/* признак знакочередования

 

flag = 1;

 

 

*/

 

 

/* flag=1- знаки чередуются, 0 –

нет

*/

 

 

 

 

 

printf ("\nВведите последовательность чисел\n");

scanf("%f", &apred);

 

 

 

while( scanf("%f", &a)>0)

 

{ if (apred * a >= 0) flag = 0;

 

}

apred = a;

 

 

 

printf ("Знаки чередуются.");

 

if (flag)

 

else

printf ("Знаки не чередуются.");

}

 

return 0;

 

 

 

 

 

 

59