关闭

用C++的STL部分实现Python中的list(列表)

124人阅读 评论(0) 收藏 举报
分类:

本来准备来实现一个简单的python的shell交互器,现在只完成了python中几个数据结构的实现,目前正在啃编译原理,等编译原理啃完了再继续回来实现pytyon的shell。
写的有点乱哈~~
Github有详细的代码:achievePythonShell
实现的思想:
Python中的列表是个神奇的数据结构,也是Python中最学用的一个数据结构(个人认为),它能存放各个类型的数据,lst1=[1,2,2.3,”string”];它的数据元素还能是列表,lst2=[1,2,2.3,”string”,[2,3,’sdf’]],这个也是我在实现的时候最难的一点,因为它能放列表,列表的列表,列表的列表的列表……
所以我先定义了一个Type类,把列表中的元素都放到Type类中,这样列表就可以用vector来进行操作。

class Type
{
    public:
    float value;//用来存放int或float类型的数据
    string val_str;//用来存放字符串类型数据
    int type;//用来表示数据的类型,因为python中没有类型,0代表整形,1代表浮点型,2代表字符串类型
     Type(float v=0,string vs="", int t=0) :value(v), type(t) {//在python中把字符串都加上‘’,在构造函数里实现
        if (t == STRING)
        {
            vs = "'" + vs + "'";
            val_str = vs;
        }
}

那如果元素要是一个列表,即[1,2,[3,4]]中的[3,4]用什么来表示呢?想了很久 ,最后把这个[3,4]看成是一个字符串”[3,4]”存放在Type中的val_str里,同时type的值为2(字符串类型)+括号的层数。
比如:元素[3,4]可以表达为Type(0,”[3,4]”,2+1),其中type=2+1;
元素[[3,4],5]可以表达为Type(0,”[[3,4],3]”,2+2),其中type=2+2;
如果要访问里的元素怎么办呢?要访问上面的
Type(0,”[[3,4],3]”,4);中的元素3怎么访问呢?我的解决方法就在Type里面重载operatro[]访问“[[3,4],3]”里面的元素.

Type Type::operator[](int index)//不能返回引用
{
    if (type < 2)//int float and string has no operator[]
    {
        cout << "\tthis type has no attritute" << endl;
        exit(-1);
    }
    if (type == 2)
    {
        string temp_s = "";
        temp_s = "'" + val_str[index];
        temp_s += "'";
        Type ty = Type(0.0, temp_s, STRING);
        ty.plast = &val_str;
    }
    //type>=3时,val_str不为空
    vector<char>bracket;//括号栈,当括号栈为空时索引才加1
    int i = 1;//从第一个中括号开始
    bool flag = true;//判断是否有语法错误
    int cur_index = -1;//当前索引
    string ele = "";//记录当前的元素
    int bracket_maxnum = 0;//括号层数
    while (flag&&i < val_str.size() && cur_index<index)
    {
        char ch = val_str[i];
        if (i == val_str.size() - 1)
            ch = ',';
        switch (ch)
        {
        case '[':
            bracket.push_back('[');
            if (bracket.size() > bracket_maxnum)
                bracket_maxnum = bracket.size();
            ele += '[';
            break;
        case ']':
            if (!bracket.empty() && bracket.back() == '[')
                bracket.pop_back();
            else
                flag = false;
            ele += ']';
            break;
        case ',':
            if (ele == "")
            {
                flag = false;
                break;
            }
            if (bracket.empty())
            {
                cur_index++;
                if (cur_index < index)
                {
                    bracket_maxnum = 0;
                    ele = "";
                }
            }
            else
                ele += ',';
            break;
        default:
            ele += ch;
            break;
        }
        i++;
    }
    if (!flag)//出现语法错误
    {
        cout << "\terror syntax!" << endl;
        exit(-1);
    }
    else if (cur_index == index)//找到指定索引元素
    {
        Type temp_t;
        temp_t.plast = &val_str;
        if (judgeValueType(ele) == INTEGER || judgeValueType(ele) == FLOAT)
        {
            stringstream ss(ele);
            ss >> temp_t.value;
            temp_t.type = judgeValueType(ele);
        }
        else if (judgeValueType(ele) == STRING)
        {
            //removeSymbol(ele,"\"");
            //removeSymbol(ele,"'");
            temp_t.val_str = ele;
            temp_t.type = STRING;
        }
        else
        {
            temp_t.val_str = ele;
            temp_t.type = OFFSET + bracket_maxnum;
        }
        return temp_t;
    }
    else
    {
        cout << "\terror index!" << endl;
        exit(-1);
    }
}

里面用到了judgeValueType()函数,这个函数是自己定义的判断数据类型的函数,因为Python中的数据类型要自己判断
这样:Type ty=Type(0,”[[3,4],3]”);我就能通过ty[1]来访问其中的元素3了。
接下来又有个问题,我重写的operator[]只是单纯返回了一个值,没有返回引用!就实现不了ty[1]=3;来改变值了,那怎么解决呢?
因为整个列表元素在一个字符串类型,而要改变可能要改变它的字串,改变字串的同时还要改变整个列表中对应的元素。于是我在Type类中添加了一个成员,是保存上原来Type中的val_str的指针,通过它就能有返回引用的效果了。

class Type//Python中的所有函数都用这个类型
{
private:
    string *plast;//用在operator[]中达到引用的效果,指向父串的内存;是opertor[]返回则非空,否则返回空
public:
    string val_str;//存放string类型 
    float value;//存放float和int类型
    int type;
    Type(float v=0,string vs="", int t=0) :value(v), type(t) {//在python中把字符串都加上‘’,在构造函数里实现
        if (t == STRING)
        {
            vs = "'" + vs + "'";
            val_str = vs;
        }
        plast = NULL;
    }
    }
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

C++ STL list介绍与使用方法

list(链表)链表也即链式表,在数据结构中,我们知道线性表的物理存储结构有两种,顺序表(数组)和链式表(结点)。链表是在堆中为每一个元素分配内存,然后利用指针将所有元素串起来。根据这种物理存储结构,...
  • Cypress1010
  • Cypress1010
  • 2016-12-15 13:34
  • 1627

STL list链表的用法详细解析

原文地址:http://www.jb51.net/article/41525.htm 本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到普通函数,而且例子丰富,通俗易懂。不失为S...
  • Double2hao
  • Double2hao
  • 2016-03-01 08:05
  • 2961

c++ STL的list用法总结

头文件 #include   声明一个int型的list:list a; 1、list的构造函数 lista{1,2,3} lista(n) //声明一个n个元素的列表,每个元素都是0...
  • xiaoquantouer
  • xiaoquantouer
  • 2017-04-21 22:02
  • 1704

stl容器list部分实现

#include #include #include using namespace std; // 双向线性链表容器模板 template class List { public: // 构...
  • liyuan_669
  • liyuan_669
  • 2016-09-27 21:53
  • 181

STL::List部分函数实现

前面一篇文章讲了STL::List用法详解,简单介绍list的一些函数,在这分享一下双向链表的部分简单函数实现       因为链表会出现频繁的增加、删除,所以使用迭代器较为简单 先定义节...
  • fangfang_666
  • fangfang_666
  • 2016-09-13 20:03
  • 238

STL讲义其中包含部分有: vector list map,还有一些例子

