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. 如何设置单个 Git 仓库的代理从而提高更新速度

    如何设置单个 Git 仓库的代理从而提高更新速度 因为特殊原因,需要单独对 Git 仓库设置远程代理,从而提高更新速度. 主要原因是因为有一些远程 Git 仓库比较慢. 最初的想法是系统全局代理,但是 ...

  2. getElementsByClassName兼容低版本浏览器

    var getElementsByClassName = function (searchClass, node,tag) { if(document.getElementsByClassName){ ...

  3. AGC029 E: Wandering TKHS

     E: Wandering TKHS - AtCoder Grand Contest 029 | AtCoder 分类讨论好题(也不太算分类讨论) 方法:感受过程手玩,考虑能不能提前预算一些东西,或者 ...

  4. hdu4324 dfs

    scanf("%1d")这种好像很慢. #include<stdio.h> #include<string.h> #define maxn 2010 str ...

  5. python 使用异常代替返回状态码

  6. Libevent:1前言

    一:libevent概述: libevent是一个用来编写快速.可移植.非阻塞IO程序的库,它的设计目标是:可移植性.高效.可扩展性.便捷. libevent包含下列组件: evutil:对不同平台下 ...

  7. 基于MaxCompute的数仓数据质量管理

    声明 本文中介绍的非功能性规范均为建议性规范,产品功能无强制,仅供指导. 参考文献 <大数据之路——阿里巴巴大数据实践>——阿里巴巴数据技术及产品部 著. 背景及目的 数据对一个企业来说已 ...

  8. 实现一个简易的promise

    //promise里面只有三个状态,且三个状态的转换形式有两种 //由pending转换为fulfilled,由pending转换为rejected //Promise的构造函数参数是一个函数,函数的 ...

  9. nodeJs学习-05 案例:http/fs/querystring/url

    const http = require('http'); const fs = require('fs'); const querystring = require('querystring'); ...

  10. iOS tableView优化

    iOS: Autolayout和UITableViewCell的动态高度 http://www.mgenware.com/blog/?p=507 优化UITableViewCell高度计算的那些事 h ...