Jak mohu postavit OneTwoThree seznam spojený s minimálním počtem operátorů přiřazení?

hlasů
4

Narazil jsem na tento problém při přípravě na pohovor a zvědavý znát prostě něco jiného způsob, jak to může být písemná. Našel jsem to v http://cslibrary.stanford.edu/103/ a dali problém, jak to je.

Zde je kód pro sestavení seznamu {1,2,3}

struct node* BuildOneTwoThree() {
    struct node* head = NULL;
    struct node* second = NULL;
    struct node* third = NULL;
    head = malloc(sizeof(struct node)); // allocate 3 nodes in the heap
    second = malloc(sizeof(struct node));
    third = malloc(sizeof(struct node));
    head->data = 1; // setup first node
    head->next = second; // note: pointer assignment rule
    second->data = 2; // setup second node
    second->next = third;
    third->data = 3; // setup third link
    third->next = NULL;
    // At this point, the linked list referenced by head
    // matches the list in the drawing.
    return head;
}

O: Zápis kódu s nejmenším počtem úkolů (=), která bude stavět výše uvedené konstrukce paměti. A: To vyžaduje 3 volání malloc (). 3 int přiřazení (=) k nastavení Ints. 4 ukazatel přiřazení k nastavení hlavy a 3 další pole. S trochou šikovnosti a znalosti jazyka C, to vše může být provedeno 7 přiřazení operace (=).

Položena 06/02/2009 v 21:18
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
9

Udělal jsem to s šesti úkolech. Co dostanu?

struct node
{
    int data;
    struct node * next;
};

struct node * build_123()
{
    struct node * first = malloc(sizeof(*first));
    struct node * second = malloc(sizeof(*second));
    struct node * third = malloc(sizeof(*third));

    assert(first && second && third);

    *first = (struct node){ 1, second };
    *second = (struct node){ 2, third };
    *third = (struct node){ 3, NULL };

    return first;
}

Také výkon není příliš užitečné. Kdybych chtěl postavit propojeného seznamu ze známého souboru celých čísel, já bych něco takového:

struct node
{
    int data;
    struct node * next;
};

#define build_list(...) \
    _build_list((sizeof((int []){ __VA_ARGS__ }))/(sizeof(int)), \
    (int []){ __VA_ARGS__ })

struct node * _build_list(size_t count, int values[count])
{
    struct node * next = NULL;

    for(size_t i = count; i--; )
    {
        struct node * current = malloc(sizeof *current);
        assert(current);
        *current = (struct node){ values[i], next };
        next = current;
    }

    return next;
}

Potom můžete vytvořit libovolný seznam s

struct node * list = build_list(1, 2, 3);

Zde je další verze pomocí jediného úkolu, inspirovaný codelogic své odpovědi :

struct node * build_123(void)
{
    struct node * list = malloc(sizeof(struct node [3]));
    return memcpy(
        list,
        (struct node []){ { 1, list + 1 }, { 2, list + 2 }, { 3, NULL } },
        sizeof(struct node [3])
    );
}

Nakonec jsem mírně upraven MSN je řešení - nyní, není úkol vůbec:

struct node
{
    int data;
    struct node * next;
};

struct node * make_node(struct node * new_node, int data, struct node * next)
{
    return memcpy(new_node, &(struct node){ data, next }, sizeof(*new_node));
}

struct node * create_node(int data, struct node * next)
{
    return make_node(malloc(sizeof(struct node)), data, next);
}

struct node * build_123(void)
{
    return create_node(1, create_node(2, create_node(3, NULL)));
}
Odpovězeno 06/02/2009 v 21:37
zdroj uživatelem

hlasů
4
node= malloc
node->data= 1
node->next= malloc
node->next->data= 2
node->next->next= malloc
node->next->next->data= 3
node->next->next->next= NULL

A tady je ten, který to dělá dvěma:

node *make_node(node *new_node, int data, node *next) 
{ new_node->data= data; new_node->next= next; return new_node; }

node *create_node(int data, node *next) 
{ return make_node((node *)malloc(sizeof(node)), data, next); }

node *BuildOneTwoThree(void) 
{ return create_node(1, create_node(2, create_node(3, NULL))); }
Odpovězeno 06/02/2009 v 21:34
zdroj uživatelem

hlasů
3

Můžete rozdělit všechny tři uzly s jedním malloc()volání. Mám podezření, že to je odpověď, co hledají. Při současném snížení počtu úkolů není praktická záležitost, svazování více přídělů do jediné malloc()může zjednodušit správu paměti. Předpokládám, že většina vývojářů starší C by být obeznámeni s touto technikou.

struct node* BuildOneTwoThree() {
    struct node *list = malloc(3 * sizeof(struct node));

    list[0].data = 1;
    list[0].next = list+1;
    list[1].data = 2;
    list[1].next = list+2;
    list[2].data = 3;
    list[2].next = NULL;

    return list;
}
Odpovězeno 06/02/2009 v 22:12
zdroj uživatelem

hlasů
3

Mírnou úpravu Christoph v kódu se 4 úkoly s využitím k tomu, že je to vždy budování 3 uzly:

struct node
{
    int data;
    struct node * next;
};

struct node * build_123()
{
    struct node* head = malloc( sizeof(struct node) * 3);
    *head     = (struct node){ 1, head+1 };
    *(head+1) = (struct node){ 2, head+2 };
    *(head+2) = (struct node){ 3, NULL };
    return head;
}

EDIT: Technicky (z hlediska montáže), za použití struct inicializátor pravděpodobně za následek alespoň 2 úkolů, jeden pro každého člena. Takže se zdá, jen jako by to 4 úkoly v C kód, když ho fakt, že je 7 nebo více. Podobně, rekurzivní řešení MSN bude také mít za následek více než 2 úkoly, které je abstrahovaných v rekurze (nepočítaje další úkoly, které budou pravděpodobně dochází v důsledku funkce nad hlavou, za předpokladu, že není inline).


UPRAVIT:

Ok, přidělovány ve frontě na celém světě, tudíž žádné úkoly, a to i při montáži. Terrible kód, pokud souvisí seznamy (nebo cokoli jiného) jde, ale ať :-)

struct node
{
  int data;
  struct node * next;
};

struct node g_nodes[3] = { {1, g_nodes+1}, {2, g_nodes+2}, {3, NULL} };    
struct node * build_123()
{
  return g_nodes;
}
Odpovězeno 06/02/2009 v 22:11
zdroj uživatelem

hlasů
2

Jako nikdo nic o tomto Nebýt C ++, tady je C ++ verze s žádnými úkoly kromě zkušebního předpisu řekl:

#include <iostream>
using namespace std;

struct Node {

    int mVal;
    Node * mNext;

    Node( int v, Node * n ) 
        : mVal( v ), mNext( n ) {}

    ~Node() {
        delete mNext;
    }
};

int main() {

    // build the list
    Node n( 1, new Node( 2, new Node( 3, 0 ) ) );

    // test it
    Node * p = & n;
    while( p ) {
        cout << p->mVal << endl;
        p = p->mNext;
    }

    return 0;
}
Odpovězeno 07/02/2009 v 00:47
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more