2015-02-01 1 views
5

Пожалуйста, обратитесь к this hackerrank challenge, если можете.Найти одиночное целое число в массиве

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

Проблема с этим тестом

9 
4 9 95 93 57 4 57 93 9 

9 является размером массива и ниже является массив

увидеть часть коды подсвечивается // ------

Если я устанавливаю scanf («% d», & n) выше, код int arr [n] работает нормально, но дает ужасные результаты в обратном порядке. Пожалуйста, помогите мне

#include <stdio.h> 

int lonely_integer(int* a, int size); 

int main(){ 
    //n is size of array, i is counter variable 
    int n, i, result; 
    // --------------------- 
    int arr[n]; 
    scanf("%d", &n); 
    // --------------------- 
    printf("%d\n", n); 
    for(i = 0; i < n; i++){ 
     scanf("%d", &arr[i]); 
    } 
    result = lonely_integer(arr, n); 
    printf("%d", result); 
    return 0; 
} 


int lonely_integer(int* a, int size){ 
    int i; 
    int res = 0; 
    for(i = 0; i < size; i++){ 
     res = res^a[i]; 
    } 

    return res; 
} 
+2

Как узнать, насколько велик массив (т. Е. Что такое «n») до инициализации «n»? –

+0

Но почему он работает для 3 тестовых случаев из 4? – piby180

+2

Пожалуйста, просто подумайте об этом сами: 'int arr [n]; scanf ("% d", &n); 'Вы определяете массив размером n и n имеет значение [ничего здесь], а затем вы сканируете размер ... (BTW: Если вам нужно писать комментарии, например:' // n - размер массива, i - переменная-счетчик, тогда ваши имена переменных не имеют достаточного значения, изменяют их на что-то вроде 'counter и size или arraySize') – Rizier123

ответ

1

Вы хотели бы использовать:

#include <stdlib.h> 
/* ... */ 
int *arr; 
scanf("%d", &n); 
arr = malloc(sizeof(int) * n); 

Таким образом, arr получает динамически во время выполнения, поэтому он может быть любого размера, в зависимости от входа n.

Что вы изначально делаете (т.е. объявляя arr[n] после получать n через зсапЕ: scanf("%d", &n); int arr[n];) не является хорошей идеей, потому что она использует массивы переменной длины, особенность C, что не является обязательным в последнем C стандарт.

Вы видите, arr получает создан во время компиляции, и вы обычно можно только инициализировать его константным выражением, известным во время компиляции, что n, переменная получила в качестве пользовательского ввода, очевидно, не является. Массивы переменной длины являются признаком языка, который в основном позволяет обойти это правило, то есть они позволяют инициализировать массив длиной, не известной во время компиляции. Он был стандартизован в C99, но был указан как "optional" с C11.

Что вы делали после этого (int arr[n]; scanf("%d", &n);) совершенно нелогично, потому что, ну, вы объявляете arr как массив целых чисел nперед тем вы получаете значение n в качестве входных данных пользователя, и, ну, знаете, его значение. Он печатает мусор, потому что n изначально инициализирован на неопределенное значение «мусора», а это то, что ваш размер VLA становится, когда вы объявляете его:

int arr[n]; //n is garbage at this point, you have no idea how large arr will be! 
scanf("%d", &n); //you got the value of n that you needed, but too late, alas! 
1

Диапазон n дается в вопросе 1 <= N < 100 который мал и a variable length array.Но вы делаете неправильно здесь

int arr[n]; // n is uninitialized. Its value is indeterminate. 
scanf("%d", &n); 

Вы должны инициализировать n перед его использованием в качестве размера массива

scanf("%d", &n); 
int arr[n]; 
+0

Это мой вопрос. Почему это работает наоборот, то есть когда мы помещаем scanf выше. Во время компиляции мы также не знаем n в этом случае. – piby180

+0

Читайте о массивах переменной длины. – haccks

+0

Спасибо! Раньше я об этом не знал. – piby180

0

расПредеЛение массив с неинициализированной переменной, приведет к непредсказуемому поведению и компилятор выдаст предупреждение «переменная, используемая неинициализированной в этой функции»

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

int data_size; 
int *data_array; 
scanf("%d", &data_size); 
data_array = (int*)calloc(data_size,sizeof(int)); 
/* 
. 
*/ 
// Free the memory at the end 
free(data_array); 
data_array = NULL; 

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

#define DATA_SIZE 9 

или установить макрос во время компиляции кода

gcc test.c -o test -DDATA_SIZE=9 -Wall 
+0

Он компилирует с компилятором, совместимым с C99, по-видимому, поэтому его массив рассматривается как VLA. – Mints97

+0

Да Шридхар, calloc будет лучшим вариантом здесь. И спасибо за ваш трюк. Это что-то новое, чему можно научиться сегодня. – piby180

0

Значение «п» должен быть определен до его использования. Например, вы используете

int arr [n];

перед чтением значения «n». Таким образом, компилятор не знает, сколько количество элементов присутствует в массиве «n», может быть значением мусора. Как много объема памяти он должен выделять массиву.

поэтому вы должны прочитать значение 'n' перед использованием его определения массива.

 Смежные вопросы

  • Нет связанных вопросов^_^