求连续最大的bit数,最近公共祖先

本文介绍了PAT编程题中的几个问题,包括最近公共祖先的求解,连续最大bit数的计算,以及字符串编辑距离的定义。在最近公共祖先问题中,给出了满二叉树节点编号的规律,通过不断除以2找到共同祖先。对于连续最大bit数,通过位运算找出二进制串中连续1的最大数量。此外,还提及了字符串的编辑距离问题,定义了插入、删除、替换字符的操作次数作为距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问答题

问答题1:若PAT是一个类,则程序运行时,语句“PAT(*ad)[3];”调用PAT的构造函数的次数是?

提示:若PAT是一个类,则程序运行时,语句 PAT( * ad)[3]; 调用构造函数次数为0 ;说白了这是一个数组指针,该数组里有三个元素;这里仅仅只是定义指针,并没有实例化;所以调用次数为0;但是如果将语句改为 PAT ad[3];那应该就是实例化三次了;

问答题2:定义char dog[]="wang\0miao"; 那么sizeof(dog)strlen(dog) 分别是多少?

提示:sizeof 计算的是所占字节数,\0 算一个字节,结尾也有一个\0 strlen 是计算字符串的长度,但是字符串的结尾符是由 \0 来判断的,所以遇到第一个 \0 为止就结束了,剩下的字符串miao 在栈缓冲区中.

问答题3:假设寄存器为8位,用补码形式存储机器数,包括一位符号位,那么十进制数-25在寄存器表示为?

提示:对于正数来说,源码,反码,补码都一样,但是对于负数来说,反码为源码的取反,补码 = 反码+1 ;所以 -25的源码为
1 0 0 1 1 0 0 1 ,取反为 1 1 1 0 0 1 1 0(最高位不变,因为它代表的是符号位) 反码加1 为 1 1 1 0 0 1 1 1 ,用十六进制表示为 E7其中H代表这是一个十六进制.

答案:E7H 或者 0xE7

问答题4:下面代码的执行结果是什么?

char ccString1[] = "Is Page Fault??";
	char ccString2[] = "No Page Fault??";
	strcpy(ccString1, "No");
	if (strcmp(ccString1, ccString2) == 0) {
		cout << ccString2;
	}
	else {
		cout << ccString1;
	}

提示:strcpy 是将第二个字符串进行拷贝覆盖到第一个字符串,返回第一个参数的字符串. strcmp 是根据字典序的比较规则去比较两个字符串.如果相等返回0,如果 第一个参数大于第二个参数返回一个正数,否则返回一个负数,注意这里的正负数不一定是1或-1,根据编译器来判断.

答案:No

问答题5:下面代码有错误,如何修改?

class A {
public:
	int GetValue() const {
		vv = 1;
		return vv;
	}
private:
	int vv;
};

提示:const 成员函数里面不可以重新赋值,因为会不安全,而mutable 就是为了突破这个限制的,可以理解为 const 的‘克星’,被 mutable 修饰的变量是可变状态的,即使在const函数中.

答案:去掉 const 或者在 int vv;语句前面加 mutable

问答题6:若用一个大小为6的数组来实现循环队列,且当前rearfront的值分别为 0 和 3 ,当从队列中删除一个元素,再加入两个元素后, rearfront 的值分别为多少?

提示:插入1个新元素,(尾指针+1%)size,删除一个元素,(头指针+1)%size

答案:2 ,4

问答题7:一棵完全二叉树第六层有9个叶结点(根为第一层),则结点个数最多有?

提示:如果第六层有9个叶节点,那么最多的情况就是,第六层满,第七层差18个节点满

答案:2^7-1-18 = 109

问答题8:已知一个线性表(38,25,74,63,52,48),假定采用散列函数h(key) = key%7 计算散列地址,并散列存储在散列表A【0…6】中,若采用线性探测方法解决冲突,则在该散列表上进行等概率成功查找的平均查找长度为?

提示:
38%7=3 (第1次出现3,无冲突,放在位置3,查找次数为1)

25%7=4(第1次出现4,无冲突,放在位置4,查找次数为1)

74%7=4(第2次出现4,有冲突,放在位置5,查找次数为2)

