1

教育目的で作成している二重リンクリストプログラムで構文上の問題が発生しています。ヘッダーファイルに構造体を作成しました。メインプログラムは問題ないようですが、.cppファイルに関数を実装すると非常に困難になります。リストにレコードを挿入するための3つのケースを見分けるのに苦労しています。具体的には、メモリの割り当て、リストの先頭と末尾の初期化、およびステートメントの順序は、リストに追加するレコードのコピーを渡すのと同様に、私を混乱させます。

私のヘッダーファイルは次のとおりです。

struct rec
{
   char * id;
   char firstname[15];
   char lastname[15];
   struct rec* prev;
   struct rec* next;
};


int AddItem ( rec r );
int DeleteItem ( char* delid );
void PrintList ( int order );

難しさがある私の.cppファイルは次のとおりです。

#include <iostream>
#include "list.h"
#include <string.h>
using namespace std;

// These pointers refer to the head and tail of the list.
rec* first = NULL;
rec* last = NULL;

int AddItem( Rec r )
{

   rec* newRecEntry;
   rec* current = NULL;
   rec* previous = NULL;

   // Check for duplicate id
   current = first;
   while (current)
   {
     if( strcmp(current -> id, r.id) == 0)
      {
         return 0;
      }
     else
      // Create a new node
      {
         newRecEntry = new Rec;
         newRecEntry->id = new char[strlen(r.id)+1];
         strcpy(newRecEntry->id, r.id);
         strcpy(newRecEntry->firstname,r.firstname);
         strcpy(newRecEntry->lastname,r.lastname);
         newRecEntry->next = NULL;
         newRecEntry->prev = NULL;
      }
      // Find the appropriate position for the node and insert accordingly
      // Check to see if the list is empty
      if (first == NULL)
      {
         first = newRecEntry;
         last = newRecEntry;
      }
      else if ( r.lastname>last.lastname)
      {




      else
      {

   return 0;
}

/*int DeleteItem(char* ID)

リストの最初、途中、最後に挿入できるはずです。IDに基づいてリストからアイテムを削除し、ユーザー入力に基づいて昇順または降順でリストを印刷しますが、最初に、リストへのアイテムの追加を処理したいと思います。私の関数定義は次のとおりで、いくつかのエラーも含まれています

lists.cpp

#include <iostream>
#include "list.h"
#include <string.h>
using namespace std;

// These pointers refer to the head and tail of the list.
   rec* first = NULL;
   rec* last = NULL;

int AddItem( Rec r )
{

   rec* newRecEntry;
   rec* current = NULL;
   rec* previous = NULL;

   // Check for duplicate id
   current = first;
   while (current)
   {
     if( strcmp(current -> id, r.id) == 0)
      {
         return 0;
      }
     else
     // Create a new node
      {
         newRecEntry = new Rec;
         newRecEntry->id = new char[strlen(r.id)+1];
         strcpy(newRecEntry->id, r.id);
         strcpy(newRecEntry->firstname,r.firstname);
         strcpy(newRecEntry->lastname,r.lastname);
         newRecEntry->next = NULL;
         newRecEntry->prev = NULL;
      }
      // Find the appropriate position for the node and insert accordingly
      // Check to see if the list is empty
      if (first == NULL)
      {
         first = newRecEntry;
         last = newRecEntry;
      }
      else if ( r.lastname>last.lastname)
      {




      else
      {

   return 0;
}

/*int DeleteItem(char* ID)
{
   rec
}
*/



/*void printList(int order)
{
loop
 {
   cout << ptr -> Id << " ";
   cout << ptr -> firstname << " ";
   cout << ptr -> lastname << " ";
   cout << ptr -> prev << " ";  // address of previous
   cout <<  ptr << " ";   // address of item
   cout << ptr -> next << " ";  //  address of next item
 }

}

主なものは次のとおりです。

#include <iostream>
#include "list.h"
#include <string.h>  // <string>

using namespace std;

void main (void)
{
   int choice, printorder;
   char idbuffer[100];
   rec r;


do
{
  cout << "Enter your choice 1 Add, 2 Delete, 3 Print, 0 quit "<<endl;
  cin >> choice;

   switch ( choice )
   {
      case 1:  //AddItem
         cout << "\nEnter ID ";
         cin >> idbuffer;

         r.id = idbuffer;
         cout << "\nFirst Name ";
         cin >> r.firstname;
         cout << "\nLast Name ";
         cin >>  r.lastname;
         if ( AddItem ( r ) )
         {
            cout << "\nSuccess!\n";
         }
         else
         {
            cout << "\nItem failed to be added\n";
         }

         break;
      case 2:  //Delete
         cout << "\nEnter id :";
         cin >> idbuffer;
         if ( DeleteItem ( idbuffer ) )
         {
            cout << "\nDelete OK\n";
         }
         else
         {
            cout << "\nDelete Failed for " << idbuffer;
         }
         break;
      case 3: // Print
        cout << "Enter order 0 - Ascending, 1 - Descending\n";
        cin >> printorder;
        PrintList (printorder);
        break;
      case 0:  // quit
         break;


      default: // bad choice
         break;
   } // end switch

}
while ( choice != 0 );// end do while
}  // end main
4

2 に答える 2

1

と思われるかもしれませんが、この機能でも

int AddItem(Record entry)
{
   Record* newRecordPointer;
   newRecordPointer=new Record;
   strcpy(newRecordPointer->firstName,entry.firstName);
   strcpy(newRecordPointer->lastName,entry.lastName);
   newRecordPointer->ID=new char[strlen(entry.ID)+1];
   strcpy(newRecordPointer->ID, entry.ID);
   return 0;
}

あまりにも多くのことをしようとしています。

リストにアイテムを追加する擬似コードの説明を書きましょう。

  1. 新しいノードを作成する
  2. 提供された値を新しいノードに入力します
  3. 新しいノードリストに追加します

関連する動詞名詞にマークを付けましたが、関数から名詞の 1 つが欠落していることがわかります。リストにアイテムを追加するように求めAddItemています...しかし、作業するリストを与えていません。

また、期待を明確に書き出すことも役立ちます。

  1. AddItemに呼び出されます:
    • 作業するリストが必要です
    • リストコンテナクラスはなく、レコードだけなので、渡す必要がありますRecord
    • 渡されたに新しいアイテムを追加したいとしましょうRecord
  2. afterAddItemが呼び出されます:
    • Record渡したものは何でもNext、新しいノードを指す必要があります
    • 新しいノードPreviousは、渡されたノードを指す必要があります
    • etc. etc. (これらは標準の二重リンク リスト挿入動作です)
  3. 後で注意してください: 空のリストを保存する方法については説明していません
    • 循環リストの場合、空のリストはとメンバーRecordがそれ自体を指すNextPrevious
    • 線形の場合、代わりに両方とも NULL になる可能性があります
    • NULL ポインターである可能性がありますが、最初のノードを空のリストに追加するには、さらに労力が必要です

したがって、機能する可能性のある最小限の機能は次のとおりです。

void AddItem(Record *insert_after, Record value)
{
    Record *new_node = CreateRecord();
    CopyRecordValues(new_node, &value);
    AttachAfter(insert_after, new_node);
}

実際の C++ を書いている場合、最初の 2 行は単にコピー コンストラクターを使用できますがRecord *new_node = new Record(value)、開始した場所から慣用的な C++ コードに到達するには、それ以上の変更が必要になることに注意してください。


さて、それを考えると、あなたはできますか:

  • これら3つの機能を実装しますか?(CreateRecordそしてCopyRecordValues、現在のコードですでに処理されています)
  • 他の操作に相当する疑似コードを書き、それを自分で翻訳しますか?
于 2013-03-07T18:48:32.783 に答える
0

これを変更してみてください:

int AddItem(Record entry);

これに:

Record* AddItem(Record entry, Record *insertion_point = NULL );

insertion_pointがの場合、が新しいリストの始まりであるNULLと見なすことができます。Record

Nextこれで、Previousポインタを設定し、新しく作成されたノードを返すのに十分な情報が得られました。

于 2013-03-07T18:04:40.330 に答える