C - Бесконечный процесс в функции. Найдите элемент большинства с помощью метода «разделяй и властвуй».

как упоминалось в заголовке, моя функция не заканчивается хорошо. Я пытаюсь сделать следующее: «Реализовать с помощью метода DC функцию, которая имеет этот интерфейс:

  • Возвращает основной элемент заданной последовательности, если он существует

  • ПАРАМЕТРЫ

  • sequence Действительный указатель на массив элементов
  • sequenceLength Размер массива *
  • ВОЗВРАТ
  • element Указатель на один элемент, соответствующий большинству
  • элемент или NULL, если такого элемента не существует

const Element getMajElDC(const Element* const * sequence, size_t sequenceLength); "

На самом деле, я только что попытался реализовать это решение: http://www.ece.northwestern.edu/~dda902/336/hw4-sol.pdf

И вот мой способ сделать это:

const Element* getMajElDC(const Element* const * sequence,    size_t,sequenceLength){
printf("1\n");

const Element* element_tmp_right;
const Element* element_tmp_left;
int occurence_left = 0;
int occurence_right = 0;


if (sequenceLength == 1)
    return sequence[1];

int mid = (int)sequenceLength/2;

element_tmp_left = getMajElDC(sequence,mid);

if (sequenceLength%2 == 0) 
    element_tmp_right = getMajElDC(&sequence[mid],mid);
element_tmp_right = getMajElDC(&sequence[mid],mid+1);


if (element_tmp_left == NULL && element_tmp_right != NULL)
    return element_tmp_right;
if (element_tmp_right == NULL && element_tmp_left != NULL)
    return element_tmp_left;


if (element_tmp_right == NULL && element_tmp_left == NULL)
    return NULL;




if (areEqual(element_tmp_left,element_tmp_right))
    return element_tmp_left;



for (int i=0;i<sequenceLength;i++){
    if( areEqual(sequence[i],element_tmp_left))
        occurence_left++;
    if (areEqual(sequence[i],element_tmp_right))
        occurence_right++;
}

if (occurence_left > mid+1)
    return element_tmp_left;
else if (occurence_left > mid+1)
    return element_tmp_left;
else
    return NULL;

}

Когда я пытаюсь запустить его в кодовых блоках, .exe просто перестает работать. Как если бы функция была бесконечной. Вот почему я разместил printf в начале: я хотел посмотреть, сколько раз «1» появится в окнах приложения, и это появляется так много раз, что все сходит с ума.

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

Я действительно потерял свое плохое знание C, кто-нибудь видит, в чем проблема?

Ps: функция areEqual() - это просто заданная функция, вот ее реализация, но в ней нет ничего особенного:

bool areEqual(const Element* a, const Element* b)
{
    return a->value == b->value;
}

с

struct element_t
{
    int value;
};

typedef struct element_t Element;

Чтобы закончить мой вопрос, я заранее сообщаю вам, что мне жаль, если важная информация отсутствует: я впервые использую этот веб-сайт, пожалуйста, будьте снисходительны!


person Michael Jacquemart    schedule 01.08.2015    source источник
comment
Кажется, что вы не выполняете рекурсию должным образом, ваше конечное условие никогда не выполняется. Попробуйте просмотреть код в отладчике, строка за строкой, переходя к рекурсивным вызовам, чтобы увидеть, что происходит на самом деле. Вероятно, это будет утомительно и займет много времени, но это все еще часть работы программиста, поэтому вам тоже нужно этому научиться.   -  person Some programmer dude    schedule 01.08.2015
comment
Я вижу проблему в том, что не пытаюсь отладить этот код пошагово (по крайней мере, согласно вашему подробному описанию).   -  person barak manos    schedule 01.08.2015
comment
Я хотел бы добавить, что извиняться заранее может быть контрпродуктивно, пользователи могут видеть, что вы новичок, и все должны исходить из доброй воли.   -  person Andras Deak    schedule 01.08.2015


Ответы (2)


Вы должны использовать отладчик, он сразу покажет вам, в чем проблема. Кстати, посмотрите поближе этот код:

if (sequenceLength == 1)
    return sequence[1];

int mid = (int)sequenceLength/2;

element_tmp_left = getMajElDC(sequence,mid);

if (sequenceLength%2 == 0) 
    element_tmp_right = getMajElDC(&sequence[mid],mid);
element_tmp_right = getMajElDC(&sequence[mid],mid+1);

Вы закрываете рекурсию, когда sequenceLength == 1, но если getMajElDC была вызвана с sequenceLength=0, она никогда не вернется. Подумайте о том, чтобы изменить:

if (sequenceLength == 1)
    return sequence[1];

to:

if (sequenceLength <= 1)
    return sequence[1];
person Frankie_C    schedule 01.08.2015

рассмотрите этот фрагмент кода:

int mid = (int)sequenceLength/2;

element_tmp_left = getMajElDC(sequence,mid);

if (sequenceLength%2 == 0) 
     element_tmp_right = getMajElDC(&sequence[mid],mid);
element_tmp_right = getMajElDC(&sequence[mid],mid+1);

обратите внимание, что третий вызов getMajElDC всегда вызывается независимо от значения sequenceLength. Я подозреваю, что вы хотели написать это:

if (sequenceLength%2 == 0) 
     element_tmp_right = getMajElDC(&sequence[mid],mid);
else
     element_tmp_right = getMajElDC(&sequence[mid],mid+1);
person thurizas    schedule 01.08.2015