Я пытаюсь заполнить недостающие числа из пользовательского ввода (который хранится в массиве. Например, если пользователь вводит 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;
}
}
}
@Someprogrammerdude Потратил около 30 минут на попытки. Я застрял
@ZoeyMalkov Вы можете объяснить свою логику?
@Shubham Он находит наименьшее и наибольшее число из пользовательского ввода (например, 1 и 8). Затем он использует наименьшее число (1) и просматривает массив, чтобы найти, есть ли наименьшее_число + 1. Таким образом, в основном он ищет число 2 в массиве. Если он находит число 2, он ничего не делает, пока int i не станет больше размера (длины) массива. Как только i превышает размер массива, int i сбрасывается до 0 и начинает поиск числа в массиве, равного 2 + 1 (также известного как 3). Таким образом, он повторяет процесс и пытается найти число 3.
@Shubham Если он не находит номер, он выводит его, а затем, когда int i больше размера массива, он сбрасывает int i в 0
Вы делаете много вещей, которых я не понимаю. В любом случае, вот быстрая попытка:
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
}
Вероятно, это идеальное время для узнать, как отлаживать свои программы.