# 6141-二进制转十进制
# 题目描述
Implement BinaryToDecimal<S>
which takes an exact string type S
consisting 0 and 1 and returns an exact number type corresponding with S
when S
is regarded as a binary. You can assume that the length of S
is equal to or less than 8 and S
is not empty.
type Res1 = BinaryToDecimal<'10'>; // expected to be 2
type Res2 = BinaryToDecimal<'0011'>; // expected to be 3
# 分析
想要实现二进制转十进制,只需要不断相加,比如 0011 = 1 * 1 + 1 * 2 + 0 * 4 + 0 * 8 = 3
。
可以从后往前遍历,然后设置一个辅助元组,每次往前遍历一个元素,就把辅助元组进行翻倍。从而产出
1 -> 2 -> 4 -> 8 -> 16
如果当前元素为 1,那么就把辅助元组的值增加到结果中(所以也需要一个结果元组),否则不增加。
比如:0(不加) -> 1(加2) -> 0(不加) -> 1(加8) -> 0(不加)
,得到 10。
依次类推,当遍历结束时,结果的元组的长度就是答案。
# 题解
// 字符转元组,因为字符不好匹配最后一个元素
// 元组可以通过扩展操作符控制匹配
type StringToUnion<T extends string> = T extends `${infer F}${infer R}`
? [F, ...StringToUnion<R>]
: [];
type Add<T extends any[], Res extends any[] = [], Acc extends any[] = [1]> =
// 匹配最后一个元素
T extends [...infer R, infer L]
? // 如果最后一个元素是 1
L extends '1'
? // 那么把 Acc 加到 Res 中,并对 Acc 进行翻倍
// Acc 的变化:1 -> 2 -> 4 -> 8 -> 16
Add<R, [...Res, ...Acc], [...Acc, ...Acc]>
: // 否则,Res不变,并对 Acc 进行翻倍
Add<R, Res, [...Acc, ...Acc]>
: // 遍历完毕,返回 res 的长度就是结果
Res['length'];
type BinaryToDecimal<S extends string> = Add<StringToUnion<S>>;
# 知识点
- 辅助元组计数
- 元组遍历更加灵活,本题从后往前更容易理解