Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Алгоритмизация и программирование на языке С++. Ч.1. Учебник

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
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] << " ";
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]