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

avatar
jumbled_joe
9 августа 2021 в 04:58
79
4
1

это программа, которую я сделал, если я ввожу [13,11,10,17,18], я получаю вывод [12,13,17,11,10]. Я не понимаю, какую ошибку я делаю. кто-нибудь, пожалуйста, помогите мне понять.

#include <stdio.h>
#include <stdlib.h>
     
int main()
{
  int* ptr;
  int n,j,i,num,v;

  printf("Enter number of elements:");
  scanf("%d",&n);
  printf("Entered number of elements: %d\n", n);
  ptr = (int*)malloc(n * sizeof(int));

  for (i = 0; i < n; ++i) {
    scanf("%d",&v);
    ptr[i] = v;
  }
  i=0;
  j=0;
  while(i<5){
    j++;
    if (ptr[j]%2==0 && i%2==0){
      num=ptr[i];
      ptr[i]=ptr[j];
      ptr[j]=num;
    }
    if (ptr[j]%2!=0 && i%2 !=0){
      num=ptr[i];
      ptr[i]=ptr[j];
      ptr[j]=num;
    }
    
    if (j==4){
      i++;
      j=0;
    }
  }

  printf("The elements of the array are: ");
  for (i = 0; i < n; ++i) {
    printf("%d, ", ptr[i]);
  }
}
Источник
WhozCraig
9 августа 2021 в 05:14
2

Если когда-либо был кандидат на однострочную пошаговую отладку, то это он.

Yunnosch
9 августа 2021 в 05:15
0

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

paddy
9 августа 2021 в 05:19
0

Это странный способ сделать вложенный цикл. Было бы намного проще читать этот код, если бы у вас было два цикла for: один внутри другого. Я предполагаю, что вы всегда перезапускаете j-цикл с нуля, что вполне может испортить более раннее состояние «хорошо до индекса-i», которое вы уже вычислили. Попробуйте установить j=i при сбросе, это первое, что я бы попробовал.

Yunnosch
9 августа 2021 в 05:20
1

"если я ввожу [13,11,10,17,18], я получаю вывод [12,13,17,11,10]" Невозможно воспроизвести, я получаю "Элементы массива: 18, 13, 17, 11, 10, "Пожалуйста, дважды проверьте, что вы действительно получаете значения, отличные от введенных, потому что код выглядит так, как будто он дает сбой только при изменении порядка. Также, пожалуйста, предоставьте содержимое массива после каждого шага и укажите, в какой момент меняются значения, а не только порядок.

WhozCraig
9 августа 2021 в 05:33
1

точный ожидаемый результат является частью вашего поста. простой перебор последовательности при условии четного и нечетного - это алгоритм O (n) и не требует вложенного цикла. Это должно быть достаточно просто, если нет других конкретных ожиданий от окончательного порядка other, кроме четных, а затем нечетных.

Costantino Grana
9 августа 2021 в 07:14
0

Я знаю, что вы этого не сделаете, но в любом случае... отредактируйте свой вопрос , добавив, какова цель вашей программы: вы хотите иметь только четные элементы перед нечетными или их нужно сортировать ? Удалите все стандартные данные: никакого ручного ввода. Предоставьте в своем минимальном воспроизводимом примере массив, инициализированный данными примера. Затем четко предоставьте свой результат для этого примера и ожидаемый результат.

Ответы (4)

avatar
Costantino Grana
11 августа 2021 в 11:23
1

Хорошо, я пытался рассказать вам, как вы должны были написать свою программу, но вы не слушали:

  1. Создайте https://coderhelper.com/help/minimal-reproducible-example
  2. Для MCVE нужны все включения
  3. Никаких интерактивных вещей. Вам нужно запускать и запускать и запускать вашу программу в отладчике. Вы не хотите вводить данные вручную каждый раз.
  4. Вам нужно много тестов, и вы хотите их повторять, чтобы, исправив один, не сломать другой.
  5. Создать функцию, которая выполняет задание.
  6. Освободи память!

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

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

void evenodd(int *v, size_t n)
{   
    for (size_t i = 0; i < n; ++i) {
        while (i < n && v[i] % 2 == 0) {
            ++i;
        }
        --n;
        while (i < n && v[n] % 2) {
            --n;
        }
        if (i < n) {
            int tmp = v[i];
            v[i] = v[n];
            v[n] = tmp;
        }
    }
}

bool is_evenodd(int *v, size_t n)
{
    size_t i = 0;
    while (i < n && v[i] % 2 == 0) {
        ++i;
    }
    while (i < n && v[i] % 2 != 0) {
        ++i;
    }

    return i == n;
}

void main_test(const int *v, size_t n)
{
    int *v1 = memcpy(malloc(n * sizeof(int)), v, n * sizeof(int));

    evenodd(v1, n);

    if (is_evenodd(v1, n)) {
        printf("Ok!\n");
    }
    else {
        printf("Fail!\n");
    }

    free(v1);
}

int main(void) 
{
    main_test((int[]) { 1 }, 0);
    main_test((int[]) { 1 }, 1);
    main_test((int[]) { 2 }, 1);
    main_test((int[]) { 1, 2 }, 2);
    main_test((int[]) { 1, 3 }, 2);
    main_test((int[]) { 2, 1 }, 2);
    main_test((int[]) { 2, 4 }, 2);

    main_test((int[]) { 1, 3, 2 }, 3);
    main_test((int[]) { 1, 4, 2 }, 3);

    size_t n = 1000;
    int *a = malloc(n * sizeof *a);
    for (size_t i = 0; i < n; ++i) {
        a[i] = rand();
    }
    main_test(a, n);
    free(a);

    return 0;
}
avatar
jumbled_joe
11 августа 2021 в 05:53
0

