郭伟 程序设计与算法(三)习题选解
002:难一点的swap
这个题有点意思,注意理解指针的含义.
002.cpp
#include <iostream>
using namespace std;
void swap(
// 在此处补充你的代码
int *&a, int *&b
)
{
int * tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 3,b = 5;
int * pa = & a;
int * pb = & b;
swap(pa,pb);
cout << *pa << "," << * pb;
return 0;
}
004:神秘的数组初始化
注意new int[]会给指针分配一段连续的地址,或许可以用这个实现vector?
004.cpp
#include <iostream>
using namespace std;
int main()
{
int *a[] = {
// 在此处补充你的代码
NULL, NULL, new int, new int[5]};
*a[2] = 123;
a[3][5] = 456;
if (!a[0])
{
cout << *a[2] << "," << a[3][5];
}
return 0;
}
006 奇怪的类复制
填代码使得输出为9 22 5
比较有意思,关键点在于需要了解复制构造函数什么时候会调用(注意函数传参时实参赋值给形参会调用)
006.cpp
#include <iostream>
using namespace std;
class Sample
{
public:
int v;
// 在此处补充你的代码
Sample(int i = 0) : v(i){};
Sample(const Sample &a)
{
v = 2 + a.v;
}
};
void PrintAndDouble(Sample o)
{
cout << o.v;
cout << endl;
}
int main()
{
Sample a(5);
Sample b = a;
PrintAndDouble(b);
Sample c = 20;
PrintAndDouble(c);
Sample d;
d = a;
cout << d.v;
return 0;
}
007:返回什么才好呢
注意this指针的使用,this会指向现在正在调用的对象
007.cpp
#include <iostream>
using namespace std;
class A
{
public:
int val;
A(int
// 在此处补充你的代码
x = 123) : val(x){};
A &GetObj()
{
return *this;
}
};
int main()
{
int m, n;
A a;
cout << a.val << endl;
while (cin >> m >> n)
{
a.GetObj() = m;
cout << a.val << endl;
a.GetObj() = A(n);
cout << a.val << endl;
}
return 0;
}
012:这个指针哪来的
注意常量成员函数的用法:对常量之类使用常量成员函数
012.cpp
#include <iostream>
using namespace std;
struct A
{
int v;
A(int vv) : v(vv) {}
// 在此处补充你的代码
const A* getPointer() const
{
return this;
}
};
int main()
{
const A a(10);
const A *p = a.getPointer();
cout << p->v << endl;
return 0;
}
013:魔兽世界之一:备战
大模拟,不过被yyz diss"封装个类就是面向对象了是吧😰"了,看来还要继续深入理解,精进面向对象编程技术
013.cpp
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
enum NAME
{
DRAGON = 0,
NINJA,
ICEMAN,
LION,
WOLF
};
const int type_num = 5;
const char name[type_num][10] = {"dragon", "ninja", "iceman", "lion", "wolf"};
int hp[type_num], q, m, n = 1, minHP;
int birthOrder[2][type_num] = {{ICEMAN, LION, WOLF, NINJA, DRAGON}, {LION, DRAGON, NINJA, ICEMAN, WOLF}};
class Headquarter
{
private:
int life, sequence[type_num], time, typeNow, num[type_num], numSum, flagOfStop;
string selfName;
public:
Headquarter(int t, int l, int s[], string n) : time(t), life(l)
{
memcpy(sequence, s, sizeof(sequence));
memset(num, 0, sizeof(num));
selfName = n;
typeNow = 0;
numSum = 0;
flagOfStop = 0;
}
~Headquarter() {}
void produceWarrior()
{
if (life < minHP)
{
if (!flagOfStop)
{
printf("%03d ", time);
cout << selfName << " headquarter stops making warriors" << endl;
}
flagOfStop = 1;
return;
}
while (life < hp[sequence[typeNow]])
typeNow = (typeNow + 1) % type_num;
int warriorNow=sequence[typeNow];
life -= hp[warriorNow];
++numSum,++num[typeNow];
printf("%03d ", time);
cout << selfName << ' ' << name[warriorNow]<<' '<<numSum<<" born with strength "\
<<hp[warriorNow]<<','<<num[typeNow]<<' '<<name[warriorNow]<<" in "\
<<selfName<<" headquarter"<<endl;
typeNow = (typeNow + 1) % type_num;
++time;
}
int isStop() { return flagOfStop; }
};
int main()
{
/* freopen("in.txt","r",stdin);
freopen("outt.txt","w",stdout); */
cin >> q;
while (q--)
{
cout << "Case:" << n << endl;
++n, minHP = 10000000;
cin >> m;
for (int i = 0; i < type_num; ++i)
cin >> hp[i], minHP = min(minHP, hp[i]);
Headquarter red(0, m, birthOrder[0], "red");
Headquarter blue(0, m, birthOrder[1], "blue");
while ((!red.isStop()) || (!blue.isStop()))
{
red.produceWarrior();
blue.produceWarrior();
}
}
return 0;
}
014:MyString
注意运算符重载(尤其记住对流输出的重载写法,很有用)
014.cpp
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class MyString
{
char *p;
public:
MyString(const char *s)
{
if (s)
{
p = new char[strlen(s) + 1];
strcpy(p, s);
}
else
p = NULL;
}
~MyString()
{
if (p)
delete[] p;
}
// 在此处补充你的代码
MyString(const MyString &x)
{
if (x.p)
{
p = new char[strlen(x.p) + 1];
strcpy(p, x.p);
}
else
p = NULL;
}
MyString() {}
void Copy(const char *str)
{
if (str)
{
p = new char[strlen(str) + 1];
strcpy(p, str);
}
else
p = NULL;
}
MyString &operator=(const MyString &x)
{
if (p == x.p)
return *this;
if(p)
delete[] p;
if (x.p)
{
p = new char[strlen(x.p) + 1];
strcpy(p, x.p);
}
else
p = NULL;
return *this;
}
friend ostream& operator <<(ostream& os, const MyString& x)
{
os<<x.p;
return os;
}
};
int main()
{
char w1[200], w2[100];
while (cin >> w1 >> w2)
{
MyString s1(w1), s2 = s1;
MyString s3(NULL);
s3.Copy(w1);
cout << s1 << "," << s2 << "," << s3 << endl;
s2 = w2;
s3 = s2;
s1 = s3;
cout << s1 << "," << s2 << "," << s3 << endl;
}
}
016:惊呆!Point竟然能这样输入输出
注意const不要乱加!!!
016.cpp
#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(){};
// 在此处补充你的代码
friend istream& operator >>(istream& is,Point& a)
{
is>>a.x>>a.y;
return is;
}
friend ostream& operator <<(ostream& os,const Point& a)
{
os<<a.x<<','<<a.y;
return os;
}
};
int main()
{
Point p;
while (cin >> p)
{
cout << p << endl;
}
return 0;
}
017:二维数组类
这里要非常注意memcpy的用法,不能乱用,尤其是**p
和p[x][y]
这两种方式构造数组的方式是不一样的.同时还需要注意不能delete
两次,不能在delete[] p[i]
之后又去delete[] p
017.cpp
#include <iostream>
#include <cstring>
using namespace std;
class Array2
{
// 在此处补充你的代码
private:
int **p;
int column, row;
public:
Array2(int x = 0, int y = 0) : row(x), column(y)
{
if (!x || !y)
p = NULL;
else
{
p = new int *[row];
for (int i = 0; i < row; ++i)
p[i] = new int[column];
}
}
~Array2()
{
if (p)
{
for (int i = 0; i < row; ++i)
delete[] p[i], p[i] = NULL;
}
p = NULL;
}
int *&operator[](int r) { return p[r]; }
int &operator()(int r, int c) const { return p[r][c]; }
Array2 &operator=(const Array2 &x)
{
if (p)
{
for (int i = 0; i < row; ++i)
delete[] p[i], p[i] = NULL;
}
p = NULL;
row = x.row, column = x.column;
if (row && column)
{
p = new int *[row];
for (int i = 0; i < row; ++i)
p[i] = new int[column];
for(int i=0;i<row;++i)
for(int j=0;j<column;++j)
p[i][j]=x.p[i][j];
}
return *this;
}
};
int main()
{
Array2 a(3, 4);
int i, j;
for (i = 0; i < 3; ++i)
for (j = 0; j < 4; j++)
a[i][j] = i * 4 + j;
for (i = 0; i < 3; ++i)
{
for (j = 0; j < 4; j++)
{
cout << a(i, j) << ",";
}
cout << endl;
}
cout << "next" << endl;
Array2 b;
b = a;
for (i = 0; i < 3; ++i)
{
for (j = 0; j < 4; j++)
{
cout << b[i][j] << ",";
}
cout << endl;
}
a.~Array2();
b.~Array2();
return 0;
}
018:别叫,这个大整数已经很简化了!
面向对象版高精度,有个坑,我一开始在类里面定义了一个len来表示他的长度,但是在重载的时候我没有在返回值里面赋len的值,于是被初始化为0导致WA掉了,后来我就直接不要这个了,用到的时候现场算即可.
018.cpp
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;
const int MAX = 110;
class CHugeInt
{
// 在此处补充你的代码
private:
char hugeInt[2 * MAX];
public:
void reverse(char *_hugeInt)
{
int len = strlen(_hugeInt);
int l = 0, r = len - 1;
while (l <= r)
{
swap(_hugeInt[l], _hugeInt[r]);
++l, --r;
}
}
CHugeInt(const char *_hugeInt)
{
memset(hugeInt, '\0', sizeof(hugeInt));
strcpy(hugeInt, _hugeInt);
reverse(hugeInt);
}
CHugeInt(const int &_hugeInt)
{
memset(hugeInt, '\0', sizeof(hugeInt));
sprintf(hugeInt, "%d", _hugeInt);
reverse(hugeInt);
}
CHugeInt operator+(const CHugeInt &_hugeInt) const
{
CHugeInt tmp(0);
int carry = 0;
for (int i = 0; i < 2 * MAX; ++i)
{
char c1 = hugeInt[i], c2 = _hugeInt.hugeInt[i];
if (c1 == '\0' && c2 == '\0' && carry == 0)
{
/* cout<<i<<" NMSL"<<endl; */
break;
}
if (c1 == '\0')
c1 = '0';
if (c2 == '\0')
c2 = '0';
int now = c1 - '0' + c2 - '0' + carry;
if (now > 9)
{
carry = 1;
now -= 10;
}
else
carry = 0;
tmp.hugeInt[i] = now + '0';
}
return tmp;
}
CHugeInt operator+(const int &_n) const { return *this + CHugeInt(_n); }
friend CHugeInt operator+(const int &_n, const CHugeInt &_hugeInt) {return _hugeInt + CHugeInt(_n);}
CHugeInt operator+=(const int &_n)
{
*this=*this+CHugeInt(_n);
return *this;
}
CHugeInt operator++()
{
*this=*this+CHugeInt(1);
return *this;
}
CHugeInt operator++(int)
{
CHugeInt tmp(*this);
*this = tmp+CHugeInt(1);
return tmp;
}
friend ostream& operator<<(ostream &os, const CHugeInt &_hugeInt)
{
int len=strlen(_hugeInt.hugeInt);
for(int i=len-1;i>=0;--i)
os<<_hugeInt.hugeInt[i];
return os;
}
};
int main()
{
char s[210];
int n;
while (cin >> s >> n)
{
CHugeInt a(s);
CHugeInt b(n);
/* CHugeInt c(a+b);
cout<<a<<" + "<<b<<" = "<<c<<endl; */
cout << a + b << endl;
cout << n + a << endl;
cout << a + n << endl;
b += n;
cout << ++b << endl;
cout << b++ << endl;
cout << b << endl;
}
return 0;
}
019:全面的MyString
注意重载等号,一开始被这个卡了好久
019.cpp
#include <cstdlib>
#include <iostream>
using namespace std;
int strlen(const char *s)
{
int i = 0;
for (; s[i]; ++i)
;
return i;
}
void strcpy(char *d, const char *s)
{
int i = 0;
for (i = 0; s[i]; ++i)
d[i] = s[i];
d[i] = 0;
}
int strcmp(const char *s1, const char *s2)
{
for (int i = 0; s1[i] && s2[i]; ++i)
{
if (s1[i] < s2[i])
return -1;
else if (s1[i] > s2[i])
return 1;
}
return 0;
}
void strcat(char *d, const char *s)
{
int len = strlen(d);
strcpy(d + len, s);
}
class MyString
{
// 在此处补充你的代码
private:
char *str;
public:
MyString(const char *_str = NULL)
{
if (_str)
{
str = new char[strlen(_str) + 1];
strcpy(str, _str);
}
else
{
str = new char[1];
str[0] = '\0';
}
}
MyString(const MyString &_MyString)
{
if (_MyString.str)
{
str = new char[strlen(_MyString.str) + 1];
strcpy(str, _MyString.str);
}
else
{
str = new char[1];
str[0] = '\0';
}
}
~MyString()
{
if (str)
delete[] str;
}
MyString &operator=(const MyString &_MyString)
{
if (str)
delete[] str;
if (_MyString.str)
{
str = new char[strlen(_MyString.str) + 1];
strcpy(str, _MyString.str);
}
else
{
str = new char[1];
str[0] = '\0';
}
return *this;
}
MyString operator+(const char *_str)
{
char *tmp=new char[strlen(str)+strlen(_str)+1];
strcpy(tmp,str);
if(_str)
strcat(tmp,_str);
return MyString(tmp);
}
MyString operator+(const MyString &_MyString)
{
char *tmp = new char[strlen(str) + strlen(_MyString.str) + 1];
strcpy(tmp, str);
strcat(tmp, _MyString.str);
return MyString(tmp);
}
friend MyString operator+(const MyString &_MyString1,const MyString &_MyString2)
{
char *tmp = new char[strlen(_MyString2.str) + strlen(_MyString1.str) + 1];
strcpy(tmp, _MyString1.str);
strcat(tmp, _MyString2.str);
return MyString(tmp);
}
MyString operator+=(const char *_str)
{
*this=*this+_str;
return *this;
}
bool operator<(const MyString &_MyString)
{
return strcmp(str,_MyString.str)==-1;
}
bool operator>(const MyString &_MyString)
{
return strcmp(str,_MyString.str)==1;
}
bool operator==(const MyString &_MyString)
{
return strcmp(str,_MyString.str)==0;
}
char& operator[](const int &_pos)const
{
return this->str[_pos];
}
char* operator()(const int &left,const int &len)const
{
int right=left+len-1;
char *tmp=new char[right-left+1];
for(int i=left;i<=right;++i)
tmp[i-left]=str[i];
tmp[right-left+1]='\0';
return tmp;
}
friend ostream &operator<<(ostream &os, const MyString &_MyString)
{
os << _MyString.str;
return os;
}
};
int CompareString(const void *e1, const void *e2)
{
MyString *s1 = (MyString *)e1;
MyString *s2 = (MyString *)e2;
if (*s1 < *s2)
return -1;
else if (*s1 == *s2)
return 0;
else if (*s1 > *s2)
return 1;
}
int main()
{
MyString s1("abcd-"), s2, s3("efgh-"), s4(s1);
MyString SArray[4] = {"big", "me", "about", "take"};
cout << "1. " << s1 << s2 << s3 << s4 << endl;
s4 = s3;
s3 = s1 + s3;
cout << "2. " << s1 << endl;
cout << "3. " << s2 << endl;
cout << "4. " << s3 << endl;
cout << "5. " << s4 << endl;
cout << "6. " << s1[2] << endl;
s2 = s1;
s1 = "ijkl-";
s1[2] = 'A';
cout << "7. " << s2 << endl;
cout << "8. " << s1 << endl;
s1 += "mnop";
cout << "9. " << s1 << endl;
s4 = "qrst-" + s2;
cout << "10. " << s4 << endl;
s1 = s2 + s4 + " uvw " + "xyz";
cout << "11. " << s1 << endl;
qsort(SArray, 4, sizeof(MyString), CompareString);
for (int i = 0; i < 4; i++)
cout << SArray[i] << endl;
// s1的从下标0开始长度为4的子串
cout << s1(0, 4) << endl;
// s1的从下标5开始长度为10的子串
cout << s1(5, 10) << endl;
return 0;
}
EntyEnty520~