копипаста из двух массивов в третий
стоит задача: Сформировать новый упорядоченный по убыванию массив из двух упорядоченных в том же порядке массивов: А (12) и В (20). Задача вроде бы не сложная, но на ней я запутался.. Написал код(специально уменьшил размеры массива, чтобы легче было проверять):
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[4], b[5],c[9];
int* pa = &a[0], *pc=&c[0], *pb = &b[0];
int i = 0, k = 0, m = 0, j = 0, g = 0, f = 0;
printf("Заполните массив a: \n");
for (i = 0; i < 4; i++)
scanf("%d", &a[i]);
for (i = 0; i < 4; i++)
for (m = i + 1; m < 4; m++)
if (a[i] < a[m])
{
k = *(pa + i);
*(pa + i) = *(pa + m);
*(pa + m) = k;
}
for (i = 0; i < 4; i++)
printf("%d ", a[i]);
printf("\n");
printf("Заполните массив b: \n");
for (j = 0; j < 5; j++)
scanf("%d ", &b[j]);
for (j = 0; j < 5; j++)
for (g = j + 1; g < 5; g++)
if (b[j] < b[g])
{
f = *(pb + j);
*(pb + j) = *(pb + g);
*(pb + g) = f;
}
for (j = 0; j < 5; j++)
printf("%d ", b[j]);
printf("\n");
for (i=0, k=0; i<4;i++){
c[k++]=a[i];
}
for (i=0, k=0; i<5;i++){
c[k++]+=b[i];
}
for (j = 0; j < 9; j++)
printf("%d ", c[j]);
return 0;
}
Но все остановилось на том, что, во-первых, после ввода, в моем случае, 5 значений массива b, программа ждет ввода еще одного значения, а после выдает отсортированный массив b. Сначала думал, что это ошибка компилятора, но перейдя на онлайн компилятор - ошибка осталась. Но основная загвоздка в том, что я не могу, а точнее просто не знаю, как отсортированные значения массивов переписать в новый, и уже в нем их так же расставить по порядку. Серфил в поисках ответа, но так ничего не нашел. Буду рад вашим ответам и подсказкам! p.s. также хотелось бы попросить у вас рекомендации о какой-нибудь книжке по программированию на си(сам, что видно по коду, пока начинающий).
Ответы (2 шт):
Слияние двух сортированных массивов используется в mergesort и при реализации других задач, так что процедура эта хорошо известная и важная.
Использование магических чисел неправильно, поэтому приведу общую реализацию с длинами массивов alen и blen
ia = 0;
ib = 0;
ic = 0;
while (ia < alen && ib < blen) {
if (a[ia] >= b[ib])
c[ic++] = a[ia++];
else
c[ic++] = b[ib++];
}
//если в одном из массивов остались элементы, докопируем
while (ia < alen)
c[ic++] = a[ia++];
while (ib < blen)
c[ic++] = b[ib++];
- Чтобы меньше путаться надо выносить участки кода в функции, это упростит код и устранит дублирование (как в случае с написаной несколько раз сортировкой в вашем коде). Также важно давать переменным осмысленные имена.
- При правильном подходе массив полученный в результате слияния двух отсортированных массивов не требует сортировки - значения становятся на нужные места при слиянии - за один проход. Это оптимальнее дополнительной сортировки.
Моё решение. Значения отсортированны по возрастанию.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void merge_two_sorted_arrs(size_t size1, int arr1[],
size_t size2, int arr2[],
size_t size3, int arr3[]) {
size_t c1 = 0;
size_t c2 = 0;
for(size_t c3 = 0; c3 < size3; c3++) {
if ((c2 >= size2) || (c1 < size1 && arr1[c1] < arr2[c2]))
arr3[c3] = arr1[c1++];
else
arr3[c3] = arr2[c2++];
}
}
void sort_arr(size_t size, int arr[size]) {
for(size_t i = 0; i < size; i++) {
for(size_t j = 1; j < size - i; j++) {
if (arr[j - 1] > arr[j]) {
int tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
}
}
}
}
void fill_arr_by_rand(size_t size, int arr[size]) {
for(size_t i = 0; i < size; i++) {
arr[i] = rand() % 10;
}
}
void print_arr(size_t size, int arr[size]) {
for(size_t i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
puts("\n");
}
int main() {
srand(time(NULL));
size_t size1, size2;
puts("Enter arr1 size: ");
scanf("%zu", &size1);
puts("Enter arr2 size: ");
scanf("%zu", &size2);
size_t size3 = size1 + size2;
int arr1[size1];
int arr2[size2];
int arr3[size3];
fill_arr_by_rand(size1, arr1);
puts("Filled arr1");
print_arr(size1, arr1);
sort_arr(size1, arr1);
puts("Sorted arr1");
print_arr(size1, arr1);
fill_arr_by_rand(size2, arr2);
puts("Filled arr2");
print_arr(size2, arr2);
sort_arr(size2, arr2);
puts("Sorted arr2");
print_arr(size2, arr2);
merge_two_sorted_arrs(size1, arr1, size2, arr2, size3, arr3);
puts("Merged arr3");
print_arr(size3, arr3);
return 0;
}
Тест
$ gcc merge_two_sorted_arrays.c
$ echo -n 4 5 | ./a.out
Enter arr1 size:
Enter arr2 size:
Filled arr1
5 6 3 3
Sorted arr1
3 3 5 6
Filled arr2
4 3 6 2 2
Sorted arr2
2 2 3 4 6
Merged arr3
2 2 3 3 3 4 5 6 6