Java: 如何应用过滤器进行设置?
Java: How to apply filters to set?
在我的程序中有不同的场景
一开始集合会像这样为空:
[]
用户可以在集合中动态添加值假设用户输入开始和结束整数 2 和 6,集合将如下所示:
[2,3,4,5,6]
A) 用户可以做什么:
用户可以这样做后让用户输入 1 和 2,设置将如下所示:
[1,2,3,4,5,6]
用户也可以这样做假设用户输入 6 和 8,设置将是这样的:
[1,2,3,4,5,6,7,8]
B) 用户不能做的是:
假设用户输入 2 和 6,因为 2,3,4,5,6
已经存在于集合中,所以程序应该向用户输出错误消息。
用户也做不到,假设用户输入0和10为0,1,2,3,4,5,6,7,8,9,10 bold集合中已经存在整数,因此程序应向用户输出错误消息。
C) 最终结果:
最后的设置应该是这样的[1,2,3,4,5,6,7,8]
更新:
用户也可以这样做,说一开始集合是空的这样:
[]
用户输入1和3,设置如下:
[1,2,3]
用户输入5和7后,设置如下:
[1,2,3,5,6,7]
用户输入3和5后,设置如下
[1,2,3,4,5,6,7]
我怎样才能做到这一点,任何帮助将不胜感激。
到目前为止我尝试过的方法没有用:
Scanner reader = new Scanner(System.in);
System.out.println("Enter a start: ");
int s = reader.nextInt();
System.out.println("Enter a end: ");
int e = reader.nextInt();
Set<Double> filterSet = new TreeSet<>();
for (int i = s; i <= n; i++) {
if(filterSet.stream().allMatch(x -> x>=s && x<=e)){
System.out.println("Error");
}
else{
filterSet.add(i);
}
}
您的流表达式不起作用的原因是您对范围的定义不一致。这种不一致会产生许多边缘情况,您在决定结果是否有效时必须对其进行测试。一些示例(来自您的更新):
从空集 Ø
开始,将其与 [1,3]
联合(请注意,这是数学中的闭集 ),给出结果 {1,2,3}
将之前的结果与 [5,7]
(另一个闭集)合并,得到 {1,2,3,5,6,7}
结果为 (3,5)
的并集(注意这是一个开集)结果为 {1,2,3,4,5,6,7}
如果我们到此为止,您可以创建一个一致的规则,如果结果的 cardinality 大于原始集的基数 |currentValue| > |previousValue|
,则计算成功。但是,您在原始 post 中提供了一个示例,其中您计算了 [0,10]
与 [1,8]
的并集,但此规则失败(即值 {0,9,10} 被添加到放)。即使结果的基数 11 大于先前值的基数 8,计算也被视为失败。
您甚至可以大方一点,将所有新输入都视为开集,[1,8] ∪ (0,10) ⇔ [1,8] ∪ [1,9]
(注意从开集到闭集的变化),但这仍然导致一项您未预料到的更改(9
已添加到集合中),因此需要测试边缘情况。
存在类似的情况,您从集合 [2,6]
(即 {2,3,4,5,6}
)开始并将其与 [1,2)
并集(注意部分开集) 导致 [1,6]
(即 {1,2,3,4,5,6}
),这被认为是成功的,即使它像前面的示例一样导致单个更改。在这种情况下,元素 1
而不是元素 9
.
被添加到集合中
在一种情况下,我在序列的末尾添加了一个元素,在另一种情况下,我在序列的开头添加了元素。为什么要区别对待这些?
在您提供一致的方法来确定结果是否有效之前,您不应该期望对您的问题有高质量的回答。
参见:notation
我使用GoogleGuava的RangeSet接口实现了我想要的。感谢@shmosel 向我指出了这一点。
Scanner reader = new Scanner(System.in);
System.out.println("Enter a start: ");
int s = reader.nextInt();
System.out.println("Enter a end: ");
int e = reader.nextInt();
RangeSet<Integer> rangeSet= TreeRangeSet.create();
if(rangeSet.isEmpty()){
System.out.println("1 Empty");
rangeSet.add(Range.closed(s, e));
}else {
System.out.println("1 Not Empty");
if(!rangeSet.encloses(Range.closed(s, e)) && !rangeSet.intersects(Range.open(s, e))){
System.out.println("2 Yes");
rangeSet.add(Range.closed(s, e));
}else{
System.out.println("2 No");
}
}
System.out.println("Range: " + rangeSet)
在我的程序中有不同的场景
一开始集合会像这样为空:
[]
用户可以在集合中动态添加值假设用户输入开始和结束整数 2 和 6,集合将如下所示:
[2,3,4,5,6]
A) 用户可以做什么:
用户可以这样做后让用户输入 1 和 2,设置将如下所示:
[1,2,3,4,5,6]
用户也可以这样做假设用户输入 6 和 8,设置将是这样的:
[1,2,3,4,5,6,7,8]
B) 用户不能做的是:
假设用户输入 2 和 6,因为 2,3,4,5,6
已经存在于集合中,所以程序应该向用户输出错误消息。
用户也做不到,假设用户输入0和10为0,1,2,3,4,5,6,7,8,9,10 bold集合中已经存在整数,因此程序应向用户输出错误消息。
C) 最终结果:
最后的设置应该是这样的[1,2,3,4,5,6,7,8]
更新:
用户也可以这样做,说一开始集合是空的这样:
[]
用户输入1和3,设置如下:
[1,2,3]
用户输入5和7后,设置如下:
[1,2,3,5,6,7]
用户输入3和5后,设置如下
[1,2,3,4,5,6,7]
我怎样才能做到这一点,任何帮助将不胜感激。
到目前为止我尝试过的方法没有用:
Scanner reader = new Scanner(System.in);
System.out.println("Enter a start: ");
int s = reader.nextInt();
System.out.println("Enter a end: ");
int e = reader.nextInt();
Set<Double> filterSet = new TreeSet<>();
for (int i = s; i <= n; i++) {
if(filterSet.stream().allMatch(x -> x>=s && x<=e)){
System.out.println("Error");
}
else{
filterSet.add(i);
}
}
您的流表达式不起作用的原因是您对范围的定义不一致。这种不一致会产生许多边缘情况,您在决定结果是否有效时必须对其进行测试。一些示例(来自您的更新):
从空集 Ø
开始,将其与 [1,3]
联合(请注意,这是数学中的闭集 ),给出结果 {1,2,3}
将之前的结果与 [5,7]
(另一个闭集)合并,得到 {1,2,3,5,6,7}
结果为 (3,5)
的并集(注意这是一个开集)结果为 {1,2,3,4,5,6,7}
如果我们到此为止,您可以创建一个一致的规则,如果结果的 cardinality 大于原始集的基数 |currentValue| > |previousValue|
,则计算成功。但是,您在原始 post 中提供了一个示例,其中您计算了 [0,10]
与 [1,8]
的并集,但此规则失败(即值 {0,9,10} 被添加到放)。即使结果的基数 11 大于先前值的基数 8,计算也被视为失败。
您甚至可以大方一点,将所有新输入都视为开集,[1,8] ∪ (0,10) ⇔ [1,8] ∪ [1,9]
(注意从开集到闭集的变化),但这仍然导致一项您未预料到的更改(9
已添加到集合中),因此需要测试边缘情况。
存在类似的情况,您从集合 [2,6]
(即 {2,3,4,5,6}
)开始并将其与 [1,2)
并集(注意部分开集) 导致 [1,6]
(即 {1,2,3,4,5,6}
),这被认为是成功的,即使它像前面的示例一样导致单个更改。在这种情况下,元素 1
而不是元素 9
.
在一种情况下,我在序列的末尾添加了一个元素,在另一种情况下,我在序列的开头添加了元素。为什么要区别对待这些?
在您提供一致的方法来确定结果是否有效之前,您不应该期望对您的问题有高质量的回答。
参见:notation
我使用GoogleGuava的RangeSet接口实现了我想要的。感谢@shmosel 向我指出了这一点。
Scanner reader = new Scanner(System.in);
System.out.println("Enter a start: ");
int s = reader.nextInt();
System.out.println("Enter a end: ");
int e = reader.nextInt();
RangeSet<Integer> rangeSet= TreeRangeSet.create();
if(rangeSet.isEmpty()){
System.out.println("1 Empty");
rangeSet.add(Range.closed(s, e));
}else {
System.out.println("1 Not Empty");
if(!rangeSet.encloses(Range.closed(s, e)) && !rangeSet.intersects(Range.open(s, e))){
System.out.println("2 Yes");
rangeSet.add(Range.closed(s, e));
}else{
System.out.println("2 No");
}
}
System.out.println("Range: " + rangeSet)