郭伟 程序设计与算法(三)习题选解

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:返回什么才好呢

image
注意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的用法,不能乱用,尤其是**pp[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;
}
posted @ 2022-10-15 23:42  520Enterprise  阅读(84)  评论(0编辑  收藏  举报