Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Алгоритмизация и программирование на языке С++. Ч.1. Учебник
.pdf
8. Массивы
111
Результат приведен на рис. 8.8.
Рис. 8.8. Подсчет количества элементов меньше среднего
Решим еще одну задачу. Найти среднее элементов одномерного массива размером n = 4, расположенных до первого
отрицательного элемента.
double a[4] {1.0, 2.0, –3.0, –4.0 };
double s; int k, i;
s = 0.0; k = 0;
for (i = 0; i<4; i++)
cout << a[i] << " ";
cout << endl;
for (i = 0; i<4; i++)
{ if (a[i] < 0) break;
s = s + a[i]; k++;
}
if (k > 0)
{ s = s / k; cout << s << endl; }
else
cout << "a[0]<0" << endl;
Для исходных данных
1.0, 2.0, –3.0, –4.0
получим результат
1,5
Для исходных данных
1.0, 2.0, –3.0, –4.0
получим результат

112
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
a[0]<0
Рассмотрим еще одну задачу. Сформировать массив из элементов исходного массива, удовлетворяющих заданному условию (отрицательных).
double a[4] {1.0, 2.0, – 3.0, – 4.0};
double b[4];
double s; int k, i;
k = 0;
for (i=0; i<4; i++)
if (a[i] < 0)
{ b[k]=a[i]; k=k+1; }
cout << " Negativ " << k << endl;
for (i = 0; i < k; i++)
cout << " " << b[i] << endl;
Результат:
Negativ 2
–3.0,
–4.0
Напомним, что в данном случае использован статический
способ определения массива.
Теперь рассмотрим задачу поиска значения и номера минимального (максимального) элемента массива.
int a[4] { –3, 2, –3, 4 };
int MinAr; int lMin, i;
MinAr = a[0]; k = 0;
for (i = 1; i < 4; i++)
{
if (a[i] < MinAr)
{ MinAr = a[i]; lMin=i;}
}
cout << "Min " << MinAr << " " << lMin;
Результатом будет значение и номер минимального элемента:
Min –3 0
В этом массиве два элемента имеют минимальное значе-
–3
ние (
). Но выводится номер первого из них. Если в услов-

8. Массивы
113
ном операторе поменять знак строго меньше (<) на нестрого
<=
меньше (
все элементы массива одинаковы, например
будет выведен номер самого последнего (
вого (
), будет выведен номер последнего. И даже если
{–3, –3, –3, –3};
<=
) или самого пер-
<
) из них (рис. 8.9).
,
Рис. 8.9. Все элементы массива одинаковы и использовано
<=
Для нахождения максимума надо поменять знак < на >.
Покажем, что можно найти это значение, не используя дополнительной переменной.
int a[4] { –3, 2, –3, 4 };
int i, iMax = 0;
// maxAr=a[0];
for (i = 1; i < 4; i++)
{
if (a[i] > a[iMax])
{ // maxAr=a[i]
k=i;}
}
cout << "Max " << a[iMax] << " " << iMax;
Будет выведено
Max 4 3
А теперь решим задачу нахождения максимума среди значений символьного массива.
// char cx[5] {'0','a','9','z','1'};
char cx[6]="0a9z1";
cout << "len = " << sizeof(cx)/sizeof(char) << endl;
cout << "(int) cx[5] = " << (int) cx[5] << endl;

114
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
char cMax=cx[0]; int iMax=0;
for (int i=0; i<5; i++)
{
cout << cx[i] << " " << (int)cx[i] << endl;
}
for (int i = 1; i < 4; i++)
{
if (cx[i] > cx[iMax])
{ cMax=cx[i];
iMax=i;}
}
cout << "\nMax " << cMax << " " << iMax;
Результат представлен на рис. 8.10.
Рис. 8.10. Максимум среди элементов символьного массива
Отметим следующее. В таком символьном массиве 6 (!)
элементов. Это связано с тем, что при инициализации массива строкой (двойные кавычки) в конец строки добавляется
символ окончания строки. Его код равен нулю. Также укажем, что максимальное значение определяется у элемента
с наибольшим кодом символа.
Теперь напишем программу, в которой индексы всех
максимальных элементов переносятся в новый массив.
int a[4] {4, 4, –3, 4 };
int ia[4];
int aMax; int k, i, iMax;
k = 0;

8. Массивы
cout << "Array " << endl;
for (i=0; i<4; i++)
cout << a[i] << " ";
cout << endl;
aMax=a[0];
for (int i = 1; i < 4; i++)
{
if (a[i] > a[iMax])
aMax=a[i];
}
cout << "Max " << aMax << endl;
k=0;
for (int i = 0; i < 4; i++)
if (a[i] == aMax)
{ ia[k]=i; k++; }
cout << "\nNew Array " << endl;
for (int i = 0; i < k; i++)
cout << ia[i] << " ";
cout << endl;
Результат представлен на рис. 8.11.
115
Рис. 8.11. Массив из номеров максимальных значений
Заметим, что возможно более эффективное решение этой
задачи с использованием одного цикла. Реализуйте его самостоятельно.
Далее рассмотрим алгоритмы сортировки.
Алгоритмов сортировки массивов существует огромное
множество, основных – около 30 [34]. Их можно разделить
на 5 групп.

