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. 基于遗传算法(Genetic Algorithm)的TSP问题求解(C)

    基于遗传算法的TSP问题求解(C) TSP问题: TSP(Travelling salesman problem): 译作“旅行商问题”, 一个商人由于业务的需要,要到n个城市,每个城市之间都有一条路 ...

  2. Linux下备份Mysql所有数据库

    需求:备份除了mysql系统数据库的所有数据库 以下为Shell脚本,只需要修改用户密码即可 MYSQL_USER=root MYSQL_PASS=123456 MYSQL_CONN="-u ...

  3. 【linux配置】VMware安装Redhat6.5

    VMware安装Redhat6.5 VMware安装Redhat6.5安装之前需要一些准备工作,首先,电脑上需要安装VMware(这个是废话),其次就是需要Redhat6.5的镜像文件(现在貌似都出R ...

  4. 【JZOJ3214】【SDOI2013】方程

    ╰( ̄▽ ̄)╭ 给定方程 X1+X 2+-+Xn=m 我们对第 1.. n1 个变量 进行一些限制 : X1≤A1 X2≤A2 - Xn1 ≤An1 我们对第 n1+1.. n1+1.. n1+ n2 ...

  5. [Vue CLI 3] 配置解析之 parallel

    官方文档中介绍过在 vue.config.js 文件中可以配置 parallel,作用如下: 是否为 Babel 或 TypeScript 使用 thread-loader. 该选项在系统的 CPU ...

  6. Android书架实现

    转自http://blog.csdn.net/wangkuifeng0118/article/details/7944215 书架效果: 下面先看一下书架的实现原理吧! 首先看一下layout下的布局 ...

  7. jmeter的关联-正则表达式的应用

    LoadRunnner中的关联为web_reg_save_param,查找左右边界,下次请求的时候会用到上次请求服务器返回的数据,那么我们把符合左右边界的数据保存下来,以便下次请求的时候用到. jme ...

  8. C++ lambda表达式总结

    一个lambda表达式用于创建闭包.lambda表达式与任何函数类似,具有返回类型.参数列表和函数体.与函数不同的是,lambda能定义在函数内部.lambda表达式具有如下形式 [ capture ...

  9. JAVA高级--java泛型

    类型的参数化 泛型类可以同时设置多个参数 泛型类可以继承泛型类 泛型类可以实现泛型接口 示例--泛型类 package com.date; public class GenericDemo { pub ...

  10. (四)IO流之InputStream和OutputStream

    InputStream:定义了字节输入流的抽象类 OutputStream:定义了字节输出流的抽象类;该类所有方法返回void值 FileInputStream:继承InputStream FileO ...