1 实现思路

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

执行过程分析:

2 代码实现

clib.h 接口定义

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

2 Clib.cpp 函数实现

 #include <string>
#include <iostream>
#include <cassert>
#include "clib.h" using namespace std; void initalize(CStash* s, int sz)
{
s->ele_size = sz;
s->capacity = ;
s->next = ;
s->storage = ;
} int add(CStash* s, const void* element)
{
if (s->next >= s->capacity)
{
inflate(s);
}
int startBytes = s->next * s->ele_size;
unsigned char* e = (unsigned char*)element; for (int i=; i<s->ele_size; i++)
s->storage[startBytes + i] = e[i];
s->next++; return s->next - ;
} //取出索引index处的栈元素
void* fetch(CStash* s, int index)
{
assert( <= index);
if (index >= s->next)
{
return ;
}
return &(s->storage[index * s->ele_size]);
} //返回栈中元素的个数
int count(CStash* s)
{
return s->next;
} //扩展栈空间,增加increase个元素空间
void inflate(CStash* s, int increase)
{
printf("inflate increase %d\n", increase); assert(increase > ); //原栈长 + 增加的栈元素个数
int newCapacity = s->capacity + increase;
int newBytes = newCapacity * s->ele_size; //新的栈空间字节数
int oldBytes = s->capacity * s->ele_size; //旧的栈空间字节数 unsigned char* b = new unsigned char[newBytes]; //在堆上分配新的栈空间 if (oldBytes)
{
//拷贝旧的栈空间的内容到新的栈空间,并释放旧的栈空间
//把旧内存块中的数据拷贝到新分配的内存块
for (int i=; i<oldBytes; i++)
b[i] = s->storage[i];
delete [] (s->storage); //释放旧的内存块
} s->storage = b; //使栈存储空间字符指针s->storage指向新分配的内存块
s->capacity = newCapacity; //更新栈的容量
} //清理栈存储空间字符指针
void cleanup(CStash* s)
{
if (s->storage != )
{
cout<<"freeing storage"<<endl;
delete []s->storage;
}
} int main(int argc, char* argv[])
{ CStash stash; char str1[] = "d1111";
char str2[] = "d2222";
char str3[] = "d3333";
char str4[] = "d4444"; initalize(&stash, ); add(&stash, str1);
add(&stash, str2);
add(&stash, str3);
add(&stash, str4); unsigned char* result = (unsigned char*)fetch(&stash, );
printf("fetch result %s\n", result);
    
     cleanup(&stash); return ;
}; 输出:

inflate increase 10
fetch result d3333

freeing storage

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

 void intTest()
{
CStash intStash; initalize(&intStash, sizeof(int)); //栈中存放int型数据,所以栈元素占用int--4个字节 int i;
for (i=; i<; i++)
add(&intStash, &i); for (i=; i<count(&intStash); i++)
cout<< "fetch(&intStash, " << i << ") = " << *(int *) fetch(&intStash, i) <<endl;
cleanup(&intStash);
} 输出:

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

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

 void stringTest()
{
CStash stringStash; ifstream in; const int bufsize = ;
initalize(&stringStash, sizeof(char) * bufsize);
in.open("clib.h");
assert(in); string line;
while (getline(in, line))
{
add(&stringStash, line.c_str());
} char *cp;
int i = ;
while ((cp = (char *) fetch(&stringStash, i++)) != )
{
cout<< "fetch(&stringStash, " << i << ") = " << cp << endl;
} cleanup(&stringStash);
} 输出:

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头文件

 #ifndef STASH_H_INCLUDED
#define STASH_H_INCLUDED class Stash
{
int ele_size; //栈中每个元素的占用的字节数
int capacity; //栈的容量,栈当前(不扩展)可容纳的元素的个数
int next; //相当于栈指针(标记下一个空位索引),栈中当前元素的个数
unsigned char* storage; //栈存储空间字符指针,动态分配的字节数组
void inflate(int increase = ); public:
void initalize(int sz);
int add(const void* element);
void* fetch(int index);
int count();
void cleanup();
}; #endif // STASH_H_INCLUDED

2)Stash.cpp实现文件

 #include "Stash.h"
#include <iostream>
#include <cassert> using namespace std; void Stash::initalize(int sz)
{
ele_size = sz;
capacity = ;
next = ;
storage = ;
} int Stash::add(const void *element)
{
if (next >= capacity)
{
inflate();
} int startBytes = next * ele_size;
unsigned char *e = (unsigned char *) element; for (int i=; i<ele_size; i++)
{
storage[startBytes + i] = e[i];
}
next++; return next-;
} void Stash::inflate(int increase)
{
cout << "inflate increase: " << increase << endl; assert(increase > ); int newCapacity = capacity + increase;
int newBytes = newCapacity * ele_size;
int oldBytes = capacity * ele_size; unsigned char *b = new unsigned char[newBytes]; if (oldBytes)
{
for (int i=; i<oldBytes; i++)
b[i] = storage[i];
delete []storage;
} storage = b;
capacity = newCapacity;
} void* Stash::fetch(int index)
{
assert(index >= );
if (index > next)
return ;
return &(storage[index * ele_size]);
} int Stash::count()
{
return next;
} void Stash::cleanup()
{
if (storage != )
{
cout << "freeing storage .... " << endl;
delete []storage;
}
}

