任何人都可以帮助我在下面的示例中识别公式或数学术语。
Predefined sets stored in the system,
1 = Monday
2 = Tuesday
4 = Wednesday
8 = Thursday
16 = Friday
32 = Saturday
64 = Sunday.
From the Total i need to retrieve the days from the predefined set, like,
Eg: 1
127 = This means i have to take All Days in the week from the predefined sets.
Eg: 2
80 = This means i have to take Friday and Sunday only
Eg: 3
7 = This means i have to take Monday, Tuesday and Wednesday.
谢谢。
答案 0 :(得分:1)
您可以将bitwise AND &
设置为当日值,并选择这一天。
const
days = { Monday: 1, Tuesday: 2, Wednesday: 4, Thursday: 8, Friday: 16, Saturday: 32, Sunday: 64 },
getDays = value => Object.keys(days).filter(day => value & days[day]);
console.log(getDays(127)); // All Days
console.log(getDays(80)); // Friday, Sunday
console.log(getDays(7)); // Monday, Tuesday, Wednesday
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
Java 9及更高版本的解决方案,因为我知道Java和JavaScript解决方案都会有所帮助。首先我们需要
private static final Map<DayOfWeek, Integer> dayBits = new EnumMap<>(
Map.of(DayOfWeek.MONDAY, 0x1, DayOfWeek.TUESDAY, 0x2,
DayOfWeek.WEDNESDAY, 0x4, DayOfWeek.THURSDAY, 0x8,
DayOfWeek.FRIDAY, 0x10, DayOfWeek.SATURDAY, 0x20,
DayOfWeek.SUNDAY, 0x40));
那我们就可以做
int total = 80;
Set<DayOfWeek> days = Stream.of(DayOfWeek.values())
.filter(dow -> (total & dayBits.get(dow)) > 0)
.collect(Collectors.toCollection(() -> EnumSet.noneOf(DayOfWeek.class)));
System.out.println(days);
我们得到的输出是
[星期五,星期天]
后面的代码片段也将在Java 8中运行,只有您需要一种更为冗长的方式来初始化地图。
您可能已经注意到,数字1、2、4、8等表示二进制数字的位。 1是二进制格式的00000001,2是00000010二进制,4是00000100,依此类推。因此,我们的任务是找出总数中的哪些位被设置。 127是01111111,所有七个位都已设置。 80是01010000,则设置了星期五和星期日的位。要确定是否设置了某个位,请使用(单个)&
运算符。如果包含星期一,则total & 1
将产生1,如果不包含星期一,则将产生0。同样,如果包含星期二,则total & 2
将产生2,否则将产生0。
我更喜欢以十六进制形式读取和写入位常量,例如0x20
。因为0b0010_0000太长了,而且从32开始,它还不是很清楚设置了哪一位(除非您真的对二进制数字非常满意,并且您不应该期望所有人都在读程序)。
当然,除了内置的DayOfWeek
枚举,我当然也不想将星期几表示为其他任何内容。
答案 2 :(得分:0)
我想在评论中添加它,但是还没有声誉。
为解决该问题,您可以看一下二进制索引。
它们是2的幂,所以例如:
2 ^ 0 = 1
2 ^ 1 = 2
2 ^ 2 = 4
通过计算2 ^ 2之前的所有数字,您将得到3,即2 ^ 2-1,因此您可以通过将数字相加来区分日期的所有组合。
相反的技巧是继续减去仍小于要求数字的最高数字,并不断重复。