хорошо, я решил это....

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

если мы находим любое (четное число), мы меняем текущее значение индекса на четное число.

#include <stdio.h>
#include <stdlib.h>
    
  int main()
{
  int* ptr;
  int n,j,i,num,v;

  printf("Enter number of elements:");
  scanf("%d",&n);
  printf("Entered number of elements: %d\n", n);
  ptr = (int*)malloc(n * sizeof(int));

  for (i = 0; i < n; ++i) {
  scanf("%d", &v);
  ptr[i] = v;
  }
  i=0;
  j=0;
  while(i<n && j<n){

  if (ptr[j]%2==0){
    num=ptr[i];
    ptr[i]=ptr[j];
    ptr[j]=num;
    i+=2;
    j=i;
  }
  j++;
  
  }

  printf("The elements of the array are: ");
  for (i = 0; i < n; ++i) {
  printf("%d, ", ptr[i]);
  }
}
Costantino Grana
11 августа 2021 в 11:11
0

"хорошо, я решил это..." Нет. Ваша программа дает сбой для произвольно большого количества случаев, таких как: [1, 4, 2]. Протестируйте здесь. Ваше предположение «видите, что четные числа всегда попадают в четные индексы» просто неверно. Подумайте о массиве, заполненном только четными числами, конечно, половина будет в четных индексах, а половина - в нечетных.

avatar
avonbied
9 августа 2021 в 05:22
-1

Если эта проблема заключается в сортировке массива по порядку (по убыванию) и последующем размещении всех четных значений перед нечетными, я бы рекомендовал:

  1. Сортировка массива
  2. Поменять местами и сдвинуть любые нечетные числа с четными числами

Вот простая реализация:

for (int i = 0; i < len - 1; i++) {
    for (int j = i + 1; j < len; j++) {
        if (arr[i] < arr[j]) {
            tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }
}
int lastEven = 0;
for (int i = 0; i < len - 1; i++) {
    if (arr[i] % 2 && (arr[i + 1] % 2 == 0)) {
        tmp = arr[i];
        arr[i] = arr[i + 1];
        arr[i + 1] = tmp;
        lastEven = i;
    } else if (arr[i] % 2 == 0 && lastEven-i > 1) {
        for (int j = i; j > lastEven; j--) {
            tmp = arr[j-1];
            arr[j-1] = arr[j];
            arr[j] = tmp;
        }
        lastEven++;
    }
}

Учитывая ввод [13,11,10,17,18], он сначала отсортирует массив ([18,17,13,11,10]), затем разделит четные и нечетные ([18,10,17,13,11])

Yunnosch
9 августа 2021 в 05:25
1

Если вам нужно задать уточняющие вопросы, прежде чем вы сможете ответить, подождите, пока у вас не будет права комментировать. meta.stackexchange.com/questions/214173/…

paddy
9 августа 2021 в 05:25
1

Выполнение нечетной/четной перетасовки после сортировки точно такое же, как и без сортировки.

avonbied
9 августа 2021 в 05:30
0

Нечетное/четное перетасовка должна происходить после сортировки, поскольку неизвестно, предварительно отсортирован ли входной массив. Если массив не отсортирован, результатом будет [10,18,13,11,17]. Сортировка удовлетворяет требованию "по порядку"

avonbied
9 августа 2021 в 05:31
0

@Yunnosch ответ можно отредактировать, как только спрашивающий внесет ясность, если это необходимо.

Yunnosch
9 августа 2021 в 05:33
0

Затем сформулируйте это как настойчивый ответ с намерением адаптировать его к поступающей информации или ...

Yunnosch
9 августа 2021 в 05:33
1

Пожалуйста, сформулируйте это как объясненный условный ответ, чтобы избежать впечатления, что вы задаете уточняющий вопрос вместо ответа (для которого вместо ответа следует использовать комментарий, сравните meta.stackexchange.com/questions/214173/ … ). Например, «Если ваша проблема… то решение состоит в… потому что….».

avonbied
9 августа 2021 в 05:36
0

Ах понял. Я продолжу и обновлю ответ сейчас. Спасибо за разъяснения

avatar
iam_atul22
9 августа 2021 в 05:17
0

Вы можете попробовать следующий код:

int even_index = 0; //start index
int odd_index = 4; //end index

for(int i=0;i<5;i++){
   if(ptr[i] % 2 == 0){
      int temp = ptr[even_index];
      ptr[even_index++] = ptr[i]; //swapping values and incrementing even_index
      ptr[i] = temp;
   }else{
      int temp = ptr[odd_index];
      ptr[odd_index--] = ptr[i];
      ptr[i] = temp;
   }
}
       

или вы также можете подсчитать количество четных чисел в цифрах при вводе и присвоить odd_value = even_num//количество четных цифр

Yunnosch
9 августа 2021 в 05:19
0

Я думаю, что ОП хочет понять свою ошибку, по крайней мере, об этом они спрашивают. Предоставление необъяснимого решения, похоже, не отвечает на этот вопрос.

Aval Sarri
9 августа 2021 в 05:22
0

ptr вводится, а также повторно используется/перезаписывается.