Двигатель обхода кругового списка

0

Я хочу пересечь круговой связанный список (v1->v2->v3) в заданном порядке ввода, скажем, как

{v1,v3,v2,v2,v1,v3,v2,v1,v1,v3,v2,v2,v1,v2,v3}.

Я написал программу ниже в качестве теста для 3 узлов и хотел бы увеличить пошагово для 8, 64, 512, 4096 и т.д. Узлов.

Мое представление о реализации требует, чтобы приведенная ниже программа работала исключительно на Abstract State Machine которая принимает только следующие функции в качестве входных данных для обработки. Я в основном хочу свести к минимуму количество циклов engine_spin_at_gear() во время прохождения. Я могу быть в non-blocking режиме для использования такой безумной abstraction чтобы имитировать/виртуализировать выполнение process-execution в качестве engine-spin с единицей измерения в качестве оборотов в минуту, но мне бы очень понравились предложения по отладке функции engine_spin_at_gear().

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MILES 15

struct package
{
        // ... other members data ...
        struct package *next;
}*v1, *v2, *v3;

int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3};

struct package *base(struct package *_vN)
{
        if (_vN)
                return _vN;
        else
                return NULL;
}

struct package *deliver(struct package *_vNP)
{
        if (_vNP)
                return base(_vNP->next);
        else
                return NULL;
}

void shift_gear(struct package *_feed)
{
        _feed->next = NULL;
}

struct package *engine_spin_at_gear(struct package *_init_cycle0, int countSession)
{
        while (countSession--) {
                shift_gear(_init_cycle0);
                return deliver(base(_init_cycle0));
        }
        return NULL;
}

struct package *journey(struct package *_current_frame, int _start, int _end)
{
        int rpm = (_end > _start)?_end-_start:_start-_end;
        if (rpm)
                return engine_spin_at_gear(_current_frame, rpm);
        else
                return v1;
}

struct package *ignition_phase(int _batteryS, int _chargedL)
{
        return journey(v1, _batteryS, _chargedL);
}


void transmit_in_order(int*input_arr)
{
        struct package *v6;
        int i;

        for (i=0; i<MILES-1; i++) {
                v6 = ignition_phase(input_arr[i], input_arr[i+1]);
                printf("%p\n", v6);
        }
}

int main()
{
        v1 = malloc(sizeof(struct package));
        v2 = malloc(sizeof(struct package));
        v3 = malloc(sizeof(struct package));

        v1->next = v2;
        v2->next = v3;
        v3->next = v1;

        printf("v1=%p\tv2=%p\tv3=%p\n", v1, v2, v3);
        transmit_in_order(input_arr);
        return 0;
}

Я получаю следующий вывод, когда я запускал свою программу GCC для Linux.

v1=0x918b008    v2=0x918b018    v3=0x918b028
(nil)
(nil)
0x918b008
(nil)
(nil)
(nil)
(nil)
0x918b008
(nil)
(nil)
0x918b008
(nil)
(nil)
(nil)
(nil)

Или мне нужно изменить shift_gear()? Могу ли я его оптимизировать, сохраняя при этом коэффициент scalability-factor? Заранее спасибо. Если я хочу поставить все эти функции в C++ качестве Class Engine и Class Gearbox, вы можете показать мне прототип?

Теги:
data-structures
circular-dependency
scheduling

2 ответа

1

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

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

typedef struct package_s
{
    // ... other members data ...
    struct package_s* next;
} package; //being lazy, I avoid typing struct everywhere...

#define HOWMANY (100)
package* v[HOWMANY];

#define MILES 15
int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3};

package*
journey(package* _current_frame, int _start, int _end)
{
    int rpm = (_end > _start) ? (_end-_start) : (_start-_end);
    if (rpm)
        return engine_spin_at_gear(_current_frame, rpm);
    else
        return v[0];
}

package*
ignition_phase(int _batteryS, int _chargedL)
{
    return journey(v[0], _batteryS, _chargedL);
}

И это исправляет адресацию с конца input_arr (возможно, вы хотите обернуть нуль?)

void
transmit_in_order(int*input_arr)
{
    package *v6;
    int i;

    for (i=0; i<MILES-2; i++) {
        v6 = ignition_phase(input_arr[i], input_arr[i+1]);
        printf("%p\n", v6);
    }
}

И главное для настраиваемого числа v[n],

int main()
{
    int ndx;
    for(ndx=0; ndx<HOWMANY; ++ndx)
    {
        v[ndx] = malloc(sizeof(package));
    }

    for(ndx=0; ndx<HOWMANY; ++ndx)
    {
        v[ndx]->next = v[(ndx+1)%HOWMANY];
        printf("v[%d]=%p\t", ndx, v[ndx]);
    }
    printf("\n", ndx, v[ndx]);

    transmit_in_order(input_arr);
    return 0;
}
1

Оптимизация в стороне, у вас есть проблема с input_arr:

int input_arr[MILES] = {1,3,2,2,1,3,2,1,1,3,2,2,1,2,3}; //has 15 elements   

В то время как для следующего цикла требуется 16:

for (i=0; i<MILES-1; i++) { //[edited] so i goes from 0 to 13
        v6 = ignition_phase(input_arr[i], input_arr[i+1]);  //otherwise, i goes to 14, +1 == 15 - 1 too big
        printf("%p\n", v6);
}

Либо создайте больший массив, либо остановите инкремент цикла 1 раньше.

Относительно этого кода:

struct package *engine_spin_at_gear(struct package *_init_cycle0, int countSession)
{
        while (countSession--) {
                shift_gear(_init_cycle0);  // }
                return deliver(base(_init_cycle0));
        }
        return NULL;
}  //move this one to after shift_gear(_init_cycle0); 

Если закрытие во время цикла } перемещается туда, где указано в комментариях? (за ваше наблюдение и наблюдение Чарли) Если вы сохраните выражение о возвращении там, вы никогда не пройдёте мимо первого цикла.

Выход изменяется в соответствии с незначительными изменениями кода:
После изменения для for (i=0; i<MILES; i++) { to for (i=0; i<MILES-1; i++) {
Изображение 174551

После изменения

while (countSession--) {
        shift_gear(_init_cycle0);
        return deliver(base(_init_cycle0));
}

чтобы:

while (countSession--) {
        shift_gear(_init_cycle0);}
        return deliver(base(_init_cycle0));

//}

Изображение 174551

Итак, кажется, что есть какой-то эффект, но я не уверен, как интерпретировать этот вывод. т.е. какое значение имеют эти изменения.

  • 0
    Спасибо за указание, я отредактировал вопрос.
  • 0
    Изменены только значения указателя, но при этом на выходе отображаются только значения узла v1 вместе с NULL.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню