ColKang v1.0

  最近尝试写一下NFA到DFA转换的函数,用C++,但是想到集合的表示比较麻烦,一些高级的容器也还没学到,因此自己先写一个简单的collection类,1.0版本。

  能实现的功能有:存储数字集合;能进行集合间比较O(N)及加O(M+N)减法O(N);能向集合中添加元素O(N)或删除元素O(N);能返回集合中第X小的元素O(1)

  因为目前对C++理解较为有限,特别是写一个类的时候感到力不从心,因此很多地方应该都不是很符合规范,先将这个能实现基本功能的代码贴上来,再想一下以后的改进空间,之后写出更加完善的collection类。

/*
*ColKang v1.0
*这个类用来定义集合,因为未学到容器,因此自己写一个类来实现
*此类仅用于存储数字
*目前使用数组存储,可用跳跃表优化。
*/

#include<iostream>
using namespace std;
class collection
{
public:
    //构造函数
    collection()
    {
        for (int i = 0; i < 1000; i++)
            this->data[i] = 0;
            this->length = 0;
    }
    //初始化集合
    void init()
    {
        for (int i = 0; i < 1000; i++)
            this->data[i] = 0;
        this->length = 0;
    }
    //判断两个集合是否相等
    bool equal(collection *b)
    {
        if (this->length != b->length) return false;
        else
        {
            for (int i = 0;i < this->length;i++)
            if (this->data[i] != b->data[i])
                return false;
        }
        return true;
    }
    //得到集合的长度
    void print_collection()
    {
        for (int i = 0; i<this->length; i++)
            cout << this->data[i] << ‘ ‘;
        cout << endl;
    }
    int search_element(int b)
    {
        int i = 0, j = this->length - 1, mid = 0;
        while (i<j)
        {
            mid = (i + j) / 2;
            if (this->data[mid] == b) break;
            else if (this->data[mid] > b) j = mid - 1;
            else i = mid + 1;
        }
        if (i > j)
        {
            cout << "There is not a element that equals with " << b << "in this collection" << endl;
            return -1;
        }
    }
    int get_length()
    {
        return this->length;
    }
    //得到集合中第X+1小的元素
    int get_element(int x)
    {
        return this->data[x];
    }
    //集合添加元素,时间复杂度为O(N)
    void add_element(int b)
    {
        int i = 0;
        while (this->data[i] <= b&&this->data[i] != -1) i++;
        for (int j = this->length - 1; j >= i; j--)
            this->data[j + 1] = this->data[j];
        this->data[i] = b;
        this->length++;
    }
    //删除指定元素
    void delete_element(int b)
    {
        int t;
        if (t = this->search_element(b))
        {
            while (t < this->length - 1)  { this->data[t] = this->data[t + 1]; t++; }
            length--;
        }
    }
    //进行集合加法
    collection add_collection(collection *b)
    {
        //使用归并排序的合并部分
        collection *c;
        int i = 0, j = 0;
        while (i <= this->length && j <= b->length)
        {
            c->length++;
            if (this->data[i] = b->data[j]) j++;
            else if (this->data[i] < b->data[j]) c->data[c->length] = this->data[i];
            else c->data[c->length] = b->data[j];
        }
        if (i <= this->length)
        while (i <= this->length)
        {
            c->length++;
            c->data[c->length] = this->data[i];
            i++;
        }
        else
        while (j <= b->length)
        {
            c->length++;
            c->data[c->length] = b->data[j];
        }
        return *c;
    }
    //集合减法
    void sub_collection(collection *b)
    {
        //对每个b集合中的元素调用delete_element
        for (int i = 0; i<b->length; i++)
            this->delete_element(b->data[i]);
    }
private:
    int data[1000], length;
};

  其中用到的一些小方法:search_element(int x)使用了二分查找,使查找的复杂度降低到O(lgn),集合加法使用了归并排序中的合并部分,实现了O(M+N)而不是N次插入。

  遇到的困难:其实还挺多的,第一次写类,感觉好多地方都不太懂。

