Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование(4172,4173) / Лекции / Лекция 5. Обработка числовых последовательностей..doc
Скачиваний:
61
Добавлен:
12.03.2015
Размер:
121.86 Кб
Скачать

Лекция 5. Обработка числовых последовательностей Последовательная обработка

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

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

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

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

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

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

- числа;

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

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

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

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

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

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

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

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

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

Тогда процесс обработки можно представить в виде схемы на рис.5.1.

a) полная форма б) более короткая форма

Рис. 5.1. Схемы обработки числ. последовательности вида n, A1, A2, ... , An

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

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

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

{ {

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

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

. . . . . .

i++; }

}

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

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

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

A1 , A2 , ... , An , W

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

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

а) scanf ("%f", &a); б) scanf ("%f", &a);

do while (a!=W)

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

. . . . . .

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

} }

while (a!=W);

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

а) цикл с постусловием б) цикл с предусловием

Ввод А

Рис. 5.2. Схемы обработки числ. последовательности вида A1, A2, ... , An, W

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

Алгоритм 5.3. Последовательная обработка элементов до конца файла.

Ввод A;

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

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

Ввод A;

}

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

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

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

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

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

Обработка A;

или

while (ввод A и не конец входного файла)

Обработка A;

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

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

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

. . .

}

Примеры решения задач

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

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

п/п

n

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

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

1

2

6

4

1 -2 3 16 -5 40

-1 5 10 -20

сумма=-4

сумма=0

Программа:

#include <stdio.h>

#include <math.h>

main()

{

int n; /* количество чисел */

int a, /* очередное число */

s=0, /* сумма */

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

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

scanf ("%d", &n);

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

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

Введите числовую последовательность:

-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>

#define W 0 /* признак конца последовательности */

main( )

{

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

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

Сумма = 12.00

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

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

0

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

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

Тесты:

п/п

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

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

1

2

3

1 -2 16.5 -5.3 40

-1 15.5 10

5 -7 2.5

Максимум = 40

Максимум = 15.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-го числа */

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

else

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

if (x > max) max = x;

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

}

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( )

{ float apred, a; /* предыдущее и текущее числа */

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;

}

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

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

return 0;

}