DHU数据结构-顺序表- ADT应用-前m个元素后置

目录

1.题目

2.题解

3.代码实现

4.改进


1.题目

                顺序表ADT模板设计及简单应用:将顺序表中前 m 个元素和后 n 个元素进行互换

                                作者: 冯向阳时间限制:  1S章节: DS:线性表

问题描述 :

目的:使用自行设计的顺序表ADT或STL中的vector模板,设计并实现顺序表应用场合的一些简单算法设计。

应用1:试设计一个算法,用尽可能少的辅助空间将非空顺序表中前 m 个元素和后 n 个元素进行互换,即将线性表(a1,a2,…,am,b1,b2,…,bn) 改变成(b1,b2,…,bn,a1,a2,…,am)。假定m始终是有效值。

参考函数原型:

(1)顺序表ADT版本

template

void Exchange( SqList &A, int m ); // 本算法实现顺序表中前 m 个元素和后 n 个元素的互换

(2)vector版本

template
void Exchange( vector &A, int m );// 本算法实现顺序表中前 m 个元素和后 n 个元素的互换

输入说明 :

第一行:顺序表的数据元素类型标记(0:int;1:double;2:char;3:string;其余值:输出err)

第二行:待处理顺序表的数据元素(数据元素之间以空格分隔)

第三行:逆置位置m

输出说明 :

第一行:逆置前顺序表的遍历结果(数据元素之间以“,”分隔)

空行

第三行:逆置后顺序表的遍历结果(数据元素之间以“,”分隔)

输入范例 :

0
13 5 27 9 32 123 76 98 54 87
5

输出范例 :

13,5,27,9,32,123,76,98,54,87

123,76,98,54,87,13,5,27,9,32


2.题解

  • 读题:题目要求通过vector或者手写adt来实现顺序表,在此基础上完成一个交换元素的算法
  • 实现顺序表:手写adt还挺麻烦的哈(等有时间再去实现),所以本大懒人选择现成的vector。表的数据的录入还挺麻烦的,不同数据类型录入的方法都不同(把输入部分储存为string类型然后再去转换类型。int考虑字符串转数字,double除了转数字外还有小数,string读入不读空格。而且还要考虑正负)。还有记得考虑空表问题,别把'/0'这个元素插到vector里面然后出错。
  • 实现交换算法:这个容易,只需要进行三步翻转。1.把表中的所有元素翻转  2.把上一步之后的表中后面的m个元素翻转 3.最后把前面n-m个翻转就ok。当然也可以直接枚举一个一个放到对应的位置,但是题目要求少用空间。

3.代码实现

  • 数据录入构成表:
    先用string来存储接下来要录入的元素
            int n;
            string s;
            cin>>n;
            getchars();
            getline(cin,s);
    
    
    
    下面是不同数据类型的录入方法
    
    //int型数据的录入(没有考虑负数情况,也没有考虑空表)
            vector a;
            int num=0;
            for(int i=0; i b;
            double num=0;
            int flag=0,t=0;//flag为1表示在计算小数部分数值,t表示小数点后的数字长度
            for(int i=0; i c;
            for(int i=0; i d;
            string str;
            str.clear();
            for(int i=0; i

  • 模版算法部分:
    //print函数
    template
    void print(vector &A)
    {
        //法一:用迭代器遍历
        typename::vector ::iterator it;//注意迭代器定义的语句
        for(it=A.begin();it!=A.end();it++)
        {
            if(it==A.begin())cout<<(*it);
            else cout<<","<<(*it);
        }
        cout<
    void change(vector &A)
    {
        print(A);
        cout<

  • 完整代码

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    int n,m;
    string s;
    
    template
    void print(vector &A)
    {
        int i;
        for(i=0;i
    void change(vector &A)
    {
        print(A);
        cout<>n;
        getchar();
        getline(cin,s);
        cin>>m;
    
            if(n==0)
            {
                vector a;
                int num=0;
                for(int i=0;i b;
                double num=0;
                int flag=0,t=0;
                for(int i=0;i c;
                for(int i=0;i d;
                string str;
                str.clear();
                for(int i=0;i


4.改进

在课堂听完老师的讲解之后发现有两处可以进行优化或者钻研

  • 首先是造表,可以用stringstream实现函数模版实现代码复用,并且不需要讨论不同类型数据的录入,方便得很
  • 第二是不能说是优化,只是想尝试手写一个模版类,毕竟老师说从底层理解vector是怎么实现的也更能熟练掌握vector运用嘛,我觉得他说得很对。

以下是代码

  • stringstream使用
    //模版造表函数,在主函数中运用就不需要写这么长的代码,stringstream头文件sstream
    template
    void CreatList(stringstream &in,vector &sqlist)
    {
        T tmp;
        while(in>>tmp)
            sqlist.push_back(tmp);
    }
    
    
    //以int类型为例
    int main()
    {
        cin>>n;
        cin.ignore();
        getline(cin,s);
        stringstream input(s);
        
        if(n==0)
        {
            vector a;
            CreatList(input,a);
            change(a);
    }

    使用stringstream的完整代码,并且进行代码赏析

    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    int n,m;
    string s;
    
    template
    void print(vector &A)
    {
        typename std::vector::iterator it=A.begin();
        for(it;it!=A.end()-1;it++) cout<<*it<<",";
        cout<<*it<
    void change(stringstream &input,vector &A)
    {
        T str;//用来临时储存单个数据
        while(input>>str) //“stringstream对象 + >>“就是提取字符串中单个数据
            A.push_back(str);//每每提取到单个数据就插入到vector中
    
        print(A);
        cout<>n;
        getchar();//也可以用cin.ignore()都是用来消除上一个n的输入后保存在缓冲区的回车
        getline(cin,s);//读入string一般用这个读入,不用cin是为了防止碰到string中的空格就读入结束
        stringstream input(s);//创建一个stringstream对象input,并把s的数据存入这个流对象input,因为stringstream对象可以进行单个字符串提取的操作,这么做是方便了提取单个数据来造表
        cin>>m;
    
        if(n!=0&&n!=1&&n!=2&&n!=3) cout<<"err"< a;
            change(input,a);
        }
        else if(n==1)
        {
            vector b;
            change(input,b);
        }
        else if(n==2)
        {
            vector c;
            change(input,c);
        }
        else
        {
            vector d;
            change(input,d);
        }
    
        return 0;
    }
    

  • 手写adt

你可能感兴趣的:(数据结构,数据结构)