1.最开始的时候所有的->都用.来表示,因为我记得语法中是这么来引用成员函数或者成员变量的,但是后来vs报错,又去网上查了一下才知道,原来如果这个类定义的时候是指针:collection *p ,那么引用成员函数及成员变量的时候是需要用->来引用的,如果定义的时候是collection p,那么直接使用.就可以了。而我发现因为各个地方都要传参数进去,出于方便考虑就是用了指针的方式。

2.add_collection函数。首先是this指针,之前C++课程开设的时候就对this指针理解的比较模糊,只记得它是指向当前对象,对于一个类来说就是指这个类。我在写add_collection函数的时候,最初是这么写的: collection * add_collection(collection*a.collection*b),后来想到一个问题:这个函数是collection的成员函数,那么调用的时候就得用 collection *collectionAns = collectionA.add_collection(*collectionA,*collectionB)这么蛋疼的方式,而且collectionA是必定要参与运算的,那么为什么还要多此一举使用两个参数呢,因此就改成了只有一个参数的函数。与是就成了collection *collectionAns = collectionA.add_collection(*collectionB)。然后又想了一下,感觉可以把返回值去掉(当时考虑的是既然this指向的就是这个类,那么只要让this指向加法产生后的结果不就可以了)结果vs继续报错,查了一下说是this指针指向的位置是固定的,不能以任何方式更改。这个道理仔细想了一下,确实是一个很合理的规定,与是就沿用了上面的方式,但是因为我想让集合a和b的加和结果存在a中,与是现在调用就成了a = a.add_collection(*b);如果要把结果存在第三个集合中,就是一种更为纠结的方式:collection *c = a.add_collection(*b)。后来想了一下,能否把函数add_collection写在collection类的外面呢?但是因为这个类中调用了collection类的私有成员变量,写在外面是无法调用到这些变量的,因此就只能做到目前这样了,感觉C++不会留这样纠结的方式吧~以后等学到能解决这些问题的地步再来重写这个函数。

  基本就是这两个问题让我最为头大,其他小问题也多多少少出现了不少,感觉语法还是最为基础也是最需要掌握好的,不然第一个问题.和->就不会困扰我那么久了(之前报错从来没想过是这个的问题~_~)

  目前优化的方向来讲,主要有这几个方面吧:

