📅  最后修改于: 2023-12-03 15:28:38.325000             🧑  作者: Mango
本文介绍了 GATE CS 2019 的第17个问题,其中涉及到门电路的设计和实现。
给定两个有序列表 $A$ 和 $B$,长度分别为 $m$ 和 $n$。找到两个列表中的中位数,前提是 $m \leq n$。
这个问题可以通过门电路实现。我们首先需要将这两个有序列表 $A$ 和 $B$ 合并成一个有序列表 $C$。这可以通过 Merge Sort 算法来实现,时间复杂度为 $O(m + n)$。
之后,根据 $m \leq n$ 的限制,我们可以将问题转化为求有序列表 $C$ 的中位数。如果列表 $C$ 的长度为奇数,则中位数是 $C_{\lfloor \frac{m + n}{2} \rfloor}$;如果长度为偶数,则中位数是 $\frac{C_{\lfloor \frac{m + n}{2} \rfloor - 1} + C_{\lfloor \frac{m + n}{2} \rfloor}}{2}$。
为了找到中位数,我们可以使用 Selection 算法,时间复杂度为 $O(m + n)$。具体地,我们可以使用 Median of Medians 算法来选择一个 Pivot,然后在小于 Pivot 和大于 Pivot 的两个子列表中递归查找中位数,直到找到中位数为止。
以下是一个示例的 Gate-Level 实现,其中输入 $A$ 和 $B$ 已经进行了编码,输出也进行了解码,其中 $\texttt{dout}(0)$ 代表中位数的整数部分,$\texttt{dout}(1)$ 代表中位数的小数部分。
## Module: median
### Inputs:
- A: [m:1] # 有序列表 A
- B: [n:1] # 有序列表 B
- clk: input # 时钟
- rst: input # 复位
### Outputs:
- dout: [2:1] # 中位数
### Implementation:
- Wires:
- M1: [m+n:1] # 合并后的列表 C
- M2: [m+n:1] # 合并后的列表 C
- P: [m+n:1] # 存储 Pivot
- L1: [m+n/2:1] # Pivot 左边的列表
- L2: [m+n/2:1] # Pivot 右边的列表
- M1_mid: [1:1] # M1 的中位数
- M2_mid: [1:1] # M2 的中位数
- Buf1: [m+n+1:1] # 中间的缓存
- Buf2: [m+n+1:1] # 中间的缓存
- S: [1:1] # 符号位(正数为0,负数为1)
- Temp: [n+1:1] # 存储临时数据
- Submodules:
- merge: Merge Sort 子模块
- pivot: Median of Medians 子模块
- Functionality:
merge(A, B, M1); # 合并列表 A 和 B
pivot(M1, m+n, P); # 选择 Pivot
assign L1 = M2[0 : P-1]; # 划分列表
assign L2 = M2[P+1 : m+n];
pivot(L1, P, M1_mid); # 递归查找中位数
pivot(L2, m+n-P, M2_mid);
if (M1_mid > M2_mid) begin
Buf1[0] = 0; # 计算差值
S = 1;
for (i = 1; i <= n; i++) begin
Temp[i] = B[i] - M2_mid;
end
for (i = 1; i <= m+n; i++) begin
if (i <= P) begin
Buf1[i] = M1_mid - M1[i];
end else begin
Buf1[i] = M2[i-P] - M2_mid;
end
end
end else begin
Buf1[0] = 1;
S = 0;
for (i = 1; i <= n; i++) begin
Temp[i] = M2_mid - B[i];
end
for (i = 1; i <= m+n; i++) begin
if (i >= P+1) begin
Buf1[i] = M1[i] - M1_mid;
end else begin
Buf1[i] = M1_mid - M2[i];
end
end
end
merge(Buf1, Temp, Buf2); # 合并列表并计算中位数
if (S == 1) begin
dout[0] = M2_mid - Buf2[(m+n)/2 + 1];
end else begin
dout[0] = M2_mid + Buf2[(m+n)/2 + 1];
end
dout[1] = Buf2[(m+n)/2] % 10;
以上代码只是一个简单的实现示例,实际上可以通过很多方式来实现这个问题。