全面的MyString

总时间限制: 

1000ms

内存限制: 

65536kB

描述

程序填空,输出指定结果

#include 
#include 
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
{
// 在此处补充你的代码
};


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

输入

输出

1. abcd-efgh-abcd-
2. abcd-
3.
4. abcd-efgh-
5. efgh-
6. c
7. abcd-
8. ijAl-
9. ijAl-mnop
10. qrst-abcd-
11. abcd-qrst-abcd- uvw xyz
about
big
me
take
abcd
qrst-abcd-

样例输入

样例输出

1. abcd-efgh-abcd-
2. abcd-
3. 
4. abcd-efgh-
5. efgh-
6. c
7. abcd-
8. ijAl-
9. ijAl-mnop
10. qrst-abcd-
11. abcd-qrst-abcd- uvw xyz
about
big
me
take
abcd
qrst-abcd-

思路: 

  1. MyString s1("abcd-"), s2, s3("efgh-"), s4(s1);

可以看到需要构造函数,一种是char *,一种是复制构造

在构造函数和析构函数时候需要考虑c h a r ∗ char *char∗的动态分配和删除

    MyString(const char* s = NULL) {
        if (s) {
            str = new char[strlen(s) + 1];
            strcpy(str, s);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
    }
    ~MyString() {
        if (str) delete[] str;
    }
    MyString(const MyString& s) {
        if (s.str) {
            str = new char[strlen(s.str) + 1];
            strcpy(str, s.str);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
    }

MyString SArray[4] = { "big","me","about","take" };

   2.s4 = s3;s1 = "ijkl-";重载=

需要考虑的是如果是s3=s3的情况需要直接返回,如果不是的话再动态赋值

    MyString& operator= (const char* s) {
        if (str == s) {
            return *this;
        }
        delete[] str;
        if (s) {
            str = new char[strlen(s) + 1];
            strcpy(str, s);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
        return *this;
    }

    MyString& operator=(const MyString& s) {
        if (str == s.str) {
            return *this;
        }
        delete[] str;
        if (s.str) {
            str = new char[strlen(s.str) + 1];
            strcpy(str, s.str);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
        return *this;
    }


3.

s3 = s1 + s3;

s4 = "qrst-" + s2;

s1 = s2 + s4 + " uvw " + "xyz";需要重载+

    friend MyString  operator+ (const MyString& a,const MyString& b) {
        char* tmp = new char[strlen(a.str) + strlen(b.str) + 1];
        strcpy(tmp, a.str);
        strcat(tmp, b.str);
        return MyString(tmp);
    }

    friend MyString operator+ (const char* p, const MyString& s) {
        char* tmp = new char[strlen(p) + strlen(s.str) + 1];
        strcpy(tmp, p);
        strcat(tmp, s.str);
        return MyString(tmp);
    }

    friend MyString operator+ (const MyString& s, const char* p) {
        char* tmp = new char[strlen(s.str) + strlen(p) + 1];
        strcpy(tmp, s.str);
        strcat(tmp, p);
        return MyString(tmp);
    }

4:

s1[2]s1[2] = 'A' ;

需要重载[],返回引用是保证第二个赋值的实现

    char& operator[] (int i) {
        return str[i];
    }

5:

s1 += "mnop";需要重载+=

    MyString& operator+= (const char* s) {
        char* tmp = new char[strlen(str) + 1];
        strcpy(tmp, str);
        delete[] str;
        str = new char[strlen(tmp) + strlen(s) + 1];
        strcpy(str, tmp);
        strcat(str, s);
        return *this;
    }

6:

s1(5, 10)需要重载()

    char* operator() (int start, int length) {
        char* tmp = new char[length + 1];
        for (int i = start; i < start + length; ++i) {
            tmp[i - start] = str[i];
        }
        tmp[length] = '\0';
        return tmp;
    }

7:

重载流运算符<<

    friend ostream& operator<< (ostream& o,const MyString& s) {
        o << s.str;
        return o;
    }

8:

qsort(SArray,4,sizeof(MyString),CompareString); 

其中注意到CompareString里需要重载各个比较运算符

#include 
#include 
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* s = NULL) {
        if (s) {
            str = new char[strlen(s) + 1];
            strcpy(str, s);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
    }
    ~MyString() {
        if (str) delete[] str;
    }
    MyString(const MyString& s) {
        if (s.str) {
            str = new char[strlen(s.str) + 1];
            strcpy(str, s.str);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
    }
    MyString& operator= (const char* s) {
        if (str == s) {
            return *this;
        }
        delete[] str;
        if (s) {
            str = new char[strlen(s) + 1];
            strcpy(str, s);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
        return *this;
    }
    MyString& operator=(const MyString& s) {
        if (str == s.str) {
            return *this;
        }
        delete[] str;
        if (s.str) {
            str = new char[strlen(s.str) + 1];
            strcpy(str, s.str);
        }
        else {
            str = new char[1];
            str[0] = '\0';
        }
        return *this;
    }
    friend MyString  operator+ (const MyString& a,const MyString& b) {
        char* tmp = new char[strlen(a.str) + strlen(b.str) + 1];
        strcpy(tmp, a.str);
        strcat(tmp, b.str);
        return MyString(tmp);
    }
    friend ostream& operator<< (ostream& o,const MyString& s) {
        o << s.str;
        return o;
    }
    char& operator[] (int i) {
        return str[i];
    }
    MyString& operator+= (const char* s) {
        char* tmp = new char[strlen(str) + 1];
        strcpy(tmp, str);
        delete[] str;
        str = new char[strlen(tmp) + strlen(s) + 1];
        strcpy(str, tmp);
        strcat(str, s);
        return *this;
    }
    friend MyString operator+ (const char* p, const MyString& s) {
        char* tmp = new char[strlen(p) + strlen(s.str) + 1];
        strcpy(tmp, p);
        strcat(tmp, s.str);
        return MyString(tmp);
    }
    friend MyString operator+ (const MyString& s, const char* p) {
        char* tmp = new char[strlen(s.str) + strlen(p) + 1];
        strcpy(tmp, s.str);
        strcat(tmp, p);
        return MyString(tmp);
    }
    friend bool operator< (const MyString& s1,const MyString& s2) {
        if (strcmp(s1.str, s2.str) < 0) {
            return true;
        }
        else {
            return false;
        }
    }
    friend bool operator> (const MyString& s1,const MyString& s2) {
        if (strcmp(s1.str, s2.str) > 0) return true;
        else
            return false;
    }
    friend bool operator== (const MyString& s1,const MyString& s2) {
        if (strcmp(s1.str, s2.str) == 0) return true;
        else
            return false;
    }

    char* operator() (int start, int length) {
        char* tmp = new char[length + 1];
        for (int i = start; i < start + length; ++i) {
            tmp[i - start] = str[i];
        }
        tmp[length] = '\0';
        return tmp;
    }
};


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

  这道题实际上是不难的,难就难在这个程序里面需要重载的运算符是在是太多了! 

因为大家可能对以上内容有些不了解,我给大家提供一个关于运算符重载的资料:

  1. C++不允许程序员定义新的运算符(废话嘛,运算符已经够多了,还闲不够多吗?不够乱吗?)
  2. 重载过后的运算符应该符合日常的习惯:什么是日常习惯呢?举几个例子:complex_a+complex_b(我们重载的是加法这个运算符,但是函数里面写的是减法的运算,这就有点儿太坑人了)word_a>word_b(这个重载的是大于号,但是你判断写的是小于) 
  3. C++里面写运算符重载的时候不能改变运算符计算的优先级
  4. 还有一些运算符是不能进行重载的,哪些呢:".",".*","::","?:","sizeof"这些都不能进行重载.
  5. 重载某些运算符的时候,运算符重载函数必须生命为类的成员函数:(),[],->或者赋值运算符=号.
  6. 运算符重载的实质是将运算符重载为一个函数,使用运算符的表达式就被解释为对“运算符函数”的调用。
  7. 运算符可以被重载为全局函数,也可以被重载为成员函数。一般来说,倾向于将运算符重载为成员函数,这样能够较好地体现运算符和类的关系。
  8. 运算符被重载为全局函数时,函数参数的个数就是运算符的操作数个数,运算符的操作数就成为函数的实参。
  9. 运算符被重载为成员函数时,函数参数的个数就是运算符的操作数个数减一,运算符的操作数有一个成为函数作用的对象,其余的成为函数的实参。
  10. 必要时需要重载赋值运算符 “=” ,即进行深拷贝,以避免两个对象内部的指针指向同一片存储空间。
  11. 类型的名字可以作为强制类型转换运算符,也可以被重载为类的成员函数。它能使得对象被自动转换为某种类型。
  12. 重载运算符时,应该尽量保留运算符原本的用法和特性。例如重载 “+” 运算符,完成的功能就应该类似于做加法,如果在其中做减法就是不合适的;再例如,赋值运算符 “=” ,它是可以连用的,这个特性在重载后也应该保持,所以 operator= 函数一般需要返回其所作用对象的引用,以保持 “=” 连用的这个特性。
  13. 运算符重载函数不能有默认的参数,否则就改变了运算符操作数的个数,这显然是错误的
  14. 将运算符重载函数作为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的
  15. 除了‘=’运算符以外,其他的运算符重载最好设计成为友元函数。

  16. 把‘=’运算符重载为类成员变量,并且将返回值设计成为该类的引用。

  17. 一定要自定义一个拷贝构造函数,这样在重载运算符返回对象副本的时候,编译器会自动调用拷贝构造函数,否则会出现结果错误。

  18. 友元关系不会被派生类继承。

你可能感兴趣的:(C++面向对象编程(类),程序设计与算法(三)测验汇总,c++,类,运算符重载,OpenJude,MyString)