• 用一维数组实现栈(C++编程思想 p120)


    1 实现思路

    向栈中插入4个元素后的状态

    执行过程分析:

    2 代码实现

    clib.h 接口定义

     1 typedef struct CStashTag
     2 {
     3     int ele_size;                    //栈中每个元素的占用的字节数 
     4     int capacity;                    //栈的容量,栈当前(不扩展)可容纳的元素的个数
     5     int next;                        //相当于栈指针(标记下一个空位索引),栈中当前元素的个数
     6     unsigned char* storage;            //栈存储空间字符指针,动态分配的字节数组
     7 } CStash;
     8 
     9 void initalize(CStash* s, int size);
    10 void cleanup(CStash* s);
    11 int add(CStash* s, const void* element);
    12 void* fetch(CStash* s, int index);
    13 int count(CStash* s);
    14 void inflate(CStash* s, int increase = 10);

    2 Clib.cpp 函数实现

      1 #include <string>
      2 #include <iostream>
      3 #include <cassert>
      4 #include "clib.h"
      5 
      6 using namespace std;
      7 
      8 void initalize(CStash* s, int sz)
      9 {
     10     s->ele_size = sz;     
     11     s->capacity = 0;  
     12     s->next = 0;
     13     s->storage = 0; 
     14 }
     15 
     16 int add(CStash* s, const void* element)
     17 {
     18     if (s->next  >=  s->capacity)
     19     {
     20         inflate(s);
     21     }
     22     int startBytes = s->next * s->ele_size;
     23     unsigned char* e = (unsigned char*)element;
     24 
     25     for (int i=0; i<s->ele_size; i++)
     26         s->storage[startBytes + i] = e[i];
     27     s->next++;
     28 
     29     return s->next - 1;
     30 }
     31 
     32 //取出索引index处的栈元素
     33 void* fetch(CStash* s, int index)
     34 {
     35     assert(0 <= index);
     36     if (index >= s->next)
     37     {
     38         return 0;
     39     }
     40     return &(s->storage[index * s->ele_size]);
     41 }
     42 
     43 //返回栈中元素的个数
     44 int count(CStash* s)
     45 {
     46     return s->next;
     47 }
     48 
     49 //扩展栈空间,增加increase个元素空间
     50 void inflate(CStash* s, int increase)
     51 {
     52     printf("inflate increase %d
    ", increase);
     53 
     54     assert(increase > 0);
     55 
     56     //原栈长 + 增加的栈元素个数
     57     int newCapacity = s->capacity + increase;
     58     int newBytes = newCapacity * s->ele_size;   //新的栈空间字节数
     59     int oldBytes = s->capacity * s->ele_size;        //旧的栈空间字节数
     60 
     61     unsigned char* b = new unsigned char[newBytes]; //在堆上分配新的栈空间
     62 
     63     if (oldBytes) 
     64     {
     65         //拷贝旧的栈空间的内容到新的栈空间,并释放旧的栈空间
     66         //把旧内存块中的数据拷贝到新分配的内存块
     67         for (int i=0; i<oldBytes; i++)
     68             b[i] = s->storage[i];
     69         delete [] (s->storage); //释放旧的内存块
     70     }
     71 
     72 
     73     s->storage = b; //使栈存储空间字符指针s->storage指向新分配的内存块
     74     s->capacity = newCapacity; //更新栈的容量
     75 }
     76 
     77 
     78 //清理栈存储空间字符指针
     79 void cleanup(CStash* s)
     80 {
     81     if (s->storage != 0)
     82     {
     83         cout<<"freeing storage"<<endl;
     84         delete []s->storage;
     85     }
     86 }
     87 
     88 
     89 int main(int argc, char* argv[])
     90 {
     91 
     92     CStash stash;
     93 
     94     char str1[] = "d1111";
     95     char str2[] = "d2222";
     96     char str3[] = "d3333";
     97     char str4[] = "d4444";
     98 
     99     initalize(&stash, 20);
    100 
    101     add(&stash, str1);
    102     add(&stash, str2);
    103     add(&stash, str3);
    104     add(&stash, str4);
    105 
    106     unsigned char* result = (unsigned char*)fetch(&stash, 2);
    107     printf("fetch result %s
    ", result);
        
         cleanup(&stash);
    108 109 return 0; 110 };


    输出:

    inflate increase 10
    fetch result d3333

    freeing storage

    向栈中存放int型数据测试:

     1 void intTest() 
     2 {
     3     CStash intStash;
     4     
     5     initalize(&intStash, sizeof(int)); //栈中存放int型数据,所以栈元素占用int--4个字节
     6 
     7     int i;
     8     for (i=0; i<20; i++)
     9         add(&intStash, &i);
    10 
    11     for (i=0; i<count(&intStash); i++)
    12         cout<< "fetch(&intStash, " << i << ") = " << *(int *) fetch(&intStash, i) <<endl;
    13     cleanup(&intStash);
    14 }

    输出:

    inflate increase 10
    inflate increase 10
    fetch(&intStash, 0) = 0
    fetch(&intStash, 1) = 1
    fetch(&intStash, 2) = 2
    fetch(&intStash, 3) = 3
    fetch(&intStash, 4) = 4
    fetch(&intStash, 5) = 5
    fetch(&intStash, 6) = 6
    fetch(&intStash, 7) = 7
    fetch(&intStash, 8) = 8
    fetch(&intStash, 9) = 9
    fetch(&intStash, 10) = 10
    fetch(&intStash, 11) = 11
    fetch(&intStash, 12) = 12
    fetch(&intStash, 13) = 13
    fetch(&intStash, 14) = 14
    fetch(&intStash, 15) = 15
    fetch(&intStash, 16) = 16
    fetch(&intStash, 17) = 17
    fetch(&intStash, 18) = 18
    fetch(&intStash, 19) = 19
    freeing storage

    向栈中存放字符串(字符数组指针)测试:

     1 void stringTest()
     2 {
     3     CStash  stringStash;
     4 
     5 
     6     ifstream in;
     7 
     8     
     9     const int bufsize = 80;
    10     initalize(&stringStash, sizeof(char) * bufsize);
    11     in.open("clib.h");
    12     assert(in);
    13 
    14     string line;
    15     while (getline(in, line))
    16     {
    17         add(&stringStash, line.c_str());
    18     }
    19 
    20     char *cp;
    21     int i = 0;
    22     while ((cp = (char *) fetch(&stringStash, i++)) != 0)
    23     {
    24         cout<< "fetch(&stringStash, " << i << ") = " << cp << endl;
    25     }
    26 
    27     cleanup(&stringStash);
    28 }

    输出:

    inflate increase 10
    inflate increase 10
    fetch(&stringStash, 1) = typedef struct CStashTag
    fetch(&stringStash, 2) = {
    fetch(&stringStash, 3) = int ele_size;       //栈中每个元素的占用的字节数
    fetch(&stringStash, 4) = int capacity;       //栈的容量,栈当前(不扩展)可容纳的元素的个数
    fetch(&stringStash, 5) = int next;         //相当于栈指针(标记下一个空位索引),栈中当前元素的个数
    fetch(&stringStash, 6) = unsigned char* storage; //栈存储空间字符指针,动态分配的字节数组
    fetch(&stringStash, 7) = } CStash;
    fetch(&stringStash, 8) =
    fetch(&stringStash, 9) = void initalize(CStash* s, int size);
    fetch(&stringStash, 10) = void cleanup(CStash* s);
    fetch(&stringStash, 11) = int add(CStash* s, const void* element);
    fetch(&stringStash, 12) = void* fetch(CStash* s, int index);
    fetch(&stringStash, 13) = int count(CStash* s);
    fetch(&stringStash, 14) = void inflate(CStash* s, int increase = 10);
    freeing storage

    附C++实现:

    1)Stash.h头文件

     1 #ifndef STASH_H_INCLUDED
     2 #define STASH_H_INCLUDED
     3 
     4 class Stash
     5 {
     6     int ele_size;                    //栈中每个元素的占用的字节数
     7     int capacity;                    //栈的容量,栈当前(不扩展)可容纳的元素的个数
     8     int next;                        //相当于栈指针(标记下一个空位索引),栈中当前元素的个数
     9     unsigned char* storage;            //栈存储空间字符指针,动态分配的字节数组
    10     void inflate(int increase = 10);
    11 
    12 public:
    13     void initalize(int sz);
    14     int add(const void* element);
    15     void* fetch(int index);
    16     int count();
    17     void cleanup();
    18 };
    19 
    20 #endif // STASH_H_INCLUDED

    2)Stash.cpp实现文件

     1 #include "Stash.h"
     2 #include <iostream>
     3 #include <cassert>
     4 
     5 using namespace std;
     6 
     7 void Stash::initalize(int sz)
     8 {
     9     ele_size = sz;
    10     capacity = 0;
    11     next = 0;
    12     storage = 0;
    13 }
    14 
    15 
    16 int Stash::add(const void *element)
    17 {
    18     if (next >= capacity)
    19     {
    20         inflate();
    21     }
    22 
    23     int startBytes = next * ele_size;
    24     unsigned char *e = (unsigned char *) element;
    25 
    26     for (int i=0; i<ele_size; i++)
    27     {
    28         storage[startBytes + i] = e[i];
    29     }
    30     next++;
    31 
    32     return next-1;
    33 }
    34 
    35 void Stash::inflate(int increase)
    36 {
    37     cout << "inflate increase: " << increase << endl;
    38 
    39     assert(increase > 0);
    40 
    41     int newCapacity = capacity + increase;
    42     int newBytes = newCapacity * ele_size;
    43     int oldBytes = capacity * ele_size;
    44 
    45     unsigned char *b = new unsigned char[newBytes];
    46 
    47     if (oldBytes)
    48     {
    49         for (int i=0; i<oldBytes; i++)
    50             b[i] = storage[i];
    51         delete []storage;
    52     }
    53 
    54     storage = b;
    55     capacity = newCapacity;
    56 }
    57 
    58 void* Stash::fetch(int index)
    59 {
    60     assert(index >= 0);
    61     if (index > next)
    62         return 0;
    63     return &(storage[index * ele_size]);
    64 }
    65 
    66 int Stash::count()
    67 {
    68     return next;
    69 }
    70 
    71 void Stash::cleanup()
    72 {
    73     if (storage != 0)
    74     {
    75         cout << "freeing storage .... " << endl;
    76         delete []storage;
    77     }
    78 }

    3)main.cpp测试类

     1 #include <iostream>
     2 #include <string>
     3 #include <fstream>
     4 #include "Stash.h"
     5 
     6 using namespace std;
     7 
     8 
     9 void intTest()
    10 {
    11     Stash intStash;
    12 
    13     intStash.initalize(sizeof(int)); //栈中存放int型数据,所以栈元素占用int--4个字节
    14 
    15     int i;
    16     for (i=0; i<20; i++)
    17         intStash.add(&i);
    18 
    19     for (i=0; i<intStash.count(); i++)
    20         cout<< "intStash.fetch(" << i << ") = " << *(int *) intStash.fetch(i) <<endl;
    21     intStash.cleanup();
    22 }
    23 
    24 void stringTest()
    25 {
    26     Stash  stringStash;
    27     ifstream in;
    28     const int bufsize = 80;
    29 
    30     stringStash.initalize(sizeof(char) * bufsize);
    31     in.open("Stash.h");
    32 
    33     string line;
    34     while (getline(in, line))
    35     {
    36         stringStash.add(line.c_str());
    37     }
    38 
    39     char *cp;
    40     int i = 0;
    41     while ((cp = (char *) stringStash.fetch(i++)) != 0)
    42     {
    43         cout<< "stringStash.fetch(" << i << ") = " << cp << endl;
    44     }
    45 
    46     stringStash.cleanup();
    47 }
    48 
    49 
    50 int main()
    51 {
    52 
    53     //intTest();
    54     stringTest();
    55 
    56     return 0;
    57 }
  • 相关阅读:
    docker-compose常用命令-详解
    Docker的4种网络模式
    docker-compose常用命令-详解
    windows 10安装nodejs(npm,cnpm),在谷歌浏览器上安装vue开发者工具 vue Devtools
    @Pointcut注解
    leetcode做题总结
    win10右键添加在此处打开powershell
    怎样从 bat 批处理文件调用 PowerShell 脚本
    Android Google Play app signing 最终完美解决方式
    526. Beautiful Arrangement
  • 原文地址:https://www.cnblogs.com/asnjudy/p/4558959.html
Copyright © 2020-2023  润新知