  • 2012-03-25 17:10
  • 22KB
  • 下载

c++ stl list实现简单的学生信息管理系统

c++ stl list实现简单的学生信息管理系统 问题描述: 已知有20个学生记录(包括学号、姓名、成绩)的文件student.dat。要求编程序实现查询、排序、插入、删除诸功能。 系统的...
  • NUPTboyZHB
  • NUPTboyZHB
  • 2012-12-19 13:20
  • 5182

用C++实现STL容器list

用C++实现STL容器list
  • yaoxiaokui
  • yaoxiaokui
  • 2015-10-17 15:35
  • 241

C++STL库list容器简单实现

针对C++应届生应聘笔试可能会涉及list容器的简单实现,特献上此文,希望能给有需要的朋友一些裨益,具体看代码讲解: #include #include using namespace st...
  • qq_31766907
  • qq_31766907
  • 2015-12-16 19:20
  • 189

【C++ STL应用与实现】6: 如何使用std::list

list是stl对链表数据结构的一种支持,其通常被实现为双向链表。本文介绍了list的基本用法以及在使用list时需要注意的一些问题。
  • elloop
  • elloop
  • 2017-01-31 19:11
  • 494
    个人资料
    • 访问:6067次
    • 积分:232
    • 等级:
    • 排名:千里之外
    • 原创:18篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论