Заполнение пропущенных чисел из массива

Я пытаюсь заполнить недостающие числа из пользовательского ввода (который хранится в массиве. Например, если пользователь вводит 9, 5, 2, 7, 1. Моя программа должна выводить недостающие числа, то есть 3, 4 , 6, 8.

Вы можете видеть, что недостающие числа выделены жирным шрифтом: 1, 2, 3, 4, 5, 6, 7, 8

Однако мой код, похоже, не запускается. Цикл while не работает. Я чувствую, что моя логика работает, но ничего не выводит.

void missing_num(int length, int numbers[]) { // length is the length of the array

// A function which finds the biggest number the user inputed
int big_num_answer = biggest_num(length, numbers);

// A functon which finds the smallest number the user inputed
int small_num_answer = smallest_num(length, numbers);

int has_been_used = 0;
int i = 0;
int start_num = small_num_answer;
while(start_num <= big_num_answer) {

    if (numbers[i] == start_num + 1) {
        start_num += 1;
        has_been_used = 1;
    } else if (i >= length && has_been_used == 0) {
        printf("%d", start_num + 1);
    }

    i++;
    if (i > length) {
        i = 0;
    }
}

}

Вероятно, это идеальное время для узнать, как отлаживать свои программы.

Some programmer dude 02.05.2018 13:34

@Someprogrammerdude Потратил около 30 минут на попытки. Я застрял

Zoey Malkov 02.05.2018 13:38

@ZoeyMalkov Вы можете объяснить свою логику?

Shubham 02.05.2018 13:49

@Shubham Он находит наименьшее и наибольшее число из пользовательского ввода (например, 1 и 8). Затем он использует наименьшее число (1) и просматривает массив, чтобы найти, есть ли наименьшее_число + 1. Таким образом, в основном он ищет число 2 в массиве. Если он находит число 2, он ничего не делает, пока int i не станет больше размера (длины) массива. Как только i превышает размер массива, int i сбрасывается до 0 и начинает поиск числа в массиве, равного 2 + 1 (также известного как 3). Таким образом, он повторяет процесс и пытается найти число 3.

Zoey Malkov 02.05.2018 13:58

@Shubham Если он не находит номер, он выводит его, а затем, когда int i больше размера массива, он сбрасывает int i в 0

Zoey Malkov 02.05.2018 13:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
299
4

Ответы 4

Вы делаете много вещей, которых я не понимаю. В любом случае, вот быстрая попытка:

static void print_with_missing(const int *array, size_t length)
{
    int last = *array;
    printf("%d", last);
    for (size_t i = 1; i < length;)
    {
        while (array[i] != last + 1)
        {
            printf(" %d", ++last);
        }
        printf(" %d", array[i]);
        last = array[i++];
    }
}

при вызове с вашим образцом массива ({ 1, 2, 5, 7, 9 }) вывод будет:

1 2 3 4 5 6 7 8 9

Примечание: для этого требуется, чтобы ввод был отсортирован, что, кажется, имеет смысл. Если вы не хотите раскрывать это, просто вызовите qsort() сначала внутри функции, конечно.

Когда у вас возникли проблемы с логикой, лучше просто пройтись по ней строка за строкой и посмотреть, что произойдет. Я не совсем понимаю, что вы пытаетесь сделать в цикле, поэтому давайте рассмотрим его блок за блоком и представим, что мы используем 1, 2, 5, 7, 9 в качестве входных данных.

while(start_num <= big_num_answer) {

Довольно просто. Цикл while продолжается, пока start_num меньше или равен наибольшему числу. start_num в данном случае равен 1.

if (numbers[i] == start_num + 1) {
    start_num += 1;
    has_been_used = 1;
}

i равен 0, поэтому эта строка превращается в if (1 == 2). Это пропущено.

else if (i >= length && has_been_used == 0) 
{
    printf("%d", start_num + 1);
}

Это эквивалентно if (0> = 5 AND 0 = 0). Он пропускается, и числа не выводятся.

i++;
if (i > length) {
    i = 0;
}

i теперь равен 1. Давайте снова пройдемся по циклу.

if (numbers[i] == start_num + 1) {
    start_num += 1;
    has_been_used = 1;
}

Преобразуется в if (2 == 2). Итак, теперь start_num = 2 и has_been_used = 1.

else if (i >= length && has_been_used == 0) 
{
    printf("%d", start_num + 1);
}

Блок else полностью пропускается, поскольку выполнено другое условие. И этот блок никогда не будет обработан снова, потому что has_been_used было установлено в 1, и у вас нет кода, который устанавливает has_been_used обратно в 0. Поскольку мы уже прошли через это, мы можем увидеть по крайней мере одну причину, по которой код ничего не выводит.

Вот еще одна не слишком сложная идея сделать это, не требуя отсортированного ввода, но обеспечивая отсортированный вывод:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int numbers[1024];
int max = INT_MIN;
int min = INT_MAX;
size_t n;

int main(void) {
    while (n < 1024)
    {
        // use something better then scanf for "production quality" code
        if (scanf("%d", numbers + n++) != 1) break;
        if (numbers[n-1] > max) max = numbers[n-1];
        if (numbers[n-1] < min) min = numbers[n-1];
    }
    if (max > min && max - min)
    {
        size_t rangesize = max - min - 1;

        // use an array of "markers" for the numbers present in the input
        char *used = calloc(1, rangesize);
        if (!used) return 1;

        // set the markers
        for (size_t i = 0; i < n; ++i)
        {
            if (numbers[i] > min && numbers[i] < max)
            {
                used[numbers[i]-min-1] = 1;
            }
        }

        // and use them for output
        for (size_t i = 0; i < rangesize; ++i)
        {
            if (!used[i])
            {
                printf("%d ", (int)i + min + 1);
            }
        }

        puts("");
        free(used);
    }
}

онлайн-демонстрация

Давайте разберем это:

int start_num = small_num_answer;
while(start_num <= big_num_answer) {

вы хотите перейти от наименьшего к наибольшему числу, пока все хорошо.

    if (numbers[i] == start_num + 1) {

здесь начинается проблема. Я не совсем уверен, но я думаю, вы хотите проверить, есть ли следующее число также в массиве, но вы проверяете только numbers[i], а не все элементы numbers.

        start_num += 1;
        has_been_used = 1;

Если текущее число есть, вы увеличиваете целое число для поиска на единицу. И установите флаг, что он есть в массиве. Но вы никогда не сбрасываете это значение. Так что это всегда будет 1.

    } else if (i >= length && has_been_used == 0) {
        printf("%d", start_num + 1);
    }

здесь вы проверяете, находится ли массив все еще в границах (слишком поздно, поскольку вы использовали numbers[i] без проверки раньше. И проверьте (не работает) флаг, было ли число на входе.

    i++;
    if (i > length) {
        i = 0;
    }
}

Наконец, вы проверяете, что i не больше, чем length, что является хорошей идеей, но i = length уже выходит за рамки, поскольку мы начинаем считать с 0.


Я пытаюсь дать вам что-то в духе вашего подхода, но вам понадобится второй цикл для итерации i по всему массиву.

while(start_num < big_num_answer) {

  for(i = 0; i < length; i++){ //iterate though the whole array

    if (numbers[i] == start_num + 1) {
        has_been_used = 1;
    }
  }

  if (has_been_used == 0){
    printf("%d", start_num + 1); //print if not found
  }

  has_been_used = 0; // reset flag
  start_num++; // next elelemt
}

Другие вопросы по теме