模板和泛型算法

#include <iostream>
#include <string>
using namespace std;

/*
关于find1使用的数据结构,我们必须知道那些情况呢?
1.我们正在查找某个类型为int的值
2.我们正在一个int对象数组中进行查找
3.我们已经预先知道了数组中元素的数目
4.我们知道了第一个元素的地址
*/
const int* find1(const int* array, int n, int x)
{
    const int* p = array;
    for (int i = 0; i < n; i++)
    {
        if (*p == x)
        {
            return p;
        }
        ++p;
    }
    return 0;
}

/*
去除的就是对int的依赖性。这将取消对它的数据类型的前两个要求
*/
template<class T>
T* find2(T* array, int n, const T& x)
{
    T* p = array;
    for (int i = 0; i < n; i++)
    {
        if (*p == x)
        {
            return p;
        }
        ++p;
    }
    return 0;
}

/*
避免必须预先知道有多少个元素,消除这个依赖性的主要原因在于,对于通用性越好的数据结构,预先计算元素的个数的代价就越昂贵
对于某些数据结构而言,甚至几乎不可能计算得出--利用这个函数来查找文件中的一个特定记录

用!=而不用<来判断循环结束并不是偶然。从某种角度来说,两者没有区别:如果find3的输入有意义,则p就小于beyond,直到它们相等位置,但是,由<加以
总体排序的类型通常也能用!=来进行比较。另一方面,考虑一下我们以后可能会用到的用来替代指针的类型,它们可能能够很好的定义!=,但不能定义<
*/
template<class T>
T* find3(T* array, T* beyond, const T& x)
{
    T* p = array;
    while (p != beyond)
    {
        if (*p == x)
        {
            return p;
        }
        ++p;
    }
    return 0;
}

/*
对于返回值,虽然可以把0转换成一个与其他所有的值不同的指针值。尽管这对于指针类型来说是完全合法的,但是我们对通用性的渴望,迫使我们必须在程序中避免这样做。
我们可以稍微改变程序的行为,以避免这种假设:如果要找的值没找到,我们就可以返回一个beyond而不是0.如果进行查找的目的是希望修改与所查找的值相等的元素,
那么这个定义就更有用处了:我们可以不用特别坚持元素是否找到了
*/
template<class T>
T* find4(T* array, T* beyond, const T& x)
{
    T* p = array;
    while (p != beyond)
    {
        if (*p == x)
        {
            return p;
        }
        ++p;
    }
    return beyond;
}

template<class T>
T* find5(T* array, T* beyond, const T& x)
{
    T* p = array;
    while (p != beyond && *p != x)
    {
        ++p;
    }
    return p;
}


/*
地址独立性操作,只依赖于指针的某些保留特性:
1.可以把指针当作参数接受,并把他们作为结果返回
2.可以比较指针相不相等
3.可以解除引用指针,以便得到一个值:*p是这样一个值
4.可以递增指针,以指向下一个元素
*/
template<class P, class T>
P find6(P start, P beyond, const T& x)
{
    while (start != beyond && *start != x)
    {
        ++start;
    }

    return start;
}

typedef struct Node
{
    string value;
    Node* next;
}Node;

class Nodep
{
public:
    Nodep(Node* p) :pt(p){}
    string& operator*(){ return pt->value; }
    void operator++(){ pt = pt->next; }
    friend int operator==(const Nodep& p, const Nodep& q);
    friend int operator!=(const Nodep& p, const Nodep& q);
    operator Node*(){ return pt; }

private:
    Node* pt;
};


int operator==(const Nodep& p, const Nodep& q)
{
    return p.pt == q.pt;
}

int operator!=(const Nodep& p, const Nodep& q)
{
    return p.pt != q.pt;
}

int main()
{

    Node n1, n2, n3, n4, n5;
    n1.value = "1111";
    n2.value = "2222";
    n3.value = "3333";
    n4.value = "4444";
    n5.value = "5555";

    n1.next = &n2;
    n2.next = &n3;
    n3.next = &n4;
    n4.next = &n5;
    n5.next = nullptr;

    Nodep obj(&n1);

    Node* pNode = find6(Nodep(&n1), Nodep(0), "3333");
    cout << pNode->value << endl;

    int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    int* data = find6(array, array + 10, 6);
    cout << *data << endl;

    getchar();

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值