笔试面试题目8

1. 写一个 String类,以及构造函数能是虚函数吗?
class string
{
	friend std::istream& operator>>(std::istream& is, string& str);
	friend std::ostream& operator<<(std::ostream& os, string& str);	
public:
	string()     //默认构造函数
	{ 
		m_length = 0;
		m_pdata = new char[1];
		m_pdata[0] = '\0';
	}
	
	string( char *str = NULL);		// 构造函数
	string( int len, char ch);
	~string();						// 析构函数
	string( string &str);  			// 复制构造函数
	int size(){ return m_length;}	// 获得字符串长度
	string operator+(const string& str);	// 重载'+'操作符
	string& operator+=(const string& str);	// 重载'+='操作符
	string& operator=(const string& str);	// 重载赋值操作符
	bool operator==(const string &s1,const string &s2);	// 比较两个字符串是否相等
	char& operator[]( int index);			// 重载下标操作符
	string substr( int pos,int len);		// 返回子字符串
	string substr( int pos);   				// 返回子字符串

 private:
	char *m_pdata;
	int m_length;
};

string::string(char *str)     // 构造函数
{
	m_length = strlen(str);
	m_pdata = new char[length+1];
	if(m_pdata != NULL)
	{
		strcpy( m_pdata, str);	
	}
}

string::string( int len, char ch);
{
	m_pdata = new char[len+1];
	for(int  i = 0; i < n; i++)
	{
		m_pdata[i] =a;
	}
	m_pdata[len] = '\0';
}

string::~string()     // 析构函数
{
	if( m_pdata != NULL)
	{
		delete [] m_pdata;	
	}	
	length = 0;
}

string::string(string &str)      // 复制构造函数
{
	m_length = str.size();
	m_pdata = new char[length+1];
	for( int i = 0; i < length; i++)
	{
		m_pdata[i] = str.m_pdata[i];
	}
	b[m_length] = '\0';
}

string string::operator+(const string& str)    // 重载+
{
	int newLen = m_length + str.m_length;
	char *newstr = new char[newLen+1];
	int count = 0;
	for( int i = 0; i<length; i++)
	{
		newstr[i] = this->b[i];
		count++;
	}	
	for( int i =0; count < newLen; count++,i++)
	{
		newstr[i] = a.b[i];
	}
	newstr[newLen] = '\0';
	string temp(newstr);
	delete [] newstr;
	return temp;
}

string& string::operator+=(const string& str)   // 重载+=
{
	int newLen = length + str.length;
	char *newstr = new char[newLen+1];
	int count = 0;
	for(int i = 0; i < length; i++)
	{
		newstr[i] = this->m_pdata[i];
		count++;
	}
	
	for(int i =0;count<newLen;count++,i++)
	{
		newstr[i] = str.m_pdata[i];
	}
	newstr[newLen] = '\0';
	string temp(newstr);
	*this = temp;
	delete [] newstr;
	return *this;
}

string& string::operator=(const string &str)    // 重载=
{
	if(this == &str)
		return *this;

	delete [] m_pdata;
	m_length = str.m_length;
	m_pdata = new char[m_length+1];
	for(int i = 0; i < m_length; i++)
	{
		b[i] = a.b[i];
	}
	b[length] = '\0';
	return *this;
}

bool string::operator==(const string &s1,const string &s2)
{
	if( s1.m_length != s2.m_length)
	{
		return false;	
	}
	
	for( int i = 0; i < s1.m_length && i < s2.m_length; i++)
	{
		if( s1.m_data[i] != s2.m_data[i])
		{
			return false;
		}	
	}
	
	return true;
}

char& string::operator[]( int index)  	// 重载下标操作符
{
	if( index > m_length)
		return m_pdata[m_length-1];
	else
		return m_pdata[index];
}

ostream& operator<<(ostream& os, string& str)  //重载输出符
{
	os << str.m_pdata;
	return os;
}

istream& operator>>( std::istream& is, string& str)  //重载输入符
{   
	is >> str.m_pdata;
	str.m_length = strlen(str.m_pdata);
	return is;
}

string string::substr( int pos, int len)    // 两个接受不同参数的substr函数,返回子字符串
{
	char *p = new char[n+1];
	for(int i=0;i<n;i++)
	{
		p[i]=b[pos];
		pos++;
	}
	p[n]='\0';
	string k(p);
	k.m_length=n;
	delete [] p;
	return k;
}

string string::substr( int pos)
{
	int len = m_length;
	char *p = new char[len-pos+1];
	int t = pos;
	for( int i = 0; t < len; t++,i++)
	{
		p[i] = b[t];
	}
	p[t]='\0';
	string k(p);
	k.m_length = len-pos;
	delete [] p;
	return  k;
}
        运算符 ">", "<", ">=", "<="和"!="均需要被重载用于字符串的比较,此处省略。
