首先,通过上一个帖子,确实提示很快的速度,总体来说提高了 3.5 倍左右。 非常感谢大家!!! 我的问题是: 想在提升时间复杂度, 目前个人觉得能在提升速度的地方只有 比较那块能操作,但是已经黔驴技穷了.
void main() {
// 以下简介是通过 举例来进行说明
// 类似于多人打游戏,假设三个人(A,B,C), 每局每个人会有一个分数, 一般来说分高则获胜(这里取最低,不影响理解)
// 最终通过 N 个迭代计算各个玩家的 Equity ( Equity = win+tie ), win , tie 数。
// 如何计算 win: 每局只有一个人获胜, 至多一个,则+1 ,
// 如何计算 tie: 1 / n , 其中 n 为当局分数最低的人数
// 第 1 局 A:50 , b: 60 , c: 60, 故 A 获胜. win-> A = 0 + 1
// 最终结果:win: A=1 , B = 0, C = 0 tie-> A: 0 , B : 0, C : 0
//
// 第 2 局 A:50 , b: 50 , c: 70, 故 A, B 平. tie-> A = (1/2) , B = (1/2)
// 最终结果:win: A=1 , B = 0, C = 0 tie-> A: 0.5 , B : 0.5, C : 0
//
// 第 3 局 A:100 , b: 100 , c: 100, 故 A, B, C 平. tie: A=1/3=0.33 , B=1/3=0.33, C=1/3=0.33
// 最终结果:win: A=1 , B = 0, C = 0 tie-> A: 0.5+0.33=0.83, B=0.5+0.33=0.83, C=0.33
// 假设只玩了三局, 那么本次游戏所有的胜率为:
// 最后结果全部除以 3 ,因为本次玩了 3 局
// A: {Equity: 1.83, win: 1, tie: 0.83} -> {Equity: 1.83/3, win: 1/3, tie: 0.83/3} -> {Equity: 0.61, win: 0.33, tie: 0.28}
// B: {Equity: 0.83, win: 0, tie: 0.83} -> {Equity: 0.83/3, win: 0/3, tie: 0.83/3} -> {Equity: 0.28, win: 0, tie: 0.28}
// C: {Equity: 0.33, win: 0, tie: 0.33} -> {Equity: 0.33/3, win: 0/3, tie: 0.33/3} -> {Equity: 0.11, win: 0, tie: 0.11}
//
// 如何验证结果是否正确: 将所有的 Equity 相加是否约等于 1. 0.61+0.28+0.11 = 1; 故正确!
// 下面简单阐述下代码逻辑
// 使用两个数组储存结果, win 数组 和 tie 数组, 分别记录次数,两个数组的长度为本次游戏的人数
// 使用上面的例子可以演变为:
// 第一局: win 数组 -> [1, 0, 0] tie 数组-> [0, 0, 0]
// 第二局: win 数组 -> [1, 0, 0] tie 数组-> [0.5, 0.5, 0]
// 第三局: win 数组 -> [1, 0, 0] tie 数组-> [0.83, 0.33, 0.33]
// 最后只需要用 n(n 为游戏次数) 除以这两个数组各个元素就可以了
int h_ = 1; // 为了方便 本次游戏次数 1 故忽略次数 for 循环
int c_ = 2; // 玩家个人数
int* res_card_lst = (int*)malloc(c_ * sizeof(int));
int* min_v_index_lst = (int*)malloc(c_ * sizeof(int));
int* score_arr_win = (int*)calloc(c_, sizeof(int)); // win 数组
float* score_arr_tie = (float*)calloc(c_, sizeof(float)); // tie 数组
int min_v_index; int min_score;
int ii; int jj; int k; int l; int m;
int a_; int min_i; int index_;
int poker_lst[] = {
0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, };
int len_poker_lst = 52;
// 五层是 将 poker_lst 进行不重复组合。
// 1.要么先组合成,在遍历,遍历的同时做逻辑处理。
// 2. 要么同时生成排列组合的时候 进行逻辑处理, 一下就是采用此方案。
for (ii = 0; ii < len_poker_lst; ii++) {
for (jj = ii + 1; jj < len_poker_lst; jj++) {
for (k = jj + 1; k < len_poker_lst; k++) {
for (l = k + 1; l < len_poker_lst; l++) {
for (m = l + 1; m < len_poker_lst; m++) {
// 下面是主要逻辑
min_score = 7462;
// 用数组进行储存结果 同时获取最小值的结果
for (int j = 0; j < c_; j++) {
// res 其实就是通过上面的循环拿到组合,进行一些逻辑操作,最终返回一个 int 数值.
// 可以理解为游戏分数,
// 可以随便写死,写死无非就是全部都是平局,
// 本次主要是测试时间复杂度,这个函数不能动,和这个函数也无太大关系
//res = evaluate_7cards(poker_lst[ii], poker_lst[jj], poker_lst[k], poker_lst[0], poker_lst[1],
// 玩家数据 1 , 玩家数据 2);
res = 666;
res_card_lst[j] = res;
if (res < min_score) min_score = res;
}
// 找到最小值的玩家的下标, 同时记录最小值玩家的个数
min_v_index = 0;
for (a_ = 0; a_ < c_; a_++) {
if (res_card_lst[a_] == min_score) {
min_v_index_lst[min_v_index] = a_;
min_v_index += 1;
}
}
// 如果最小值玩家只有一个,那么就直接 win 数组 += 1
if (min_v_index == 1) {
score_arr_win[min_v_index_lst[0]] = score_arr_win[min_v_index_lst[0]]+ 1;
}
else {
// 最小值玩家多个情况, 遍历玩家下标,在 tie 数组进行计算 (1 / n)
for (min_i = 0; min_i < min_v_index; min_i++) {
index_ = min_v_index_lst[min_i] + c_;
score_arr_tie[index_] = score_arr_tie[index_] + (1.0 / min_v_index);
}
};
}
}
}
}
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.