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

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

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
8. Массивы
121
cout << endl;
}
cout << "\nSort: \n"; for (int i = 0; i < n; i++)
cout << a[i] << " "; cout << endl;
Результат представлен на рис. 8.15.
Рис. 8.15. Сортировка вставками
Разберем алгоритм удаления элемента из массива. В при­мере задан символьный массив из пяти элементов. Надо уда­лить элемент с заданным номером. При этом размер массива не изменяется, а последний элемент окажется продублиро­ван. Алгоритм работает так. Начиная с элемента с заданным номером, на место каждого элемента помещается элемент с номером на единицу больше. Затем количество элементов формально уменьшается на единицу.
char Symbol[5] { 'a', 'b', 'Z', 'c', 'd'}; int i, k, n=5; k = 2; for (i = 0; i<n; i++) cout << Symbol[i] << " "; for (i = k; i < n; i++) Symbol[i] = Symbol[i + 1]; cout << "\nРезультат удаления элемента " << endl; n=n-1; for (i = 0; i<n; i++) // i<n cout << Symbol[i] << " ";
122
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Будет выведено следующее.
a b Z c d Результат удаления элемента
a b c d
И последний алгоритм, который рассмотрим в этом раз­деле, – добавление элемента в массив. В алгоритме исход­ный массив будет содержать на один элемент больше, но по­следний элемент будет пустым. Именно с него и будет начато смещение значений. Сначала последний элемент получит значение предпоследнего. Затем на место предпоследнего бу­дет занесен стоящий левее и так далее до элемента, располо­женного справа от того, на место которого надо занести но­вое значение. После этого можно поставить новое значение на указанное место.
// Добавление элемента в массив char Symbol[5] {'a', 'b', 'c', 'd', ' '}; char Ins='Z'; int i, k, n=5; k = 2; for (i = 0; i<n; i++) cout << Symbol[i] << " "; for (i = n-1; i >k; i--) Symbol[i] = Symbol[i-1]; Symbol[k]=Ins; cout << "\nРезультат добавления элемента " << endl; for (i = 0; i<n; i++) // i<n cout << Symbol[i] << " ";
В заключение приведем несколько типовых алгоритмов без соответствующих кодов. Рекомендуется разработать их самостоятельно, используя приведенные схемы алгоритмов, и проверить их на компьютере.
Поиск заданного элемента в упорядоченном массиве (би­нарный поиск).
Поиск в упорядоченном массиве осуществляется суще­ственно быстрее, чем в неупорядоченном. Поэтому часто це-
8. Массивы
123
лесообразно предварительно произвести упорядочение мас­сива, особенно в случае необходимости многократного поиска и больших массивов.
Требуется в массиве а размером n, упорядоченном по воз­растанию, определить наличие заданного элемента х и его индекс, если такой элемент найден.
Схема алгоритма.
x сравнивается со средним элементом массива.
Индекс среднего элемента i = (i
+ i2) / 2, где i1 = 0, i2 = n – 1.
1
Если x == a[i], задача решена.
Если x < a[i], то поиск продолжается в левой половине:
= i – 1, i1 не изменяется.
i
2
Если x > a[i], то поиск продолжается в правой половине:
= i + 1, i2 не изменяется.
i
1
Искомый элемент отсутствует в массиве, если выполнит­ся условие i
< i1.
2
Объединение двух массивов с чередованием элементов.
Требуется объединить два массива одинакового размером
A = {a b
, a1, …, a
0
, a1, b1, …, a
0
} и B = {b0, b1, …, b
n–1
, b
n–1
}.
n–1
} в один массив C = {a0,
n–1
Элементами массива С с четными индексами являются элементы массива A:
= a0; с2 = a1; …; с2i = ai, …,
c
0
элементами с нечетными индексами – элементы массива B:
= b0, c3 = b1…, …, с
c
1
2i–1
= bi, …
Таким образом, требуется организовать цикл и выполнить операции
с
2i
= ai, с
2i–1
= b
, для i = 0, 1, 2, … , n – 1.
i – 1
Если массивы имеют разные размеры, то больший массив обрезается по размеру меньшего, и меньший массив и уре-
124
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
занный большой объединяются в соответствии с предложен­ным алгоритмом. Далее оставшиеся элементы большего мас­сива пересылаются подряд.
Объединение двух упорядоченных массивов в один с со­хранением упорядоченности (упорядочение слиянием).
Требуется объединить два упорядоченных по убыванию массива – A размером n и B размером m в один массив C раз­мером (n + m), также упорядоченный.
Схема алгоритма.
Начиная с первых элементов массивов A и B, сравниваем элементы A[i] и B[j]. В массив C пересылаем больший из них, например A[i] (если выполняется условие A[i] >= B[j]).
Далее продолжаем пересылать в массив C элементы мас­сива A (индекс j при этом не меняется), пока очередной эле­мент массива A не будет меньше B[j] (условие A[i] >= B[j] не выполняется).
Тогда начинаем пересылать в массив C элементы массива B (индекс i при этом не меняется), пока для какого-либо элемен­та массива B не будет снова выполнено услови (A[i] >= B[j]).
Если один из массивов исчерпан (выполнено условие i >= n или j >= m), то оставшиеся элементы другого массива пересы­лаются друг за другом без всяких проверок.
Инвертирование массива.
Требуется изменить порядок следования элементов массива размером n на обратный, т.е. поменять местами нулевой эле­мент массива с (n – 1)-м, первый с (n – 2)-м, i-й с (n – (i + 1))-м. Последними нужно поменять местами средние элементы, т.е. (n / 2)-й и (n / 2 + 1)-й.
Циклический сдвиг.
Требуется переместить элементы массива А размером n на m позиций вправо. При этом m элементов из конца масси­ва перемещаются в начало:
А = {a
, a1, a2, a3, a4} – исходный массив;
0
8. Массивы
125
A = (a3, a4, a0, a1, a2) – после циклической перестановки на 2 позиции вправо.
Вариант 1. Используется вспомогательный массив для временного хранения m последних элементов массива А. Далее оставшиеся элементы с нулевого по (n m – 1)-й смещаются вправо на m позиций. (Заметим, что перемещение нужно на­чинать с последнего из перемещаемых элементов, чтобы не ис­портить элементы массива А.) После этого в первые m элемен­тов пересылаются элементы вспомогательного массива.
Вариант 2. Циклический сдвиг осуществляется с исполь­зованием одной вспомогательной переменной, в которую каж­дый раз пересылается последний элемент массива А, после чего все элементы сдвигаются вправо на 1 позицию (начиная с кон­ца), и на место первого элемента помещается значение вспомо­гательной переменной. Эта процедура повторяется m раз.
Далее рассмотрим способы обработки двухмерных масси­вов (матриц).
 
Матрица – это двухмерный массив, который можно пред­ставить себе как совокупность строк. Наглядно матрицу можно представить как таблицу. Для доступа к элементам двухмерных массивов обычно используются два индекса (номер строки и номер столбца). Заметим, что в памяти ком­пьютера элементы такого массива располагаются линейно (по строкам). Поэтому возможно перебирать элементы ма­трицы и с использованием указателя (то есть одной перемен­ной), как и одномерного массива.
 
Объявление двухмерного массива выполняется аналогич­но объявлению одномерных массивов. Так, следующее объ­явление создает двухмерный массив (матрицу) целых чисел из трех строк и трех столбцов.
126
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
int array[3][3];
Такое определение вводит множество из девяти элемен­тов:
array[0,0], array[0,1], array[0,2], array[1,0], array[1,1], ..., array[2,2]
При этом первый индекс элемента двухмерного массива обозначает номер сроки, а второй – номер столбца (то есть его номер в этой строке).
Покажем, как можно эти элементы заполнить, например, последовательными натуральными числами:
array[0,0]=1, array[0,1]=2, array[0,2]=3, . . . , array[2,2]=9:
int Arr2[3][3]; int k=0; for(int i=0; i<3; i++) for(int j=0; j<3; j++)
{
k=k+1; Arr2[i][j] = k;
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{ cout << Arr2[i][j] << " "; } }
При такой организации вывода значения элементов мас­сива будут последовательно (по строкам) напечатаны в стро­ку через пробел:
1 2 3 4 5 6 7 8 9
Если в оператор вывода добавить
endl
cout << Arr2[i][j] << " " << endl;
вывод будет в столбец.
Чтобы обеспечить наглядный вывод матрицы (в виде та­блицы), каждая строка матрицы должна выводиться в новую строку экрана с использованием подходящего формата:
8. Массивы
setlocale(LC_ALL,"Russian");
int Arr2[3][3]; int k=0; for(int i=0; i<3; i++) for(int j=0; j<3; j++)
{
k=k+1; Arr2[i][j] = pow(2,k);
}
// cout.width(2); – только первая строка for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{ cout.width(3); cout << Arr2[i][j] << " "; }
cout << endl; // переход на новую строку
}
Результат приведен на рис. 8.16.
127
Рис. 8.16. Вывод целочисленного двумерного массива
Замечание  1. В примере осуществляется форматирован­ный вывод.
Замечание  2. Значения элементов заполняются последо­вательными степенями числа 2.
Приведем код программы, в которой осуществлен фор­матированный вывод вещественного массива. Значения эле­ментов заполняются с использованием датчика случайных чисел.
oat Arr2[3][3]; int k=0;
128
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Согласен for(int i=0; i<3; i++) for(int j=0; j<3; j++)
{
k=k+1; Arr2[i][j] = rand()/pow(3,k);
}
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++) { cout.setf(ios::xed);
cout.width(8); cout.precision(2); cout << Arr2[i][j] << " "; }
cout << endl; // переход на новую строку
}
Результат приведен на рис. 8.17.
Рис. 8.17. Форматированный вывод вещественного
двухмерного массива
Еще один способ заполнить массив – это вводить значе­ния с клавиатуры, например:
oat Arr2[3][3]; cout << "Вводите значения" << endl; for(int i=0; i<3; i++) for(int j=0; j<3; j++)
{ cin >> Arr2[i][j]; }
8. Массивы
// cout.width(2); – только первая строка for(int i=0; i<3; i++)
{ // cout.width(3);
for(int j=0; j<3; j++) { cout.setf(ios::xed);
cout.width(8); cout.precision(2); cout << Arr2[i][j] << “ “; }
cout << endl; // переход на новую строку
}
Результат приведен на рис. 8.18.
129
Рис. 8.18. Ввод массива с клавиатуры
Теперь перейдем к рассмотрению алгоритмов обработки двухмерных массивов.
 
Теперь приведем несколько алгоритмов обработки дву­мерных массивов.
Замечание. В предыдущем разделе были приведены раз­личные способы задания значений элементов двухмерных
130
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
массивов. Однако в дальнейшем будем использовать только инициализацию массива при его объявлении, чтобы при от­ладке можно было легко изменить значения исходных дан­ных и проверить результат работы программы на разных те­стах.
Вычислим сумму элементов двухмерного массива:
oat Arr2[3][3]
{ {–1.0, 2.0, 3.0}, { 1.0, –2.0, 3.0}, { 1.0, 2.0, –3.0} };
cout << "Исходный массив:" << endl; for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++) { cout.setf(ios::xed);
cout.width(6); cout.precision(2); cout << Arr2[i][j] ; } cou << "\n"; }
oat Sum=0.0; for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
Sum = Sum + Arr2[i][j] ;
} }
cout << "Сумма – " << Sum << endl;
Результат выполнения программы приведен на рис. 8.19.
Теперь покажем, как можно получить доступ к элемен­там матрицы с помощью указателя, например для вывода:
int main()
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]