字符串序列修改的任务

时间:2015-04-07 18:22:57

标签: c++ string long-integer unsigned-integer

下面是抽象数据类型字符串序列的C ++类定义:

class Sequence
{
  public:
    Sequence();    // Create an empty sequence.
    bool empty();  // Return true if the sequence is empty, otherwise false.
    int size();    // Return the number of items in the sequence.
    bool insert(int pos, const std::string& value);
       // Insert value into the sequence so that it becomes the item at
       // position pos.  The original item at position pos and those that
       // follow it end up at positions one higher than they were at before.
       // Return true if 0 <= pos <= size() and the value could be
       // inserted.  (It might not be, if the sequence has a fixed capacity,
       // e.g., because it's implemented using a fixed-size array.) Otherwise,
       // leave the sequence unchanged and return false.  Notice that
       // if pos is equal to size(), the value is inserted at the end.

    bool insert(const std::string& value);
       // Let p be the smallest integer such that value <= the item at
       // position p in the sequence; if no such item exists (i.e.,
       // value > all items in the sequence), let p be size().  Insert
       // value into the sequence so that it becomes the item at position
       // p.  The original item at position p and those that follow it end
       // up at positions one higher than before.  Return true if the value
       // was actually inserted.  Return false if the value was not inserted
       // (perhaps because the sequence has a fixed capacity and is full).

    bool erase(int pos);
       // If 0 <= pos < size(), remove the item at position pos from
       // the sequence (so that all items that followed this item end up at
       // positions one lower than they were at before), and return true.
       // Otherwise, leave the sequence unchanged and return false.

    int remove(const std::string& value);
       // Erase all items from the sequence that == value.  Return the
       // number of items removed (which will be 0 if no item == value).

    bool get(int pos, std::string& value);
       // If 0 <= pos < size(), copy into value the item at position pos
       // in the sequence and return true.  Otherwise, leave value unchanged
       // and return false.

    bool set(int pos, const std::string& value);
      // If 0 <= pos < size(), replace the item at position pos in the
      // sequence with value and return true.  Otherwise, leave the sequence
      // unchanged and return false.

    int find(const std::string& value);
      // Let p be the smallest integer such that value == the item at
      // position p in the sequence; if no such item exists, let p be -1.
      // Return p.

    void swap(Sequence& other);
      // Exchange the contents of this sequence with the other one.
};

这是一个字符串序列的删除函数示例:

Sequence s;
s.insert(0, "a");
s.insert(1, "b");
s.insert(2, "c");
s.insert(3, "b");
s.insert(4, "e");
assert(s.remove("b") == 2);
assert(s.size() == 3);
string x;
assert(s.get(0, x)  &&  x == "a");
assert(s.get(1, x)  &&  x == "c");
assert(s.get(2, x)  &&  x == "e");

这是交换功能的一个例子:

