Я хочу пересечь круговой связанный список (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
, вы можете показать мне прототип?
Вы упомянули масштабирование для большего количества элементов, вот некоторые части, которые масштабируются до 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;
}
Оптимизация в стороне, у вас есть проблема с 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++) {
После изменения
while (countSession--) {
shift_gear(_init_cycle0);
return deliver(base(_init_cycle0));
}
чтобы:
while (countSession--) {
shift_gear(_init_cycle0);}
return deliver(base(_init_cycle0));
//}
Итак, кажется, что есть какой-то эффект, но я не уверен, как интерпретировать этот вывод. т.е. какое значение имеют эти изменения.
v1
вместе с NULL.