C++编程训练8


已提供代码文件如下:

stdafx.h 文件,包含程序所需的文件; myarray.h 文件 动态数组类模板文件,实现了动态数组的基本操作;提供了[], begin(),end() 等,同时提供了异常处理的类,当访问数组时出现越界异常,则会抛出异常。

要求: 1)实现 replaceValue 函数,该函数为一个全局函数,其说明见所给的main.cpp 文件 template size_t replaceValue(DT first,DT last,DT oldValue,DT newValue)

2)利用main 函数中的测试用例,测试该函数的有效性。

头文件stdafx.h

#ifndef SYDFAX_H_INCLUDE
#define SYDFAX_H_INCLUDE
#pragma once
#include <iostream>
#include <cstring>
#include <fstream>

using namespace std;
#endif // !SYDFAX_H_INCLUDE

头文件myarray.h

#ifndef MYARRAY_H_INCLUDED
#define MYARRAY_H_INCLUDED

#include "stdafx.h"

//自定义的异常类型
class OutOfRange{
public:
    OutOfRange() = default;
    OutOfRange(int len, int index): m_len(len), m_index(index) { }
public:
    void what() const;  //获取具体的错误信息
private:
    int m_len = 0;  //容器中定义的长度
    int m_index = 0;  //当前用户要访问的下标
};
void OutOfRange::what() const
{
    cout<<"Error: out of range( continents length "<<m_len
        <<", access index "<<m_index<<" )"<<endl;

}

//实现动态数组的类模板
template<typename DT>
class ArrayT{
private:
    //initialize 初始化
    void init(int nums = 0)
    {
        nums = nums > 0? nums : 0;
        m_pData = (DT*)malloc( sizeof(DT) * (nums + m_stepSize) );
        m_capacity = nums + m_stepSize;
        m_len = nums;
    }
public:
    //ctor
    ArrayT()  { init(); }
    ArrayT(int nums){ init(nums); }
    ArrayT(int nums,DT val)
    {
        init(nums);
        for(int i=0;i<m_len;++i)
        {
            m_pData[i] = val;
        }
    }
    //copy ctor
    ArrayT(const ArrayT & obj)
    {
        //初始化一个同obj相同的空间
        init(obj.m_len);
        //将元素进行拷贝
        for(int i=0;i<obj.m_len;++i)
        {
            m_pData[i] = obj.m_pData[i];
        }
    }
    //copy assignment 拷贝赋值
    ArrayT & operator=(const ArrayT & obj)
    {
        //self assignment pred 自我赋值判断
        if(m_pData == obj.m_pData){return * this;}

        //capacity 如果目标空间大于源空间,则不需要申请内存空间
        if(m_capacity < obj.m_capacity)
        {
            //对原有空间进行扩容,即已经有的数值保持不变,现有空间同obj的空间相同
            m_pData = (DT*)realloc( m_pData, sizeof(DT) * obj.m_capacity );
            m_capacity = obj.m_capacity;
        }
        //将元素进行拷贝
        for(int i=0; i<obj.m_len; ++i)
        {
            m_pData[i] = obj.m_pData[i];
        }
        m_len = obj.m_len;
        return *this;
    }
    //dtor
    ~ArrayT()
    {
        if(m_pData)
        {
            free(m_pData);
            m_pData = nullptr;
        }
    };

    //member of function
public:
    //overload operator []
    DT& operator[](int index) const
    {
        //判断是否越界
        if( index<0 || index>=m_len )
        {
            //抛出异常(创建一个临时的匿名对象)
            throw OutOfRange(m_len, index);
        }
        return *(m_pData + index);
    }

    //在末尾插入元素,返回当前插入元素的索引号
    int push_back(DT ele)
    {
        if(m_len >= m_capacity)
        {
            //如果容量不足就扩容
            m_capacity += m_stepSize;
            //扩容 原有元素保持不变
            m_pData = (DT*)realloc( m_pData, sizeof(DT) * m_capacity );
        }
        *(m_pData + m_len) = ele;
        m_len++;
        return m_len-1;
    }

    //在末尾弹出数组元素,返回该元素
    DT pop_back()
    {
        if(m_len == 0)
        {
            throw OutOfRange(m_len,m_len);  //抛出异常(创建一个匿名对象)
        }
        m_len--;
        return *(m_pData + m_len);
    }

    //获取数组长度
    int length() const{ return m_len; };

    //获取开始位置的指针
    DT * begin() const{  return m_pData;   }
    //获取超尾位置的指针
    DT * end() const {return m_pData+m_len;}

    //member of data
private:
    int m_len = 0;          //数组长度
    int m_capacity = 0;     //当前的内存能容纳多少个元素
    DT *m_pData = nullptr;           //具体数据内容的内存指针
private:
    static const int m_stepSize = 50;  //每次扩容的步长
};


#endif // MYARRAY_H_INCLUDED

源文件main.cpp

#include "myarray.h"

using namespace std;

//算法的说明
//将区间 [first,last)之间的值进行替换
//当该区间的值为旧值oldValue时,替换为新值 newValue
//返回替换值的个数
//形参列表的说明
//DT * first 区间 [first,last)第一个元素的指针
//DT * last 区间 [first,last)最后一个元素的指针
//DT oldValue 待替换的值
//DT newValue 替换后的值
template<typename DT>
size_t replaceValue(DT* first, DT* last, DT oldValue, DT newValue)
{
    //完善该代码
    size_t nsize = 0;
    //在此处填写代码
    for (;first != last;++first)
    {
        if (*first == oldValue)
        {
            *first = newValue;
            ++nsize;
        }
    }
    return nsize;
}

int main()
{
    //测试所写的函数是否正确
    int n = 49;
    ArrayT<int> objint(n, 1);
    for (int i = 0;i < n;++i)
    {
        if (i % 3 == 0) { objint[i] = 3; }
        else { objint[i] = 5; }
    }
    //原数组
    cout << "替换前的数组为:" << endl;
    for (int i = 0;i < n;++i)
    {
        cout << objint[i] << "\t";
    }
    cout << endl;
    cout << endl;
    size_t nn = replaceValue(objint.begin(), objint.end(), 5, 6);

    //调整后的数组
    cout << "替换后的数组为:" << endl;
    for (int i = 0;i < n;++i)
    {
        cout << objint[i] << "\t";
    }
    cout << endl;
    cout << "替换的个数为" << nn << "个。" << endl;
    return 0;
}

文章作者: 陈细利
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 陈细利 !
评论
 上一篇
C++编程训练9 C++编程训练9
滴滴打车是目前出行的一种选择,打车时根据选择车型不同,实际行驶路程进行计费。武汉市的滴滴打车目前提供了 4 种车型,分别为快车、出租车、专车和豪华车。不同车型的 起步价以及起步价内的行驶路程不同,同时,每公里的计费标准也不相同;例如武汉市
下一篇 
C++编程训练7 C++编程训练7
学生信息管理 定义学生类,包含学号 姓名 年龄 绩点这些成员 要求: 通过键盘输入学生信息,保存到文件中(文本文件、二进制文件全都要) 能够读取要求 1 中的文件,在屏幕上显示学生信息; 根据学生的绩点、年龄、学号进行排序,排序完成后,
  目录