Sequence s1;
s1.insert(0, "paratha");
s1.insert(0, "focaccia");
Sequence s2;
s2.insert(0, "roti");
s1.swap(s2);
assert(s1.size() == 1  &&  s1.find("roti") == 0  &&  s2.size() == 2  &&
            s2.find("focaccia") == 0  &&  s2.find("paratha") == 1);
  1. Sequence类的哪些成员函数应该是const成员函数(因为它们不修改Sequence)?我们必须相应地更改班级声明。

  2. 如上所述,Sequence类允许客户端使用仅包含 std :: strings 的序列。如果我们要修改类以包含其他类型的项目,例如仅整理或仅双精选,则必须在许多地方进行更改。修改您在上一个问题中生成的类定义,以便在原始定义使用 std :: string 的所有值中使用 typedef - 定义类型。使用 typedef

    的示例
    typedef int Number;  // define Number as a synonym for int
    int main()
    {
         Number total = 0;
         Number x;
         while (cin >> x)
         total += x;
         cout << total << endl;
    }
    
  3. 修改此代码以对long或double的序列求和。只需要在一个地方进行更改:typedef。要求是使用与 typedef 定义的名称相同的同义词:名称 ItemType ,具有该拼写和大小写。

    1. 现在已经定义了一个序列类的接口,其中可以轻松更改项类型,实现类及其所有成员函数,使得序列中的项包含在数据中作为数组的成员。序列必须能够容纳最多DEFAULT_MAX_ITEMS项,其中

       const int DEFAULT_MAX_ITEMS = 200;
      
    2. 必须针对无符号长整数序列测试该类。类定义和内联函数定义(如果有)必须包含在名为 Sequence.h 的文件中,非内联函数定义(如果有)必须包含在名为 Sequence.cpp。

      可以根据需要添加任何私有数据成员或私有成员函数,但不必在上一个问题中定义的公共接口中添加或删除任何内容,也不允许更改函数签名。唯一的例外是:允许添加带有签名 void dump()const 的公共成员函数。该函数的目的是为了测试目的,它能够调用它来打印有关序列的信息。如果不需要,不必添加此功能,但如果添加,则不得对序列进行任何更改。转储功能不得写入 cout ,但允许写入 cerr

      Sequence类的实现必须使编译器生成的析构函数,复制构造函数和赋值运算符做正确的事情。必须编写名为 testSequence.cpp 的测试程序,以确保Sequence类实现正常工作。这是一个可能的(不完整的)测试程序:

      #include "Sequence.h"
      #include <iostream>
      #include <cassert>
      using namespace std;
      
      int main()
      {
          Sequence s;
          assert(s.empty());
          assert(s.find(42) == -1);
          s.insert(42);
          assert(s.size() == 1  &&  s.find(42) == 0);
          cout << "Passed all tests" << endl;
      }
      

      现在(仅)必须更改Sequence.h中的typedef,以便Sequence现在包含 std :: strings 。除非必要时添加 #include ,否则不得对 Sequence.h Sequence.cpp 进行其他更改。可以验证实现是否正确构建并且正常使用此替代主程序(这不是对正确性的完整测试):

      #include "Sequence.h"
      #include <iostream>
      #include <cassert>
      using namespace std;
      
      int main()
      {
          Sequence s;
          assert(s.empty());
          assert(s.find("laobing") == -1);
          s.insert("laobing");
          assert(s.size() == 1  &&  s.find("laobing") == 0);
          cout << "Passed all tests" << endl;
      }
      

      Sequence.h Sequence.cpp 代码可能需要在彼此之间翻转才能修复几次,以便对这些文件进行必要的更改更改序列的项类型是 Sequence.h 中的typedef。 (当任务完成后,请使用它们以使项目类型为无符号长。)

      Sequence.h 中的typedef语句外,unsigned和long一词不得出现在 Sequence.h Sequence.cpp 中。除 #include 的上下文外,单词字符串不得出现在 Sequence.h Sequence.cpp 中。

      (实施说明:交换功能可在不创建任何附加阵列或附加序列的情况下实现)

      1. 现在该类已经实现了,必须编写一些使用它的客户端代码。实现以下使用无符号long序列的类:

         #include "Sequence.h"
         #include <limits>
        
          const unsigned long NO_SCORE = std::numeric_limits<unsigned long>::max();
          class ScoreList
          {
            public:
              ScoreList();       // Create an empty score list.
              bool add(unsigned long score);
                // If the score is valid (a value from 0 to 100) and the score list
                // has room for it, add it to the score list and return true.
                // Otherwise, leave the score list unchanged and return false.
        
              bool remove(unsigned long score);
                // Remove one instance of the specified score from the score list.
                // Return true if a score was removed; otherwise false.
        
              int size() const;  // Return the number of scores in the list.
        
              unsigned long minimum() const;
                // Return the lowest score in the score list.  If the list is
                // empty, return NO_SCORE.
        
              unsigned long maximum() const;
                // Return the highest score in the score list.  If the list is
                // empty, return NO_SCORE.
        
              private:
                // Some of your code goes here.
           };
        
      2. ScoreList实现必须使用Sequence类型的数据成员,该成员使用typedef ItemType 作为 unsigned long 的同义词。除了更改一行(Sequence.h中的typedef)之外,不必对为问题3生成的 Sequence.h Sequence.cpp 文件进行更改,因此不会必须将成员函数添加到Sequence类中。每个成员函数添加,删除,大小,最小和最大必须尽可能多地委托他们需要执行的工作,以便对成员函数进行排序。 (换句话说,他们不能自己工作,他们可以要求Sequence成员函数来做。)如果编译器生成的析构函数,复制构造函数和ScoreList的赋值运算符不做正确的事情,它们必须是宣布并实施。构造一个程序来测试ScoreList类。这些文件应命名为 ScoreList.h,ScoreList.cpp和testScoreList.cpp。

        不得出现在 ScoreList.h ScoreList.cpp 中,但是如果需要, ScoreList :: minimum ScoreList :: maximum 的实现。字符[(方括号)和*不得出现在 StudentMultiset.h StudentMultiset.cpp 中,但评论中除外(如果需要)。如果不需要, ScoreList.h ScoreList.cpp 中的无符号长 ItemType 不需要进行任何更改如此。

        1. 现在已经创建了基于数组的序列类型,其大小在编译时是固定的,必须更改实现以使用动态分配的对象数组。必须复制为问题3生成的三个文件,命名新文件newSequence.h,newSequence.cpp和testnewSequence.cpp。必须通过添加另一个构造函数或修改现有构造函数来更新这些文件,以便客户端可以执行以下操作:

            Sequence a(1000);   // a can hold at most 1000 items
            Sequence b(5);      // b can hold at most 5 items
            Sequence c;         // b can hold at most DEFAULT_MAX_ITEMS items
            ItemType v = some value of the appropriate type;
          
              // No failures inserting 5 items into b
            for (int k = 0; k < 5; k++)
                 assert(b.insert(v));
          
              // Failure if we try to insert a sixth item into b
            assert(!b.insert(v));
          
              // When two Sequences' contents are swapped, their capacities are
              // swapped as well:
            a.swap(b);
            assert(!a.insert(v)  &&  b.insert(v));
          
        2. 由于编译器生成的析构函数,复制构造函数和赋值运算符不再正确,它们必须被声明(作为公共成员)并实现。不必对您的类的公共接口进行其他更改。 (允许对私有成员和成员函数的实现进行更改或添加。)必须更改 swap 函数的实现,以便在交换两个序列时执行语句的次数无论序列中有多少项,都是一样的。 (例如,如果 swap 函数导致循环访问序列中的每个项目,则会满足此要求,因为循环的所有迭代执行的语句数量取决于数量序列中的项目。)

          字符[(空方括号)不得出现在 newSequence.h 中(但在 newSequence.cpp 中可以正常使用)。

          必须测试Sequence类的新实现。 (即使文件名为 newSequence.h ,其中定义的类名仍必须序列

          验证ScoreList类是否仍适用于此新版本的Sequence。除了#include&#34; newSequence.h &#34;之外,ScoreList类不需要以任何方式更改或实现。而不是&#34; Sequence.h&#34; 。 (在ScoreList.h和ScoreList.cpp完成之前,请确保所有#includes to&#34; Sequence.h&#34;都已恢复,而不是&#34; newSequence.h&#34;)

          任务#1-5的要求:

          每个头文件 Sequence.h,ScoreList.h和newSequence.h 必须具有适当的包含保护。在要运行和测试的文件中,Sequence.h和newSequence.h中的typedef必须将ItemType定义为unsigned long的同义词。

          如果创建了由 Sequence.h,Sequence.cpp和testSequence.cpp 组成的项目,则必须在Visual C ++下成功构建。

          如果创建了由 Sequence.h,Sequence.cpp,ScoreList.h,ScoreList.cpp和testScoreList.cpp 组成的项目,则必须在Visual C ++下成功构建。

          如果创建了由 newSequence.h,newSequence.cpp和testnewSequence.cpp 组成的项目,则必须在Visual C ++下成功构建。

          如果创建的项目由 newSequence.h,newSequence.cpp和testSequence.cpp 组成,那么在testSequence.cpp中只有 #include&#34; Sequence.h&# 34; 更改为 #include&#34; newSequence.h&#34; ,项目必须在Visual C ++下成功构建。 (如果尝试这样做,请确保在运行 testSequence.h 之前将#include返回更改为&#34; Sequence.h&#34; 。)

          除名称以test开头的文件之外的文件可能包含从cin读取任何内容或将任何内容写入cout的代码,但对于问题5,采用整数参数的构造函数的实现可能会写入消息并退出程序,如果整数是负数。任何文件都可以写入cerr(可能用于调试目的);写入cerr的任何输出都将被忽略。

          Sequence和ScoreList的每个成员函数都必须有一个实现。如果无法正确实现函数,则其实现必须至少成功构建。

          如果将 #include 添加到创建的 Sequence.h ,请更改序列的项类型的typedef以指定 std ::字符串作为项目类型,不对 Sequence.cpp 进行更改,编译 Sequence.cpp ,并将其链接到包含以下内容的文件:

              #include "Sequence.h"
              #include <string>
              #include <iostream>
              #include <cassert>
              using namespace std;
          
              void test()
              {
                  Sequence s;
                  assert(s.insert(0, "lavash"));
                  assert(s.insert(0, "tortilla"));
                  assert(s.size() == 2);
                  ItemType x = "injera";
                  assert(s.get(0, x) && x == "tortilla");
                  assert(s.get(1, x) && x == "lavash");
              }
          
              int main()
              {
                  test();
                  cout << "Passed all tests" << endl;
              }
          

          链接必须成功。当生成的可执行文件运行时,它必须写通过所有测试,而不是 cout ,并正常终止。

          如果成功实现了上述目标,则更改序列项目类型的typedef以指定 unsigned long 作为项目类型而不进行任何其他更改,重新编译序列。 cpp ,并将其链接到包含以下内容的文件:

              #include "Sequence.h"
              #include <iostream>
              #include <cassert>
              using namespace std;
          
              void test()
              {
                  Sequence s;
                  assert(s.insert(0, 10));
                  assert(s.insert(0, 20));
                  assert(s.size() == 2);
                  ItemType x = 999;
                  assert(s.get(0, x) && x == 20);
                  assert(s.get(1, x) && x == 10);
              }
          
              int main()
              {
                  test();
                  cout << "Passed all tests" << endl;
              }
          

          链接必须成功。当生成的可执行文件运行时,它必须写通过所有测试,而不是 cout ,并正常终止。

          如果将 #include 添加到 newSequence.h ,请更改序列的项类型的typedef以指定 std :: string 作为项目类型,不对 newSequence.cpp 进行更改,编译 newSequence.cpp ,并将其链接到包含以下内容的文件:

              #include "newSequence.h"
              #include <string>
              #include <iostream>
              #include <cassert>
              using namespace std;
          
              void test()
              {
                  Sequence s;
                  assert(s.insert(0, "lavash"));
                  assert(s.insert(0, "tortilla"));
                  assert(s.size() == 2);
                  ItemType x = "injera";
                  assert(s.get(0, x) && x == "tortilla");
                  assert(s.get(1, x) && x == "lavash");
              }
          
              int main()
              {
                  test();
                  cout << "Passed all tests" << endl;
              }
          

          链接必须成功。当生成的可执行文件运行时,它必须写通过所有测试,而不是 cout ,并正常终止。

          如果成功实现了上述目标,则更改序列项目类型的typedef以指定 unsigned long 作为项目类型而不进行任何其他更改,重新编译 newSequence。 cpp ,并将其链接到包含

          的文件
              #include "newSequence.h"
              #include <iostream>
              #include <cassert>
              using namespace std;
          
              void test()
              {
                  Sequence s;
                  assert(s.insert(0, 10));
                  assert(s.insert(0, 20));
                  assert(s.size() == 2);
                  ItemType x = 999;
                  assert(s.get(0, x) && x == 20);
                  assert(s.get(1, x) && x == 10);
              }
          
              int main()
              {
                  test();
                  cout << "Passed all tests" << endl;
              }
          

          链接必须成功。当生成的可执行文件运行时,它必须写通过所有测试,而不是 cout ,并正常终止。

0 个答案:

没有答案