Phone Number Divide

本文介绍了一种针对电话号码的分组优化算法,通过将电话号码分为不同类型的小组(优秀、良好、普通),旨在最大化分组的整体质量评分。算法采用递归方式,并通过缓存已计算子序列的质量值来提高效率。

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

You are given a String number containing the digits of a phone number (the number of digits, n, can be any positive integer) . To help you memorize the number, you want to divide it into groups of contiguous digits. Each group must contain exactly 2 or 3 digits. There are three kinds of groups:

  • Excellent: A group that contains only the same digits. For example, 000 or 77.
  • Good: A group of 3 digits, 2 of which are the same. For example, 030, 229 or 166.
  • Usual: A group in which all the digits are distinct. For example, 123 or 90.

The quality of a group assignment is defined as 2 × (number of excellent groups) + (number of good groups), Divide the number into groups such that the quality is maximized. Design an e-cient algorithm to return the solution that maximizes the quality.

分析:从头开始扫描phone number,第一个group可以是2或者3个字符,分别计算剩下的序列的quality,最后得到整个序列的最大quality。此处可以使用递归,但是需要注意,可能存在重复计算的情况,可以使用数组来保存已经计算过的子序列的max quality,避免递归时的重复计算。

//返回group的quality值
static int GroupQuality(const char* group, int len){
	assert(len==2 || len==3);
	int quality = 0;
	if (group[0] == group[1]){
		if (len==2 || (len==3&&group[1]==group[2]))
			quality = 2;
		else
			quality = 1;
	} else if (len == 3 && (group[0]==group[2] || group[1]==group[2])){
		quality = 1;
	}
	return quality;
}
//计算phoneNumber的第一个分组字符数为firstGroup时对应的最大quality值和相应分组
static int PhoneNumberQuality(const char* phoneNumber, int numberLen, int firstGroup, int qualities[], string groups[], string& group){
	int quality = -1;
	group = "";
	if (numberLen==firstGroup || numberLen-firstGroup>=2){
		quality = GroupQuality(phoneNumber, firstGroup);
		group = string(phoneNumber, firstGroup);
		if (numberLen-firstGroup>=2){
			PhoneNumberSplit(phoneNumber+firstGroup, numberLen-firstGroup, qualities+firstGroup, groups+firstGroup);
			quality += qualities[firstGroup];
			group += "-"+groups[firstGroup];
		}
	}
	return quality;
}
//递归计算phoneNumber[0..numberLen-1]每个位置对应的最大quality值和相应的分组
static void PhoneNumberSplit(const char* phoneNumber, int numberLen, int qualities[], string groups[]){
	if (qualities[0] >= 0)
		return;
	assert(numberLen>=2);
	int quality = -1;
	string group;
	string tmpGroup;
	//第一个分组时3个字符的情况
	int tmpQuality = PhoneNumberQuality(phoneNumber, numberLen, 3, qualities, groups, tmpGroup);
	if (tmpQuality>quality){
		quality = tmpQuality;
		group = tmpGroup;
	}
	//第一个分组时2个字符的情况
	tmpQuality = PhoneNumberQuality(phoneNumber, numberLen, 2, qualities, groups, tmpGroup);
	if (tmpQuality>quality){
		quality = tmpQuality;
		group = tmpGroup;
	}
	qualities[0] = quality;
	groups[0] = group;
}
//返回电话号码进行分组后的最大Quality值,group返回具有最大Quanlity值得分组
int PhoneNumberSplit(const string& phoneNumber, string& group){
	int numberLen = phoneNumber.length();
	assert(numberLen>=2);
	int* qualities = new int[numberLen];
	memset(qualities, -1, sizeof(int)*numberLen);	//qualities[i]==-1表示第i个字符的quality值尚未计算
	string* groups = new string[numberLen];			//存放qualities对应的分组情况
	PhoneNumberSplit(phoneNumber.c_str(), numberLen, qualities, groups);
	int maxQuality = qualities[0];
	group = groups[0];
	delete[] qualities;
	delete[] groups;
	return maxQuality;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值