1.存储的方式。现在是数组存储,因为考虑到如果用链表的话不能直接获取下标,这样get_element(int x)函数的时间复杂度会变成0(N),而且我个人对C++指针部分学习还不是很到位。以后拟使用跳跃表来存储,并稍作调整:每一个非底层链表中存有一个域指出当前元素在最底层链表中的位置,这样add_collection,sub_collection,add_element,这几个元素的时间复杂度都会有提升,而且search_element的时间复杂度也会比较理想(应该是O(sqrt(n),当时看跳跃表的时候记得高度是sqrt(n),底层链表中每个区间长度期望值也是sqrt(n))

2.扩展集合的类型。现在只支持数字,希望能以后扩展到字母,符号,再深入一点扩展到数组,字符串,甚至类。

3.运算符重载。这个我目前只是理解一个概念,但是并未深入,如果能弄好这个,我感觉那个add_collection函数的蛋疼之处就能解决掉啦~

时间: 2024-10-09 20:36:18

ColKang v1.0的相关文章

【资源共享】Rockchip I2C 开发指南 V1.0

2C设备的设备应用非常广泛,常见的包含重力传感器,触摸屏驱动芯片,音频解码等 这个文档是RK3399的I2C开发文档:<Rockchip I2C 开发指南 V1.0> 内容预览: 下载地址:http://developer.t-firefly.com/thread-12495-1-1.html

Windows环境下Android Studio v1.0安装教程

Windows环境下Android Studio v1.0安装教程 Windows环境下Android Studio v1.0安装教程 准备工具 JDK安装包. 要求:JDK 7以及以上版本. Android Studio安装文件. Windows: exe(包含SDK) (813 MB) exe(不包含SDK) (250 MB) zip (235 MB) Mac dmg (234 MB) zip (233 MB) Linux: zip (233 MB) 说明: 32位系统和64位系统是同一个安

Alien.Skin.Bokeh.v1.0.3.Incl.

Ablume.Surfmemo.v4.2.Regged-WaLMaRT\ Alien.Skin.Blow.Up.v2.0.3.MacOSX.Incl.  Alien.Skin.Blow.Up.v2.0.4.Incl. TEL:15108931101   QQ:316859986 Alien.Skin.Exposure.v3.0.0.Incl.  Alien.Skin.Exposure.v3.0.0.MacOSX.Incl.  Alien.Skin.Eye.Candy.v6.0.0a.Incl. 

wzplayer for ios 针对(mms)优化版本V1.0

wzplayer for ios针对mms优化版本发布. 1.支持mms,http,rtmp,rtsp等协议 2.支持全格式 下载地址:http://www.coolradio.cn/WzPlayer.ipa 更强大的,请使用tlplayerhttp://blog.csdn.net/tigerleap/article/details/19007057 联系方式:[email protected] QQ:514540005 版权所有,禁止转载. 发布自:http://blog.csdn.net/t

Nat.Geo.Games.DogTown.v1.0.Cracked-F4C

Macaraja.Soft.RamWizard.v3.1.2.2.Cracked-QUANTiZE\ MetaProducts.LightPad.v4.6.164.WinAll.Incl.Keygen-CRD\ MetaProducts.Portable.Offline.Browser.v5.8.3158.Incl.Keymaker.And.Patch-ROGUE\ Millionenjagd.GERMAN-ALiAS\ Mishap.An.Accidental.Haunting-OUTLAWS

主流区块链技术特点及Fabric V0.6&V1.0版本特点

声明:文章内容来源于网络. 一.主流区块链技术特点 二.Hyperledger的fabric V0.6总体架构: 对应的0.6版本的运行时架构: 0.6版本的架构特点是: 结构简单: 应用-成员管理-Peer的三角形关系,主要业务功能全部集中于Peer节点:    架构问题:由于peer节点承担了太多的功能,所以带来扩展性.可维护性.安全性.业务隔离等方面的诸多问题,所以0.6版本在推出后,并没有大规模被行业使用,只是在一些零星的案例中进行业务验证: 三.Hyperledger的fabric V

heatmap.js v1.0 到 v2.0,详细总结一下:)

前段时间,项目要开发热力图插件,研究了heatmap.js,打算好好总结一下. 本文主要有以下几部分内容: 部分源码理解 如何迁移到v2.0 v2.0官方文档译文 关于heatmap.js介绍,请看这里: http://www.oschina.net/p/heatmap-js 目前,对于热力图的开发,百度.高德开发平台上使用的都是这款JS开源库.当然,现在还有我们公司:P 百度示例:http://developer.baidu.com/map/jsdemo.htm#c1_15 高德示例:http

【转】Windows环境下Android Studio v1.0安装教程

原文网址:http://ask.android-studio.org/?/article/9 http://android-studio.org/index.php/docs/experience/158-androidstudio-v1-0-win-install Windows环境下Android Studio v1.0安装教程 准备工具 JDK安装包.要求:JDK 7以及以上版本. Android Studio安装文件. Windows:exe(包含SDK) (813 MB)exe(不包含

效率飞速提高Four Dimension Technologies GeoTools v17.0 1CD+AutoHook.2017.v1.0.3.00 1CD

效率飞速提高Four Dimension Technologies GeoTools v17.0 1CD+AutoHook.2017.v1.0.3.00 1CD GeoTools v12.18 1CD     GeoTools写的是测绘.GIS用户心中最初但现在有这个程序它是有用的,只是任何AutoCAD用户相关的足够的命令.GeoTools现在是几乎所有的AutoCAD用户有用.它解决了很多常见的问题和地图生产的要求和编辑AutoCAD是地理数据的一个非常方便的工具捕获(GIS底图).处理.转