63%7=0(第1次出现0,无冲突,放在位置0,查找次数为1)

52%7=3(第2次出现3,有冲突,发现冲突3,4,5,故只能放到6,查找次数为4)

48%7=6 (第1次出现6,有冲突,发现冲突6,1,故只能放到1,查找次数为3)

答案:(1+1+2+1+4+3)÷ 6 = 2

最近公共祖先

有一棵无穷大的满二叉树,其结点按根结点一层一层地从左往右依次编号,根结点编号为1。现在有两个结点a,b。请设计一个算法,求出a和b点的最近公共祖先的编号。给定两个int a,b。为给定结点的编号。请返回a和b的最近公共祖先的编号。注意这里结点本身也可认为是其祖先。

测试样例:2,3
返回:1

提示:最近公共祖先表示距离两个节点最近的公共父节点,这道题考察二叉树,题目所描述的满二叉树如下

     1 
   /   \ 
  2     3
 / \   / \
4   5 6   7 

上述树中子节点与父节点之间的关系为 root = child / 2,所以如果a != b,就让其中的较大数除以2, 如此循环直到a == b 即是原来两个数的最近公共祖先

例:2 和 7 的最近公共祖先:7/2 = 3 —> 3/2 = 1, 2/2 = 1, 得到1为它们的公共祖先

int getLCA(int a, int b){
	while (a != b){
		if (a > b){
			a /= 2;
		}else{
			b /= 2;
		}
	}
	return a;
}

求连续最大的 bit 数

求一个 byte 数字对应的二进制数字中 1 的最大连续数

示例1:输入:3 输出:2
解释 3 的二进制为 000… 00000011,最大连续2个1

提示:考察的是位运算;获取每一位的二进制值,获取第 i 位的值方法是: (n >> i) & 1;如果1连续,则计数累加,如果不连续,则从0开始计数。

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main(){
	int n;
	while (cin >> n){
		int count = 0, maxCount = 0;
		while (n){
			if (n & 1){
				//如果1的值连续,计数累加,否则重新赋值为0
				++count;
				maxCount = max(count, maxCount);
			}
			else{
				count = 0;
			}
			n = n >> 1;
		}
		cout << maxCount << endl;
	}
	return 0;
}

编程题3:计算字符串的距离

Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数

许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。编辑距离的算法是首先

字符串A:abcdefg
字符串B: abcdef
通过增加或是删掉字符”g”的方式达到目的。这两种方案都需要一次操作。把这个操作所需要的次数定义为两个字符串的距离

输入:字符串A和字符串B
返回:如果成功计算出字符串的距离,否则返回-1

提示:动态规划

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int minDistance(string word1, string word2) {
	// word与空串之间的编辑距离为word的长度
	if (word1.empty() || word2.empty()) {
		return max(word1.size(), word2.size());
	}
	int len1 = word1.size();
	int len2 = word2.size();
	// F(i,j)初始化
	vector<vector<int> > f(1 + len1, vector<int>(1 + len2, 0));
	for (int i = 0; i <= len1; ++i) {
		f[i][0] = i;
	}
	for (int i = 0; i <= len2; ++i) {
		f[0][i] = i;
	}
	for (int i = 1; i <= len1; ++i) {
		for (int j = 1; j <= len2; ++j) {
			// F(i,j) = min { F(i-1,j)+1, F(i,j-1) +1, F(i-1,j-1) +
			//(w1[i]==w2[j]?0:1) }
			// 判断word1的第i个字符是否与word2的第j个字符相等
			if (word1[i - 1] == word2[j - 1]) {
				f[i][j] = 1 + min(f[i][j - 1], f[i - 1][j]);
				// 字符相等,F(i-1,j-1)编辑距离不变
				f[i][j] = min(f[i][j], f[i - 1][j - 1]);
			}
			else {
				f[i][j] = 1 + min(f[i][j - 1], f[i - 1][j]);
				// 字符不相等,F(i-1,j-1)编辑距离 + 1
				f[i][j] = min(f[i][j], 1 + f[i - 1][j - 1]);
			}
		}
	}
	return f[len1][len2];
}

int main() {
	string a, b;
	while (cin >> a >> b)
		cout << minDistance(a, b) << endl;

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿的温柔香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值