Как скопировать содержимое массива в два меньших массива неравного размера - PullRequest
0 голосов
/ 20 февраля 2019

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

#define size 20
double bigArray[size]={14.553,13.653,9.555,8.564..and so on...9.324,11.123};
/*IndicatorArray is associated to bigArray as follows:
 if bigArray[i]<10 then indicatorArray[i]=10 else =20 */
int indicatorArray[size]={20,20,10,10,..and so on..};
double array10[count10], array20[count20]; /*count10 and count20 are 
counters from indicatorArray passed as a size of each array 
in earlier function not shown here*/
for (i=0;i<size;i++){
        if (indicatorArray[i]==10) {
            arr10[i]=bigArray[i];
        //  printf("%lf ",arr10[i]); /*this shows me correct results*/
        }
        else {
            arr20[i]=bigArray[i];
        }
    }
    for (i=0;i<count10;i++){
        printf("%lf ",arr10[i]);
    }
    printf("\n \n");
    for (i=0;i<count20;i++){
        printf("%lf ",arr20[i]);
    }

В результате получается что-то типа

00.0000 00.0000 9.555 8.564 11.123 14.666 ....

14.553 13.653 00.000...... 00.000

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

9.55 8.564 ...... 7.123 и 14.533 13.653 .....11.123

Почему это происходит и как это сделать правильно?

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

Используйте отдельные счетчики для индекса в array10 и array20.

#define size 20

double bigArray[size]={14.553,13.653,9.555,8.564..and so on...9.324,11.123};

/*IndicatorArray is associated to bigArray as follows:
 if bigArray[i]<10 then indicatorArray[i]=10 else =20 */
int indicatorArray[size]={20,20,10,10,..and so on..};

double array10[count10], array20[count20]; /*count10 and count20 are 
counters from indicatorArray passed as a size of each array 
in earlier function not shown here*/

size_t i10; /* index for array10 *** */
size_t i20; /* index for array20 *** */

for (i=0, i10=0, i20=0; i<size; i++){
        if (indicatorArray[i]==10) {
            if(i10 < count10) { /* prevent array index out of range *** */
                arr10[i10++]=bigArray[i];
            }
        }
        else {
            if(i20 < count20) { /* prevent array index out of range *** */
                arr20[i20++]=bigArray[i];
            }
        }
    }
    for (i=0;i<count10;i++){
        printf("%lf ",arr10[i]);
    }
    printf("\n \n");
    for (i=0;i<count20;i++){
        printf("%lf ",arr20[i]);
    }
0 голосов
/ 20 февраля 2019

Как прокомментировал someprogrammerdude, вы должны изучить использование memcpy при копировании данных.Если вы все еще хотите использовать свою реализацию вместо этого, проблема заключается в том, как вы используете i в цикле for.Помните, что в этом случае i будет позицией в большом массиве, в которой появляется число, которое вы хотите скопировать.Если вы хотите, чтобы первый элемент, который вы копируете из большого массива, находился в позиции 0 одного из меньших массивов, то не получится, если вы используете arr10[i] и arr20[i].Вместо этого вы можете использовать счетчик для каждого меньшего массива и увеличивать каждый раз, когда элемент входит в него.Вот быстрый пример, который я сделал с онлайн-компилятором после жесткого кодирования некоторых значений:

int arr10Count = 0;
int arr20Count = 0;

int i;
for (i=0;i<size;i++){
        if (indicatorArray[i]==10) {
            arr10[arr10Count]=bigArray[i];
            arr10Count++;
        //  printf("%lf ",arr10[i]); /*this shows me correct results*/
        }
        else {
            arr20[arr20Count]=bigArray[i];
            arr20Count++;
        }
    }
0 голосов
/ 20 февраля 2019

Как уже упоминалось в комментариях, при разбиении содержимого массива распознайте, что каждый элемент находится в определенном адресуемом месте в памяти, что делает эту работу идеальной для memcpy () ,Вот простая иллюстрация, использующая эту концепцию:

int main(void)
{
    double source[] = {3.4,5.6,2.3,4.5,6.7,8.9,10.1,11.1,12.3,4.5};
    double split1[3];
    double split2[7];

    memcpy(split1, &source[0], 3*sizeof(double));
    memcpy(split2, &source[3], 7*sizeof(double));

    return 0;   
}

Если ваш проект имеет четко определенные и статические параметры, которые известны во время выполнения, тогда с помощью нескольких распространенных макросов и некоторых дополнительных переменных это можно сделатьнемного более общий.

Следующий пример по сути аналогичен приведенному выше рисунку, но в цикле, потенциально более адаптируемой конструкции.

#define SPLIT_CNT 3

int main(void)
{
    double source[] = {3.4,5.6,2.3,4.5,6.7,8.9,10.1,11.1,12.3,4.5,8.5,9.5};
    double split1[3];                         // arrays if differing sizes
    double split2[7];
    double split3[2];
    size_t start_pos;                         //position accumulator
    size_t cpy_len[SPLIT_CNT] = {3,7,2};      //known array sections
    double *split[] = {split1,split2,split3}; //enables looping on arrays of differing sizes
    start_pos = 0;
    for(int i=0;i<SPLIT_CNT;i++)
    {
        if(i > 0)start_pos += cpy_len[i-1]; //move the start postition  
        memcpy(split[i], &source[start_pos], sizeof(double)*cpy_len[i]);
    }

    return 0;   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...