构造函数能够声明为虚函数?
        由虚函数的机制我们可知,每个类需要一个虚函数表,虚函数表的指针放在本类对象的最前面四个字节(一个指针的大小)。
        虚函数表的初始化是在本类的构造函数调用时完成的,因此即使将构造函数声明为虚函数也不起作用。

2. 在一个Array中,有一些数字为0,那么将 这些为0的数字所在的行,列都设置为0。但是对于新设置的元素,不再对其进行重复设置
1  2  3 
4  0  5
6  7  0
        在本题目中,(1,1)处元素为0,(2,2)出元素为0,这样将第一行,第一列(从0列开始),第二行,第二列的元素都设置为0。对于(0,1)处的元素为新设置为0的元素,因此不需要对其所在行列进行设置了。
        直接使用一个动态Array,将为0的元素下标(row,col)放入到数组中,再遍历数组中的元素,依次将元素对应的行列置为0。

3. 二叉树,找到其中两个节点的公共祖先。
        见前面的题目中,里面有寻找节点路径的题目,本题目就在那个题目的基础上加上,寻找两个节点的路径,再分别寻找路径中第一个不同节点的上一个节点,即为我们要寻找的公共节点。

4. 一个整数A,寻找由A的各位上的数字组成的比A大的整数里面那个最小的整数。
        例如: 12345,比它大的数字中最小的数字,12354
                     134651 对应要找的数字应该为 135146
        思路:首先将整数转化为字符串,放到数组中,然后从数字的最低位开始查找,第一个有比其低的位数字小的一个数,将其与比起低的位中最大数进行交换。
再对所找到数字的低位进行排序(升序)。即可得到题目答案。
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void PrintBiggerNum( unsigned int Num)
{
    int num[30] = {0};
    int count = 0;
    unsigned int tmp = Num;
    while( tmp > 0)
    {
        num[count++] = tmp % 10;
        tmp /= 10;
    }

    int max = 0;
    int i = 0;
    for( i = 0; i < count; i++)
    {
        if( max < num[i] && i != 0)
        {
            max = num[i];
        }
        else if(max > num[i] && i != 0)
        {
            for( int j = 0; j < i; j++)
            {
                if( num[j] > num[i])
                {
                    tmp = num[i];
                    num[i] = num[j];
                    num[j] = tmp;
                    break;
                }
            }
            break;
        }
    }

    sort(num, num+i, greater<int>());

    cout << Num << " ---> ";
    for( int i = count-1; i >= 0; i--)
    {
        cout << num[i];
    }
    cout << endl;

    return ;
}

int main()
{
    PrintBiggerNum(134651);
    return 0;
}
5. 数组逆时针旋转90度,以及证明你的方法的有效性
        1 2 3         3 6 9
        4 5 6 --->  2 5 8
        7 8 9         1 4 7
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
#define ARRAY_LEN 3
int NumArray[ARRAY_LEN][ARRAY_LEN];

void RotateArray()
{
    int i = 0, j = 0;
    for( i = 0; i < ARRAY_LEN; i++)
    {
        for( j = i+1; j < ARRAY_LEN; j++)
        {
            int temp = NumArray[i][j];
            NumArray[i][j] = NumArray[j][i];
            NumArray[j][i] = temp;
        }
    }

    for( i = 0; i < ARRAY_LEN/2; i++)
    {
        for( j = 0; j < ARRAY_LEN; j++)
        {
            int temp = NumArray[i][j];
            NumArray[i][j] = NumArray[ARRAY_LEN - 1 - i][j];
            NumArray[ARRAY_LEN - 1 - i][j] = temp;
        }
    }

    return ;
}

int main()
{
    int index = 1;
    for( int i = 0; i < ARRAY_LEN; i++)
    {
        for( int j = 0; j < ARRAY_LEN; j++)
        {
            NumArray[i][j] = index++;
        }
    }

    for( int i = 0; i < ARRAY_LEN; i++)
    {
        for( int j = 0; j < ARRAY_LEN; j++)
        {
            cout << NumArray[i][j] << " ";
        }
        cout << endl;
    }
    cout << "<------------->" << endl;

    RotateArray();

    for( int i = 0; i < ARRAY_LEN; i++)
    {
        for( int j = 0; j < ARRAY_LEN; j++)
        {
            cout << NumArray[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}	
对于证明其正确性:
        可以将整个矩阵放到坐标轴上,一个点代表其对应的坐标值。

        可以推导出相应的坐标对应。


By Andy @ 2013年11月1日

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值