http://blog.csdn.net/wuzhekai1985/article/details/6627888
问题11:下面这个函数希望完成什么任务?
- int func(int x)
- {
- int countx = 0;
- while(x)
- {
- countx ++;
- x = x&(x-1);
- }
- return countx;
- }
解答:这个函数是求一个整数的二进制表示中含1的个数。假定x = 9999,该函数返回8。这是道微软的面试题,在《编程之美》一书中给出了若干种方法,用来求二进制数中1的个数。
问题12:以下三条输出语句分别输出什么?
- char str1[] = "abc";
- char str2[] = "abc";
- const char str3[] = "abc";
- const char str4[] = "abc";
- const char* str5 = "abc";
- const char* str6 = "abc";
- cout << boolalpha << ( str1==str2 ) << endl; // 输出什么
- cout << boolalpha << ( str3==str4 ) << endl; // 输出什么
- cout << boolalpha << ( str5==str6 ) << endl; // 输出什么
问题13: 已知String类定义如下,请实现这些函数。
- class String
- {
- public:
- String(const char *str = NULL); //默认构造函数
- String(const String &another); //拷贝构造函数
- ~String(); //析构函数
- String & operator =(const String &rhs); //赋值操作符
- private:
- char *m_data; //用于保存字符串
- };
解答:实现中有几点要注意:(1)默认构造函数中,判断str是否为空。(2)析构函数中应使用delete [ ] 运算符。(3)赋值操作符应判断是否是给自身赋值。代码如下:
- String::String(const char *str)
- {
- if(str == NULL)
- {
- m_data = new char[1];
- m_data[0] = '\0';
- }
- else
- {
- m_data = new char[strlen(str) + 1]; //需要加1,strlen返回的字符串长度并不包含'\0'
- strcpy(m_data,str);
- }
- }
- String::String(const String &another)
- {
- m_data = new char[strlen(another.m_data) + 1];
- strcpy(m_data,another.m_data);
- }
- String& String::operator=(const String &rhs)
- {
- if(this != &rhs) //防止给自身赋值
- {
- delete [] m_data;
- m_data = new char[strlen(rhs.m_data) + 1];
- strcpy(m_data,rhs.m_data);
- }
- return *this;
- }
- String::~String()
- {
- delete [] m_data; //注意是delete []
- }
解答:用KMP算法即可。基本策略是预处理子串 P ,获得其中与模式匹配有关的子字符串关系规律,从而当发生匹配失败时,可以确定继续与 T 当前位置匹配的 P 的新位置,这样就不需要在 T 中回溯了。时间复杂度为O(T+P)。
- int KMP(char *T, char *P)
- {
- int lenT = strlen(T);
- int lenP = strlen(P);
- int i = 0, j = 0;
- int *next = new int[lenP + 1]; //最后一个元素用不到
- Fail(next, P); //计算失败函数
- while(i < lenT && j < lenP)
- {
- if(j == -1 || T[i] == P[j])
- {
- i++; j++;
- }
- else
- j = next[j]; //P的下一个比较位置
- }
- delete [] next;
- if(j < lenP || j == 0)
- return -1;
- else
- return i - lenP;
- }
- //仍是一个模式匹配的过程,只不过目标串和模式串是同一串P,所以两个代码的程序很相似
- void Fail(int *next, char *P)
- {
- int lenP = strlen(P);
- int i = -1,j = 0;
- next[0] = -1;
- while(j < lenP)
- {
- if(i == -1 || P[i] == P[j])
- {
- i++; j++;
- next[j] = i;
- }
- else
- i = next[i];
- }
- }
解答:空类同样可以被实例化,每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址。