【问题标题】:Circular List Traversal Engine循环列表遍历引擎
【发布时间】:2013-10-18 22:59:54
【问题描述】:

我想以给定的输入顺序遍历循环链表(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 上运行,该Abstract State Machine 仅接受以下函数作为处理输入。我基本上想在遍历时最小化engine_spin_at_gear() 的循环计数。我可能在non-blocking 模式下使用这种疯狂的abstraction 来模拟/虚拟化process-execution 作为engine-spin,测量单位为rpm,但我真的很想要有关调试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;
}

当我在 Linux 上运行程序的 GCC 可执行文件时,我得到以下输出。

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 EngineClass Gearbox,你能给我看一个原型吗?

【问题讨论】:

  • 返回'return Deliver(base(_init_cycle0));'在 engine_spin_at_gear 内的 while 循环内看起来很可疑。它总是会在第一次通过循环时返回。
  • @CharlieBurns 即使我将上面更改为return deliver(_init_cycle0),输出也保持不变。奇怪!!
  • 将结束时 } 移动到 shift_gear(_init_cycle0); 之后而不是它所在的位置。
  • @ayyker 输出似乎不受任何此类更改的影响。循环shift_gear(_init_cycle0)对o/p没有影响。
  • 其实也不能幸免。我得到不同的价值观。您的值(在 OP 配置中)如图所示,在我修复索引问题 (MILES-1) 之后,我得到了另一组值,然后在移动 } 之后,我得到了另一组值。请参阅我的图像答案编辑。

标签: c++ c data-structures scheduling circular-dependency


【解决方案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;
}

【讨论】:

    【解决方案2】:

    抛开优化,你的 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); 
    

    是否应该将结束的 while 循环 } 移动到注释中指示的位置? (根据您和查理的观察)如果您将 return 语句保留在那里,您将永远不会超过第一个循环。

    根据代码的微小更改输出更改:
    for (i=0; i&lt;MILES; i++) {更改为for (i=0; i&lt;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。
    猜你喜欢
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 2017-09-17
    • 2017-03-02
    • 1970-01-01
    • 2018-10-26
    • 2013-09-04
    相关资源
    最近更新 更多