3)main.cpp测试类

 #include <iostream>
#include <string>
#include <fstream>
#include "Stash.h" using namespace std; void intTest()
{
Stash intStash; intStash.initalize(sizeof(int)); //栈中存放int型数据,所以栈元素占用int--4个字节 int i;
for (i=; i<; i++)
intStash.add(&i); for (i=; i<intStash.count(); i++)
cout<< "intStash.fetch(" << i << ") = " << *(int *) intStash.fetch(i) <<endl;
intStash.cleanup();
} void stringTest()
{
Stash stringStash;
ifstream in;
const int bufsize = ; stringStash.initalize(sizeof(char) * bufsize);
in.open("Stash.h"); string line;
while (getline(in, line))
{
stringStash.add(line.c_str());
} char *cp;
int i = ;
while ((cp = (char *) stringStash.fetch(i++)) != )
{
cout<< "stringStash.fetch(" << i << ") = " << cp << endl;
} stringStash.cleanup();
} int main()
{ //intTest();
stringTest(); return ;
}

用一维数组实现栈(C++编程思想 p120)的更多相关文章

  1. 小马哥讲Spring栈核心编程思想 Spring IoC+Bean+Framework

    小马哥出手的Spring栈核心编程思想课程,可以说是非常专业和权威的Spring课程.课程主要的方向与核心是Spring Framework总览,带领同学们重新认识重新认识IoC,Spring IoC ...

  2. Java编程思想—八皇后问题(数组法、堆栈法)

    Java编程思想-八皇后问题(数组法.堆栈法) 实验题目:回溯法实验(八皇后问题) 实验目的: 实验要求: 实验内容: (1)问题描述 (2)实验步骤: 数组法: 堆栈法: 算法伪代码: 实验结果: ...

  3. 《Java编程思想》笔记 第十六章 数组

    1 数组 数组和容器比较,数组的优点也只剩访问效率高这一点了. 2 数组是第一级对象 数组也是一个对象,和其他普通对象一样在堆中创建, int[ ] arr  arr是数组的引用. 可以隐式创建数组对 ...

  4. java数组实现买彩票(二个一维数组的比较思想)

    /** 设计一个程序,模拟从彩球池里随机抽取5个彩球(彩球池里一共有11个彩球,编号为1~11), 要求在控制台打印出这5个被取出来的彩球的编号(注意编号不能重复). 思路: 1.创建一个int类型的 ...

  5. Java编程思想 笔记

    date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...

  6. C++编程思想重点笔记(下)

    上篇请看:C++编程思想重点笔记(上) 宏的好处与坏处 宏的好处:#与##的使用 三个有用的特征:字符串定义.字符串串联和标志粘贴. 字符串定义的完成是用#指示,它容许设一个标识符并把它转化为字符串, ...

  7. Java编程思想(11~17)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第十一章 持有对象 11.1 泛型和类型安全的容器>eg: List<St ...

  8. Java编程思想读书笔记(一)【对象导论】

    2018年1月7日15:45:58 前言 作为学习Java语言的经典之作<Java编程思想>,常常被人提起.虽然这本书出版十年有余,但是内容还是很给力的.很多人说这本书不是很适合初学者,我 ...

  9. Java编程思想(后)

    Java编程思想(后) 持有对象 如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这是一个非常简单的程序. Java中的库基本类型: List, Set, Queue和Map --- 称为集 ...

随机推荐

  1. Leetcode695.Max Area of Island岛屿的最大面积

    给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包围着. 找到给定的二维数组中 ...

  2. Javascript一些要点记录

    1. == 比较,它会自动转换数据类型再比较 === 比较,它不会自动转换数据类型,如果数据类型不一致,返回false 大部分时候应该使用===来比较2. 使用'use strict'来强制通过var ...

  3. scorllview嵌套gridview和listview的兼容问题

    ScrollView嵌套GridView或ListView,由于这两款控件都自带滚动条,当他们碰到一起的时候便会出问题,即GridView会显示不全. 解决办法:自定义一个GridView控件 pac ...

  4. 洛谷 P1027 Car的旅行路线 最短路+Dijkstra算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1027 Car的旅行路线 题目描述 又到暑假了,住在 ...

  5. 【转载】CPU相关总结

    What is the difference between Processor, Core, Logical Processor ? Processor : It’s the physical co ...

  6. CDH5.13.1安装

    文件下载 Cloudera Manager 地址:http://archive.cloudera.com/cm5/cm/5/ 这里下载的是5.13.1的版本,https://archive.cloud ...

  7. js不停地触发按钮的事件

    例子:不断地发匿名邮件 http://tool.chacuo.net/mailsend 在控制台写:setInterval('$(".convert :input[arg]").t ...

  8. md5小工具

    <?php$str = "123456";echo md5($str);?>

  9. RedHat6.2离线安装vncserver

    准备安装包 tigervnc-server-1.1.0-5.el6_4.1.x86_64.rpm pixman-0.32.8-1.el6.x86_64.rpm pixman-devel-0.32.8- ...

  10. Person Re-identification 系列论文笔记(五):SVD-net

    SVDNet for Pedestrian Retrieval Sun Y, Zheng L, Deng W, et al. SVDNet for Pedestrian Retrieval[J]. 2 ...