0

私は次の配列構造(リンクリスト)を持っています:

    struct str_pair   
     {  
       char ip  [50] ;  
       char uri [50] ;  
       str_pair *next ;  
     } ;

str_pair *item;

私は新しいアイテムを作成することを知っています、私は使用する必要があります

item = new str_pair;

ただし、配列をループして特定の項目を削除できるようにする必要があります。ループ部分をソートしました。しかし、構造体の配列から項目を削除するにはどうすればよいでしょうか?

4

5 に答える 5

5

あなたが示したのは、の配列ではなく、(タイプの)配列を含むstructリンクされたリストです。structchar


配列はstruct次のようになります。

str_pair array_of_structs[10];
    // or:
str_pair* dynamically_allocated_array_of_structs = new str_pair[10];

実際にこのようなものがある場合はdelete、配列から項目を 1 つにする必要はありません。次のように配列を初期化したとしましょう。

str_pair* array_of_structs = new str_pair[10];

次に、以下を使用して配列全体 (すべての項目を含む) を削除します。

delete[] array_of_structs;

繰り返しますが、 ;deleteで割り当てられた配列内の項目を 1 つにすることはできません。アレイ全体new[]で a を実行します。delete[]


一方、「のリンクされたリストstruct」と言うつもりなら、通常、次のようにアイテムを削除します。

str_pair* previous_item = ...;
str_pair* item_to_delete = previous_item->next;

if (item_to_delete != 0)
{
    previous_item->next = item_to_delete->next;  // make the list "skip" one item
    delete item_to_delete;                       // and delete the skipped item
}

または、英語で: 削除する項目 ( B ) の前にある項目 ( A ) を見つけ、Aの」ポインターを調整して、 Bがリストでスキップされるようにし、 B を削除します

特殊なケース、つまりリストから削除するアイテムが最初のアイテムまたは最後のアイテムである場合には注意が必要です。リストの最初の項目を削除したい場合、上記のコードは十分ではありませんprevious_item。この場合、リストの最初の要素へのポインターを 2 番目の要素に変更する必要があります。


あなたのコード:

void deleteitem(char *uri)
{
    str_pair *itemtodelete;
    curr = head;

    while (curr->next != NULL) {
    if ((strcmp(curr->uri, uri)) == 0) {
        itemtodelete = curr;
        curr = itemtodelete->next;
        delete itemtodelete;

        curr = head;
        return;
    }

    curr = curr->next;
    }
}

ここでいくつかのことが間違っています:

  • headnull の場合、テストcurr->next != NULLによってセグメンテーション違反が発生します。(null ポインターを逆参照してはいけません!)

  • リストからアイテムを削除するためのコードは完全に間違っています。最悪なのは、前の項目の次のポインターを変更せずにノードを削除することです。したがって、前のアイテムは、もう存在しないアイテムを参照します。

  • 詳細:ステートメントcurr = head;の前では、return何も役に立ちません。

推奨コード:

2 つのステップで実行します。1 つの関数は、アタッチされた を介して削除するノードを検索し、uriもう 1 つの関数はノードを削除します。以下のコードよりもうまく分離できますが、出発点にする必要があります。

str_pair* finditemwithuri(char* uri)
{
    str_pair* current = head;
    while (current)
    {
        if (strcmp(current->uri, uri) == 0) return current;
        current = current->next;
    }
    return 0;
}

void deleteitem(char* uri)
{
    // find linked list node with that uri; abort if uri not in list
    str_pair* itemtodelete = finditemwithuri(uri);
    if (!itemtodelete) return;

    // special case: node to be deleted is the list's head
    if (itemtodelete == head)
    {
        head = itemtodelete->next;
        delete itemtodelete;
        return;
    }

    // else, iterate over list nodes
    // up to the one preceding the node to be deleted
    str_pair* current = head;
    while (current)
    {
        if (itemtodelete == current->next)
        {
            current->next = itemtodelete->next;
            delete itemtodelete;
            return;
        }
        current = current->next;
    }
}
于 2010-05-02T08:44:21.677 に答える
1

std::list を使用するだけです。このような構成を手動で作成する理由はありません。

http://msdn.microsoft.com/en-us/library/802d66bt(VS.80).aspx

std::list は削除を提供します。

于 2010-05-02T16:44:43.570 に答える
0

話が逸れるかもしれませんが、なぜstd::listライブラリを使用しないのですか?

于 2010-05-02T13:27:11.310 に答える
0

通常の delete キーワードを使用して削除できますが、配列の他のすべてのメンバーがシフトされるわけではありません。この種の動作が必要な場合は、std::vector などを見てください。

于 2010-05-02T08:43:49.120 に答える
0

他の人が指摘したように、これは配列ではなくリンク リストです。リンクされたリストに関する質問に答えるには:

アイテムを挿入するには:

str_pair* p = // iterate over the linked list to your insertion point
str_pair* item = new str_pair;
item->next = p->next;
p->next = item;

str_pairp の後に new を挿入します。

アイテムを削除するには:

str_pair* p = // iterate to just before your deletion point
str_pair* item = p->next;
p->next = p->next->next;
delete item;

これにより、要素が削除されますp

コードでこれを行うには:

void deleteitem(char *uri)
{
    str_pair *previous = NULL;
    curr = head;

    while (curr != NULL) {
        if ((strcmp(curr->uri, uri)) == 0) {

            // modify the previous element to skip over our deleted one
            if (previous)
                previous->next = curr->next;
            else
                head = curr->next;

            // safely delete the element, now that no one points to it
            delete curr;

            curr = head;
            return;
        }

        // always remember our previous element, so we can fix its 'next' pointer
        previous = curr;
        curr = curr->next;
    }
}

より良い add メソッドも必要です。

void additem(char *uri, char *ip)
{
    curr = head;

    // traverse the list until we're at the last item
    while (curr->next != NULL) {
        curr = curr->next;
    }

    // attach a new element to the list
    curr->next = new str_pair;

    // go to that new element
    curr = curr->next;

    // set the values of the new element
    strcpy(curr->ip, ip);
    strcpy(curr->uri, uri);
    curr->next = NULL;

    curr = head;

}
于 2010-05-02T08:54:13.423 に答える