116
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Один из наиболее известных алгоритмов сортировки –
сортировка «пузырьком» (англ. Bubble sort). При его реализации попарно сравниваются все расположенные рядом
элементы. И они меняются местами, если они расположены в неправильном порядке. Такая процедура повторяется
многократно (на один раз меньше, чем количество элементов
массива). Проиллюстрируем работу такого алгоритма. Рассмотрим процесс упорядочения по возрастанию элементов
массив a = {1, 2, –3, 4}:
а[0]
с
а[1]
сравниваем
– пара упорядочена, делать ничего
не недо;
а[1]
с
а[2]
сравниваем
их местами:
a = {1,–3,2,4}
Очевидно, что в случае такого массива
– пара не упорядочена, меняем
и т.д.
{1, 2, 4, –3}
для сортировки «пузырьком» надо выполнить такие шаги (на каждом из них сравниваются все соседние элементы):
{1,2,–3, 4}
1)
2)
{1,–3,2, 4}
3)
{–3,1,2, 4}
Таким образом, один шаг (проход) сравнения всех соседних элементов требует (n – 1) действий. Если элемент, который должен находиться на первом месте, в исходном массиве
находится на последнем месте, потребуется (n – 1) проходов.
Приведем программную реализацию этого алгоритма.
int n=4; int a[4] {1, 2, 4, –3};
cout << " ";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
for (int i = 0; i < (n-1); i++)
{
for (int j = 0; j < (n-1); j++)
{
if (a[j] > a[j + 1])
{

8. Массивы
117
int temp = a[j];
a[j]=a[j+1];
a[j+1] = temp;
// swap (a[j], a[j + 1]);
}
}
cout << "i= " << i << " ";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
}
cout << "Sort: ";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
В результате (рис. 8.12) выводятся значения элементов
массива после каждого прохода проверки соседних элементов.
Рис. 8.12. Сортировка «пузырьком»
Возможным недостатком такого алгоритма является тот
факт, что даже если исходный массив уже упорядочен, то все
проходы все равно будут выполняться.
Приведем реализацию алгоритма проверки «пузырьком»,
в котором проверяется упорядоченность после каждого прохода, и если массив уже упорядочен, то дальнейшие проверки не выполняются.

118
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
// Улучшенная сортировка "пузырьком"
int n=4; int a[4] {1, 2, –3, 4};
cout << "Array ";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
for (int i = 0; i < (n-1); i++) {
bool ag = true;
for (int j = 0; j < n-(i+1); j++)
{
if (a[j] > a[j + 1])
{
/* int temp = a[j];
a[j]=a[j+1];
a[j+1] = temp;
*/
/* a[j] =a[j]+a[j+1];
a[j+1]=a[j]-a[j+1];
a[j] =a[j]-a[j+1];
*/
ag = false;
swap (a[j], a[j + 1]); // МОЖНО ИСПОЛЬЗОВАТЬ swap
cout << "i= " << i << endl;
}
}
if (ag) {
break;
}
}
cout << "Sort: ";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
Результат приведен на рис. 8.13.

8. Массивы
Рис. 8.13. Сортировка «пузырьком» с проверкой
119
Если массив уже упорядочен, то после первого прохода
алгоритм прекратит проверку (рис. 8.14).
Рис. 8.14. Сортировка «пузырьком» с упорядоченным
массивом
Обратим внимание на то, что в программе для обмена значений двух элементов массива используются три способа. Два
из них (с использованием дополнительной переменной и без
использования таковой) закомментированы. А третий способ
swap
предполагает использование функции
.
Замечание. Есть разные мнения об эффективности использования функций в ситуации, когда содержащиеся в ней
действия можно легко реализовать самому. Отметим два момента. Первый – так проще – видимо, не правильный. А вот
swap
в случае с функцией
есть аргумент, который, видимо,
можно считать верным: она реализована для разных типов
данных и для некоторых из них обладает свойством эффективности [35].
Рассмотрим алгоритм сортировки вставками, базирующий-
ся на двух уже рассмотренных алгоритмах, а именно на алго-

120
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
ритмах поиска максимального элемента и перестановки элементов.
В цикле при i = 0, 1, 2, …, n – 2 будем устанавливать
на нужное место i-й элемент. Для этого найдем максимальный элемент и его индекс в части массива, начиная с i-го элемента, и далее поменяем местами максимальный элемент
с i-м. После окончания цикла элементы массива будут расположены в порядке убывания, при этом на последнем (n – 1)-м
месте окажется самый маленький элемент.
Отметим, что алгоритм так же потребует (n – 1) проходов,
как и в случае «пузырька». Но если каждый проход последнего потребует (n – 1) сравнений, то алгоритм вставками за 1-й
проход предполагает (n – 1) сравнение, 2-й – (n – 2) сравнения,
3-й – (n – 3) сравнения и т.д. При этом количество проходов
на один меньше, чем количество элементов, потому что, когда
останется последний элемент, его уже будет не с чем сравнивать, он уже и так на своем месте.
Приведем исходный код алгоритма сортировки вставками.
int a[4] { –1, 2, 3, –4};
int n=4, i, tmp;
for (i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
for (int j = 0; j < (n-1); j++)
{
int jMax = j;
for (i = j + 1; i < n; i++)
{ if (a[i]>= a[jMax])
{ jMax = i; }
}
tmp = a[j]; a[j]=a[jMax]; a[jMax] = tmp;
for (int i = 0; i < n; i++)
cout << a[i] << " ";
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
