tags:C++
Vector和Set类
by –catherine
1.vector-ND类(n维向量)
#include<iostream>
#include<cstring>
#define MAX 51
using namespace std;
//注意类名的第一个字母一定要用大写
class Vector {
private:
int dimension;
int *param;
string name;
public:
Vector(); // 缺省构造函数,也称默认构造函数
Vector(string, int, int[]); // 普通构造函数
// Vector(string n = "", int d = 0, int *p = NULL)是缺省构造函数,需要定义
// 其中的变量名既可以是name, dimension,也可以是n, d
Vector(const Vector& otherVec);
~Vector();
void isEqual(const Vector& otherVec);
void setName(string);
void print();
};
//默认构造函数,此题中这个函数需要写,因为下面的缺省构造函数已经包含了这一种构造函数
//若是 Vector(string n = "", int d = 0, int *p = NULL), 则此函数不需要写
Vector::Vector() {
dimension = 0;
param = NULL;
name = "";
}
//普通构造函数
Vector::Vector(string n, int d, int *p) {
name = n;
dimension = d;
param = new int[d + 1]; // d 而不是 d+1是否可以?
// 可以是d,此处用d大概是为了防止内存非法访问(谨慎的做法)
for (int i = 0; i < d; i++)
param[i] = p[i];
cout << "construct a vector called " << name << endl;
}
// 拷贝构造函数,注意是深度拷贝,因为有指针
// 深度拷贝避免两次delete同一块内存
Vector::Vector(const Vector& otherVec) {
dimension = otherVec.dimension;
param = new int[dimension + 1]; // 先将创建的整个数组初始化是不是一个好习惯?
for (int i = 0; i < dimension; i++)
param[i] = 0;
for (int i = 0; i < dimension; i++)
param[i] = otherVec.param[i]; // 注意要一个元素一个元素进行赋值,不能直接是
// param = otherVec.param;
name = otherVec.name;
cout << "copy a vector called " << name << endl;
}
// 析构函数,delete掉前面创建的param,注意一定要先有new,才能够有delete
Vector::~Vector() {
delete []param; // delete掉数组,注意前面要有[]
}
void Vector::isEqual(const Vector& otherVec) {
if (name == otherVec.name)
cout << "same name." << endl;
else cout << "different name." << endl;
if (dimension != otherVec.dimension) {
cout << "different value." << endl;
return;
}
for (int i = 0; i < dimension; i++) {
if (param[i] != otherVec.param[i]) {
cout << "different value." << endl;
return;
}
}
cout << "same value." << endl;
}
void Vector::setName(string n) {
name = n;
}
void Vector::print() {
cout << name << "(";
for (int i = 0; i < dimension - 1; i++)
cout << param[i] << ",";
cout << param[dimension - 1] << ")" << endl;
}
int main() {
string name = "";
int dim, num[MAX];
cin >> name >> dim;
for (int i = 0; i < dim; i++) {
cin >> num[i];
}
Vector vec1(name, dim, num);
vec1.print();
Vector vec2(vec1);
vec2.print();
vec1.isEqual(vec2);
int vec3_num[] = {1, 2, 3};
Vector vec3(name, 3, vec3_num);
vec1.isEqual(vec3);
vec2.setName("helloWorld!");
vec1.isEqual(vec2);
return 0;
}
/*
input:
cookie 5 1 2 3 4 5
output:
construct a vector called cookie
cookie(1,2,3,4,5)
copy a vector called cookie
cookie(1,2,3,4,5)
same name.
same value.
construct a vector called cookie
same name.
different value.
different name.
same value.
*/
(1)类函数的4个特殊函数:缺省构造函数,拷贝构造函数,析构函数,赋值运算符重载
(2)注意构造函数不能有virtual, static, 和 valatile 来修饰
(3)在类中存在虚函数或者有虚基类的情况下需要显式声明构造函数
2.Set类
#include<iostream>
#include<algorithm> // 用到了sort函数
#define MAX_SIZE 100
using namespace std;
class Set {
private:
int size;
int members[MAX_SIZE];
public:
Set();
Set(int *m, int s);
bool append(int e);
bool remove(int e);
bool isEmptySet();
int* getMembers();
int getSize();
bool isInSet(int e);
};
// 注意集合的元素不能相同
Set::Set() {
size = 0;
}
//注意参数的传递顺序
Set::Set(int *m, int s) {
size = 0;
for (int i = 0; i < s; i++) {
if (!isInSet(m[i])) // 保证集合中的元素互不相同
members[size++] = m[i];
if (size == MAX_SIZE) break; // 每一次的算法思路都应该注意边界问题
}
}
//往集合中添加一个元素
bool Set::append(int e) {
if (!isInSet(e)&&size < MAX_SIZE) { // 合理使用已有的成员函数
members[size++] = e;
return true;
}
return false;
}
bool Set::remove(int e) {
for (int i = 0; i < size; i++) {
if (members[i] == e) {
members[i] = members[--size]; // 很神奇很简洁的一句代码
return true;
}
}
return false;
}
bool Set::isEmptySet() {
return (size == 0)?true:false; // 三元操作符简化代码
}
int* Set::getMembers() {
return members;
}
int Set::getSize() {
return size;
}
bool Set::isInSet(int e) {
for (int i = 0; i < size; i++) {
if (members[i] == e) {
return true;
}
}
return false;
}
void display(int* members, int size) {
std::sort(members, members + size);
std::cout << "{";
for (int i = 0; i < size; i++) {
if (i < size - 1) std::cout << members[i] << ", ";
else std::cout << members[i];
}
std::cout << "}" << std::endl;
}
int main(int argc, const char * argv[]) {
int test[5];
std::cin >> test[0]
>> test[1]
>> test[2]
>> test[3]
>> test[4];
// Constructor 1
Set s1 = Set();
display(s1.getMembers(), s1.getSize());
std::cout << "is empty set: " << s1.isEmptySet() << std::endl;
// append func
std::cout << "append: " << s1.append(test[0]) << std::endl;
std::cout << "append: " << s1.append(test[4]) << std::endl;
display(s1.getMembers(), s1.getSize());
// repeat append
std::cout << "append: " << s1.append(test[0]) << std::endl;
display(s1.getMembers(), s1.getSize());
std::cout << "is empty set: " << s1.isEmptySet() << std::endl;
// Constructor 2
Set s2 = Set(test, 5);
// remove func
std::cout << "remove: " << s2.remove(test[0]) << std::endl;
display(s2.getMembers(), s2.getSize());
// repeat append
std::cout << "remove: " << s2.remove(test[0]) << std::endl;
display(s2.getMembers(), s2.getSize());
return 0;
}
/*inout:
1 1 1 1 1
output:
{}
is empty set: 1
append: 1
append: 0
{1}
append: 0
{1}
is empty set: 0
remove: 1
{}
remove: 0
{}
*/
Set类中最重要的是学习如何让代码更加简洁
例如:members[i] = members[–size]以及三元操作符的使用
注意边界问题的考虑和判断
To
代码需要不断的练习才能提升,debug就是将所有可能犯的错误都犯一次,然后才知道怎样能减少错误