以下几道算法题,本来是要求用C语言解答的,这里用Java来实现,并不是最好的解法,只是一个思路。
1. 字符串重排
- 输入最多10个大写字母(可重复),求其排列的总数
- 例1 输入ABA -->输出 3
- 例2 输入AABBCC -->输入 90
- 例3 输入AABCDEFGHH --输出 907200
- 思路:
- 1.根据排列组合,去找出规律,按照重复的数字分组
- (1)完全不重复:n!
- (2)有一个重复m次,先从n个数中取m个位置,剩下的位置排列一下:
- C(n,m)*A(m,m)
- (3)多个字母重复,最多重复的同字母是全部为同一个字母:10个(AAAAAAAAAA),
- 重复的不同字母最多5个(AABBCCDDEE)
- 与(2)相似,先排重复的字母:C(10,10)=1;C(10,2)*C(8,2)*C(6,2)*C(4,2)*C(2,2)
- 代码实现:
- 1.阶乘计算
- 2.求出字符串的总长len,
- 重复的字符种类:arr[0]
- 重复的字母的个数:arri
public class Exem02 {
public static int ss(String str) {
int[] arr = ss2(str);
int len = str.length();
int count = 0;
if (len == 0)
return 0;
int sum = 1;
// 重复字母先排
for (int i = 1; i < arr.length; i++) {
if (arr[i] == 0)
break;
else
count += arr[i];
if (len - arr[i] > 0) {
sum = sum * jiecheng(len) / (jiecheng(len - arr[i]) * jiecheng(arr[i]));
len = len - arr[i];
}
}
// 余下不重复的数字排序
if (count < str.length())
sum = sum * jiecheng(str.length() - count);
return sum;
}
// 阶乘计算n>0
public static int jiecheng(int n) {
if (n == 1) {
return 1;
} else {
return n * jiecheng(n - 1);
}
}
// * 重复的字符种类:arr[0]
// * 重复的字母的个数:arr[i](0<i<6)
public static int[] ss2(String str) {
int[] arr = new int[6];
int index = 1;
char[] chs = str.toCharArray();
for (int i = 0; i < chs.length - 1; i++) {
if (chs[i] == '0')
continue;
int repeat = 1;
for (int j = i + 1; j < chs.length; j++) {
if (chs[i] - chs[j] == 0) {
repeat++;
chs[j] = '0';
}
}
if (repeat >= 2) {
arr[0]++;
arr[index++] = repeat;
}
}
return arr;
}
}
2. 爆满的旅行社
- 旅馆共有m个房间,输入字符串,一个字符指该客人入住时间与离开时间,要求:
- 如果当客人入住时,没有房间,则输出:“还有k位客人没有入住”
- 如果所有客人都入住了,就输入:“所有客人都入住”(最多26位客人)
- 思路:
- 1.用标记(0,1)判断客人是否入住
- 建立一个大小为26*2的数组(最多26位客人),前26个数表示客人的ASCLL码,后26个数用来标记是否入住
- roomCount 表示已经住人的房间,当遍历结束字符串时,roomCount<=m,则说明可以全部住下;反之,则不能
- 2.计算还未住进来的客人数,只要遍历roomCount>m时且还没有住进来(即标记为1)的人数就可以了
- 3.改进:可以考虑减小数组的大小
- 代码实现
public class Exem03 {
public static String s2(int m, String c) {
char[] cs = c.toCharArray();
int c_num = cnum(c);// 计算出客人的总数(重复的算1位)
if (m == 0) {
return "还有" + c_num + "位客人没有入住";
} else if (m >= 26) {
return "所有客人都入住";
}
// 设计房间
int[] rooms = new int[52];
for (int i = 0; i < 25; i++) {
rooms[i] = 'A' + i;
}
int roomCount = 0;// 已经住人的房间数
for (int i = 0; i < cs.length; i++) {
int temp = cs[i] - 'A' + 26;// 根据+26获取所对应的客人的入住状态0:没有入住,1:已经入住
if (rooms[temp] == 1) {//再次遍历到相同字符,则roomCount-1
rooms[temp] = 0;
roomCount--;
} else if (rooms[temp] == 0) {//
if (roomCount < m) {
rooms[temp] = 1;
roomCount++;
} else {
for (int j = i; j < cs.length; j++) {// 计算还没有入住的人数
temp = cs[j] - 'A' + 26;
int k = 1;
if (rooms[temp] == 0) {
k++;
}
return "还有" + k + "位客人没有入住";
}
}
}
}
return "所有客人都入住";
}
public static int cnum(String c) {
int sum = 0;
char[] chs = c.toCharArray();
for (int i = 0; i < chs.length - 1; i++) {
if (chs[i] == '0')
continue;
for (int j = i + 1; j < chs.length; j++) {
if (chs[i] == chs[j]) {
chs[j] = '0';
}
}
sum++;
}
return sum;
}
}