#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;
}