字典(dictionary)是由一些形如(k,v)的数对所组成的集合,其中k是关键字,v是与关键字k对应的值(也可以说,v是值,它的关键字是 k)。任意两个数对,其关键字都不等。
多重字典:两个或更多的数对可以具有相同的关键字。
在一个多重字典中进行查找和删除操作时,需要消除歧义。就查找而言,有两种可能:
1)查找任何一个具备给定关键字的数对;
2)查找所有具备给定关键字的数对。就删除操作而言,我们要求给用户提供与给定关键字对应的所有数对,由用户选择删除哪些数对。此外,可以任意删除与给定关键字对应的一个数对或所有数对。
/*
Project name : allAlgorithmsTest
Last modified Date: 2022年8月13日17点38分
Last Version: V1.0
Descriptions: main()函数,控制运行所有的测试函数
*/
#include "_23dictionaryChain.h"
int main()
{
dictionaryChainTest();
}
/*
Project name : allAlgorithmsTest
Last modified Date: 2022年8月22日09点17分
Last Version: V1.0
Descriptions: 使用链表实现的字典的头文件---是有序的
*/
#pragma once
#ifndef _DICTIONARY_CHAIN_H_
#define _DICTIONARY_CHAIN_H_
#include
#include "_23pairNode.h"
#include "_23dictionary.h"
using namespace std;
/*测试函数*/
void dictionaryChainTest();
template<class K, class E>
class dictionaryChain : public dictionary<K, E>
{
public:
/*成员函数*/
/*构造函数和析构函数*/
dictionaryChain() { firstNode = nullptr; dSize = 0; }
~dictionaryChain();
/*其他成员函数*/
bool empty() const { return dSize == 0; }
int size() const { return dSize; }
pair<const K, E>* find(const K&) const;
void erase(const K&);
void insert(const pair<const K, E>&);
/*友元函数*/
/*输入字典*/
istream& input(istream& in);
// friend istream& operator>> (istream& in, dictionaryChain& m);
/*输出字典*/
ostream& output(ostream& out) const;
// friend ostream& operator<< (ostream& out, const dictionaryChain& m);
protected:
pairNode<K, E>* firstNode; // pointer to first node in chain
int dSize; // number of elements in dictionary
};
/*输入字典*/
template<class K, class E>
istream& dictionaryChain<K, E>::input(istream& in)
//istream& operator>>(istream& in, dictionaryChain& m)
{
int numberOfElement = 0;
cout << "Please enter the number of element:";
while (!(in >> numberOfElement))
{
in.clear();//清空标志位
while (in.get() != '\n')//删除无效的输入
continue;
cout << "Please enter the number of element:";
}
pair<K, E> element;
for (int i = 0; i < numberOfElement; i++)
{
cout << "Please enter the element " << i + 1 << ":";
while (!(in >> element.first >> element.second))
{
in.clear();//清空标志位
while (in.get() != '\n')//删除无效的输入
continue;
cout << "Please enter the element " << i + 1 << ":";
}
insert(element);
}
return in;
}
template<class K, class E>
istream& operator>>(istream& in, dictionaryChain<K,E>& m){
m.input(in);
return in;
}
/*输出字典*/
template<class K, class E>
ostream& dictionaryChain<K, E>::output(ostream& out) const
//ostream& operator<<(ostream& out, const dictionaryChain& m)
{
pairNode<K, E>* currentNode = firstNode;
while (currentNode != nullptr)
{
out << "(" << currentNode->element.first << " ," << currentNode->element.second << ")" << " ";
currentNode = currentNode->next;
}
cout << endl;
return out;
}
template<class K, class E>
ostream& operator<<(ostream& out, const dictionaryChain<K,E>& m){
m.output(out);
return out;
}
/*析构函数*/
template<class K,class E>
dictionaryChain<K,E>::~dictionaryChain()
{
pairNode<K, E>* nextNode;
while (firstNode != nullptr)
{
nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
/*寻找关键字为key的数对并返回*/
template<class K, class E>
pair<const K, E>* dictionaryChain<K, E>::find(const K& key) const
{
//返回匹配的数对的指针
//如果不存在匹配的数对,则返回nullptr
pairNode<K, E>* currentNode = firstNode;
while (currentNode != nullptr && currentNode->element.first != key)
currentNode = currentNode->next;
if (currentNode != nullptr && currentNode->element.first == key)
return ¤tNode->element;
return nullptr;//如果没找到就返回nullptr
}
/*删除关键字为key的数对*/
template<class K, class E>
void dictionaryChain<K, E>::erase(const K& key)
{
//删除关键字为key的数对
pairNode<K, E>* p = firstNode;//存储的是插入元素之后的位置
pairNode<K, E>* tp = nullptr;//存储的是插入元素之前的位置
//搜索关键字为key的数对
while (p != nullptr && p->element.first < key)
{
tp = p;
p = p->next;
}
//确定是否匹配
if (p != nullptr && p->element.first == key)
if (tp == nullptr) firstNode = p->next;//p是第一个节点
else tp->next = p->next;
delete p;
dSize--;
}
/*往字典中插入data,覆盖已经存在的匹配的数对*/
template<class K,class E>
void dictionaryChain<K, E>::insert(const pair<const K, E>& data)
{
pairNode<K, E>* p = firstNode;//存储的是插入元素之后的位置
pairNode<K, E>* tp = nullptr;//存储的是插入元素之前的位置
while (p != nullptr && p->element.first < data.first)
{
tp = p;
p = p->next;
}
//检查是否有匹配的数对
if (p != nullptr && p->element.first == data.first)
{
p->element.second = data.second;
return;
}
//无匹配的数对,为thePair建立新节点
pairNode<K, E>* newNode = new pairNode<K, E>(data, p);
//在tp之后插入新节点
if (tp == nullptr) firstNode = newNode;
else tp->next = newNode;
dSize++;
return;
}
#endif
/*
Project name : allAlgorithmsTest
Last modified Date: 2022年8月22日09点17分
Last Version: V1.0
Descriptions: 使用链表实现的字典的cpp文件
*/
#include "_23dictionaryChain.h"
using namespace std;
void dictionaryChainTest()
{
cout << endl << "******************************dictionaryChainTest()函数开始***********************************" << endl;
dictionaryChain<int, int> a;
//测试输入和输出
cout << endl << "测试输入输出*******************************************" << endl;
cout << "输入输出************************" << endl;
cin >> a;
cout << "dictionaryChain a is:" << a;
cout << endl << "测试成员函数*******************************************" << endl;
cout << "empty()*************************" << endl;
cout << "a.empty() = " << a.empty() << endl;
cout << "size()**************************" << endl;
cout << "a.size() = " << a.size() << endl;
cout << "find()**************************" << endl;
cout << "a.find(1)->second = " << a.find(1)->second << endl;
cout << "insert()************************" << endl;
pair<const int, int> insertData(3,4);
a.insert(insertData);
cout << "dictionaryChain a is:" << a;
cout << "erase()*************************" << endl;
a.erase(1);
cout << "dictionaryChain a is:" << a;
cout << "******************************dictionaryChainTest()函数结束***********************************" << endl;
}
/*
Project name : allAlgorithmsTest
Last modified Date: 2022年8月22日09点17分
Last Version: V1.0
Descriptions: 是字典的一个节点
*/
#pragma once
#ifndef _PAIRNODE_H_
#define _PAIRNODE_H_
using namespace std;
template <class K, class E>
struct pairNode
{
typedef pair<const K, E> pairType;
pairType element;
pairNode<K, E>* next;
pairNode(const pairType& thePair) :element(thePair) {}
pairNode(const pairType& thePair, pairNode<K, E>* theNext)
:element(thePair) {
next = theNext;
}
};
#endif
/*
Project name : allAlgorithmsTest
Last modified Date: 2022年8月22日09点17分
Last Version: V1.0
Descriptions: 字典的抽象类
*/
/*
pair:
介绍:是将2个数据组合成一组数据,是一个结构体,主要的两个成员变量first和second,分别存储两个数据.
使用:使用std命名空间引入对组std::pair
*/
#pragma once
#ifndef _DICTIONARY_H_
#define _DICTIONARY_H_
using namespace std;
template<class K,class E>
class dictionary
{
public:
virtual ~dictionary() {}
/*返回为true,当且仅当字典为空*/
virtual bool empty() const = 0;
/*返回字典中数对的数目*/
virtual int size() const = 0;
/*返回匹配数对的指针*/
virtual pair<const K, E>* find(const K&) const = 0;
/*删除匹配的数对*/
virtual void erase(const K&) = 0;
/*往字典中插入一个数对*/
virtual void insert(const pair<const K, E>&) = 0;
};
#endif