drools规则属性(rule attributes)的使用
一、介绍
规则属性
是您可以添加到业务规则以修改规则行为
的附加规范。 在 DRL
文件中,您通常在规则条件和操作的上方定义规则属性,多个属性位于单独的行中
,格式如下:
rule "rule_name"
// Attribute
// Attribute
when
// Conditions
then
// Actions
end
二、常见的规则属性
规则属性 | 解释 | 举例 |
---|---|---|
salience | 定义规则优先级 ,是一个整数。当在激活队列中排序 时,salience的值越大 ,优先级越高 。 |
salience 99 |
enabled | 定义规则是否启用. true 启用,false 禁用,默认值是true |
enabled true |
date-effective | 包含时间和日期的字符串,当当前时间大于date-effective 时,该规则才会被激活。这个时间格式可以修改,见下方具体的用法 |
date-effective "4-5月-2022" |
date-expires | 设置规则的过期时间,时间格式和上方一样。 | date-expires "4-5月-2022" |
no-loop | 布尔值,默认值为false , 定义当当前规则规则的结果 修改了fact 对象时,是否可以再次执行该规则。true: 不可以, false: 可以,可能会导致死循环。指的是当前规则的修改,如果别的规则修改了,还会导致该规则的触发 |
no-loop true |
agenda-group | Agenda groups 允许您对agenda 进行分区,以提供对规则组的更多执行控制。 只有获得焦点的议程组中的规则才能被激活。 ,但是这个里面有个特例 ,如果某个规则没有配置 agenda-group,但是它模式匹配成功了,那么会被分到默认的组(main ),这个main 组的规则也会执行。 |
agenda-group "GroupName" |
auto-focus | 布尔值,仅适用于Agenda-Group 内的规则。当值为true 时,下次激活该规则时,会将焦点自动给这个Agenda group |
auto-focus true |
activation-group | 表示该组下的规则只有一个规则 会被执行,该组下其余激活的规则会被取消执行。 但是别的组激活的规则可能会被执行。 |
activation-group "GroupName" |
duration | long类型的值,如果在这个时间之后规则还成立 ,那么执行该规则 |
duration 1000 |
timer | 一个字符串,标识用于调度规则的 int(间隔)或 cron 计时器定义。 | Example: timer ( cron:* 0/15 * * * ? ) (every 15 minutes) |
calendar | 定义Quartz calendar用于调度规则。 | |
lock-on-active | 一个布尔值,仅适用于规则流组或议程组中的规则。 选择该选项后,下次规则的规则流组变为活动状态或规则的议程组获得焦点时,规则无法再次激活,直到规则流组不再处于活动状态或议程组失去焦点。 这是 no-loop 属性的更强版本,因为匹配规则的激活被丢弃,无论更新的来源如何(不仅是规则本身)。 此属性非常适合计算规则,其中您有许多修改事实的规则并且您不希望任何规则重新匹配和再次触发。 | lock-on-active true |
dialect | 将 JAVA 或 MVEL 标识为用于规则中的代码表达式的语言的字符串。 默认情况下,该规则使用在包级别指定的方言。 此处指定的任何方言都会覆盖该规则的包方言设置。 | dialect "JAVA" |
三、部分规则属性案例
此处编写出规则文件和部分核心Java代码
1、salience
定义规则执行的优先级,salience的值越大,优先级越高
1、规则文件的编写
rule "salience_rule_1"
salience 4
when
then
System.out.println("rule 1");
end
rule "salience_rule_2"
salience 3
when
then
System.out.println("rule 2");
end
// 此处优先级的值是动态获取来的
rule "salience_rule_3"
salience $dynamicSalience
when
$dynamicSalience: Integer()
then
System.out.println("rule 3");
end
注意:
我们的salience_rule_3
的优先级的值是动态
来的,即是从工作内存中获取的。
2、java代码编写
public class DroolsSalienceApplication {
public static void main(String[] args) {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 向工作内存中插入一个Integer值,salience_rule_3 需要用到这个优先级
kieSession.insert(10);
// 只匹配规则名称是已 salience_ 开头的规则,忽略其余的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("salience_"));
kieSession.dispose();
}
}
kieSession.insert(10);
此处向工作内存中插入一个值,将会匹配到salience_rule_3
,然后动态修改它的优先级。
3、运行结果
rule 3
rule 1
rule 2
因为 salience
的值越大优先级越高,所以是这个顺序。
2、enabled
定义规则是否启用,true
启用 false
禁用
1、规则文件编写
package rules
rule "enabled_rule_1"
// 禁用此规则
enabled false
when
then
System.out.println("enabled_rule_1");
end
rule "enabled_rule_2"
// 启用此规则,默认就是启用
enabled true
when
then
System.out.println("enabled_rule_2");
end
enabled_rule_2
这个规则需要运行,enabled_rule_1
这个规则不能运行。
2、java代码编写
/**
* 测试规则的启用和禁用
*/
public class DroolsEnabledApplication {
public static void main(String[] args) {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 只匹配规则名称是已 enabled_ 开头的规则,忽略其余的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("enabled_"));
kieSession.dispose();
}
}
没有需要注意的地方
3、运行结果
enabled_rule_2
可以看到只有规则enabled_rule_2
输出了结果,而enabled_rule_1
被禁用了。
3、date-effective
定义规则什么时候启用,只有当前时间>
规则时间才会启用。需要注意默认的时间格式
,可以通过java代码进行修改。
1、规则文件编写
package rules
import java.text.SimpleDateFormat
import java.util.Date
// 规则一:输出当前时间
rule "date_effective_rule_1"
when
then
System.out.println("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
end
// 规则二: 该规则会在2022-05-18 10:54:26之后被激活
rule "date_effective_rule_2"
date-effective "2022-05-18 10:54:26"
when
then
System.out.println("date_effective_rule_2执行了,规则允许被执行的时间应该在2022-05-18 10:54:26之后");
end
// 规则三: 该规则会在2023-05-18 10:54:26之后被激活
rule "date_effective_rule_3"
date-effective "2023-05-18 10:54:26"
when
then
System.out.println("date_effective_rule_3会在时间到了2023-05-18 10:54:26才激活");
end
规则一:输出当前时间
规则二: 该规则会在2022-05-18 10:54:26之后被激活
规则三: 该规则会在2023-05-18 10:54:26之后被激活
2、java代码编写
/**
* 测试规则在执行的时间之后才能执行
*/
public class DroolsDateEffectiveApplication {
public static void main(String[] args) {
// 设置日期格式,否则可能会报错(Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]])
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 只匹配规则名称是已 date_effective_ 开头的规则,忽略其余的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("date_effective_"));
kieSession.dispose();
}
}
需要注意System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
这句,这个修改drools中的日期格式,因为规则中写的日期格式为date-effective "2023-05-18 10:54:26"
而默认的格式为d-MMM-yyyy
,不修会报错。
3、运行结果
当前时间:2022-05-18 10:59:38
date_effective_rule_2执行了,规则允许被执行的时间应该在2022-05-18 10:54:26之后
可以看到规则二执行了,规则三没有执行,因为规则三需要时间到达了2023-05-18 10:54:26
才执行,而当前时间不符合。
4、注意事项
如果出现了Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]]
这个错误该怎么解决了,这是因为日期格式不正确。需要在java代码中进行如下设置System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss")
4、date-expires
定义规则的过期时间,即规则到了该时间之后就不可使用了。和date-effective
的用法类似,此处就不演示了。
5、no-loop
定义当当前规则
的结果修改了fact
对象时,是否可以再次执行该规则。可以防止死循环
1、规则文件编写
package rules
import java.util.concurrent.TimeUnit
import java.text.SimpleDateFormat
import java.util.Date
rule "no_loop_rule_1"
no-loop true
when
$i: Integer(intValue() < 20)
then
modify($i){
}
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " no_loop_rule_1 i=" + $i);
end
rule "no_loop_rule_2"
no-loop false
when
$i: Integer(intValue() < 20)
then
modify($i){
}
TimeUnit.SECONDS.sleep(1);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " no_loop_rule_2 i=" + $i);
end
解释:
no_loop_rule_1
:no-loop true
表示如果当前规则的RHS
部分,对Fact对象进行了修改,则不会再次触发该规则。那如果是no_loop_rule_2
修改了,会导致该规则的触发吗?答案是
会触发,如果我不想被触发呢?那么使用lock-on-active
可以实现。
no_loop_rule_2
:no-loop false
表示如果当前规则的RHS
部分,对Fact对象进行了修改,那么还会再次匹配这个规则。
2、java代码编写
/**
* 测试规则是否可以再次被执行
*/
public class DroolsNoLoopApplication {
public static void main(String[] args) throws InterruptedException {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
kieSession.insert(10);
// 只匹配规则名称是已 no_loop_ 开头的规则,忽略其余的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("no_loop_"));
// 睡眠5s,使规则文件中的规则执行完
TimeUnit.SECONDS.sleep(5);
kieSession.dispose();
}
}
此处 java 代码,睡眠了5s,是为了让规则执行。
3、运行结果
2022-05-18 11:42:29 no_loop_rule_1 i=10
2022-05-18 11:42:31 no_loop_rule_2 i=10
2022-05-18 11:42:31 no_loop_rule_1 i=10
2022-05-18 11:42:32 no_loop_rule_2 i=10
解释:
2022-05-18 11:42:29 no_loop_rule_1 i=10
: no_loop_rule_1被触发,由于RHS部分使用了modify
修改了规则内存中的对象,但是该规则存在 no-loop true 的属性,所以该规则没有再次被触发,即只输出了一次。
2022-05-18 11:42:30 no_loop_rule_2 i=10 2022-05-18 11:42:30 no_loop_rule_1 i=10
此时规则 no_loop_rule_2 执行了,由于该规则的 no-loop 为 false 并且使用了 modify 方法,所以该规则多次被触发了,从结果上看,貌似规则 no_loop_rule_1 又再次被触发了,不是应该不被触发吗,因为设置了no-loop true?因为这是no_loop_rule_2导致no_loop_rule_1触发的,而no_loop只对自身的RHS修改有效。
疑问:
那如果将 no-loop
换成lock-on-active
结果会一样吗?可以自己尝试一下看看结果。
6、agenda-group
将被模式匹配成功后的规则,进行分组,只有获得焦点的组
,才可以执行规则。但是这个里面有个特列,如果某个规则在模式匹配,匹配成功了,但是没有配置agenda-group,那么它会被分配到main
组,这个main
组的规则总是执行的。
agenda-group
的数据结构就类似stack
,激活的组是在栈顶。参考如下图:
参考链接: https://stackoverflow.com/questions/6870192/understanding-agenda-group-in-drools
1、规则文件编写
package rules
/**
agenda-group 的数据结构类似与栈,激活的组会被放置在栈顶,
`main`是默认组,总是存在的,即没有配置agenda-group的就是`main`,
`main`总是会执行的。
*/
rule "agenda_group_001_rule_1"
agenda-group "group-001"
when
then
System.out.println("agenda_group_001_rule_1");
end
rule "agenda_group_001_rule_2"
agenda-group "group-001"
when
then
System.out.println("agenda_group_001_rule_2");
end
rule "agenda_group_002_rule_3"
agenda-group "group-002"
when
then
System.out.println("agenda_group_002_rule_3");
end
rule "agenda_group_no_group_rule_4"
when
then
System.out.println("agenda_group_no_group_rule_4");
end
注意: 此处其实是 存在 3个组的,agenda_group_no_group_rule_4
如果模式匹配成功后会被分配到main
组,main
总是会被执行的。
2、java代码编写
/**
* 测试规则分组
*/
public class DroolsAgendaGroupApplication {
public static void main(String[] args) {
// 设置日期格式,否则可能会报错(Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]])
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 激活组
kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
// 只匹配规则名称是已 agenda_group_ 开头的规则,忽略其余的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("agenda_group_"));
kieSession.dispose();
}
}
激活group-001
分组。
3、运行结果
agenda_group_001_rule_1
agenda_group_001_rule_2
agenda_group_no_group_rule_4
解释:
agenda_group_no_group_rule_4
为什么会被输出呢?它没有定义agenda-group
啊,而且我们激活的也是group-001
分组,它不应该输出啊。这是应为这个规则模式匹配成功后被分配到了默认的main
组,而main
组一定会被执行的。
7、auto-focus
设置某个agenda-group
默认获取到焦点,和在java代码中使用kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
或在drl文件中使用drools.setFocus(..)
一样。
8、activation-group
处于该分组中激活的规则,同一个组下,只有一个规则可以执行
,其余的会被取消执行。但是别的组中激活的规则还是可以执行的。
1、规则文件编写
package rules
rule "activation_group_001_rule_1"
activation-group "group-001"
salience 1
when
then
System.out.println("activation_group_001_rule_1");
end
rule "activation_group_001_rule_2"
activation-group "group-001"
salience 2
when
then
System.out.println("activation_group_001_rule_2");
end
rule "activation_group_002_rule_3"
activation-group "group-002"
when
then
System.out.println("activation_group_002_rule_3");
end
rule "activation_group_no_group_rule_4"
when
then
System.out.println("activation_group_no_group_rule_4");
end
activation-group "group-001"
此处对这个组的规则指定了优先级,优先级高的先执行,执行完之后,该组别的规则不执行。
2、java代码编写
public class DroolsActivationGroupApplication {
public static void main(String[] args) {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 只匹配规则名称是已 activation_group_ 开头的规则,忽略其余的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("activation_group_"));
kieSession.dispose();
}
}
3、运行结果
activation_group_001_rule_2
activation_group_002_rule_3
activation_group_no_group_rule_4
可以看到分组group-001
中有2个规则,但是只执行了一个规则。
9、duration
long类型的值,单位毫秒,如果在这个时间之后规则还成立
,那么执行该规则。
1、规则文件编写
package rules
import java.text.SimpleDateFormat
import java.util.Date
rule "duration_rule_1"
// 延迟1s后执行规则
duration 1000
when
$i: Integer(intValue() < 10)
then
System.out.println(Thread.currentThread().getName() + ": " +
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+
" duration_rule_1 $i:"+$i);
end
定义规则延迟1s
后进行执行。
2、java代码编写
/**
* 在多少毫秒后,如果条件还成立,则触发该规则
*/
public class DroolsDurationApplication {
public static void main(String[] args) throws InterruptedException {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
FactHandle factHandle = kieSession.insert(3);
// 只匹配规则名称是已 duration_ 开头的规则,忽略其余的规则
new Thread(() -> {
// 调用此方法会阻塞调用线程,直到 `kieSession.halt();`的调用
System.out.println("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
kieSession.fireUntilHalt(new RuleNameStartsWithAgendaFilter("duration_"));
}, "fire-thread").start();
// 如果修改这个值,使得规则的条件不成立,看规则是否还执行
kieSession.update(factHandle, 4);
TimeUnit.SECONDS.sleep(2);
kieSession.halt();
kieSession.dispose();
}
}
注意:
1、我们调用出发所有规则执行的方法不在是fireAllRules
而是fireUntilHalt
。
2、fireUntilHalt
的调用会阻塞线程,直到调用halt
方法,因此fireUntilHalt
需要放置到另外的线程中调用。而且我们观察规则的执行,也是在这个线程中调用的。
3、运行结果
当前时间:2022-05-18 14:13:36
fire-thread: 2022-05-18 14:13:37 duration_rule_1 $i:4
可以看到,延迟1s
后规则执行了。
4、疑问
如果我们在1s
钟之内,将规则的条件修改成不成立,那么规则还执行吗?答案:
不执行。
10、lock-on-active
和rule flow groups or agenda groups
配合使用。
需求:
我们有2个规则,并且同属于一个组,规则二执行完之后,工作内存中的Fact对象的值发生了变化,导致规则一满足执行的条件,而规则一已经执行一遍了,此处需要阻止规则二的触发导致规则一的出触发。使用lock-on-active
即可实现。
1、规则文件编写
package rules
import com.huan.drools.lockonactive.Person
rule "lock_on_active_rule_01"
agenda-group "group-001"
lock-on-active true
when
$p: Person(age < 18)
then
System.out.println("lock_on_active_rule_01: 用户:[" + $p.getName() + "]当前的年龄是:[" + $p.getAge() + "]");
end
rule "lock_on_active_rule_02"
agenda-group "group-001"
when
$p: Person(name == "张三")
then
modify($p){
setAge(15)
}
System.out.println("lock_on_active_rule_02: 用户:[" + $p.getName() + "]当前的年龄是:[" + $p.getAge() + "]");
end
规则lock_on_active_rule_01
加了lock-on-active true
属性后,规则lock_on_active_rule_02
修改Fact
导致规则lock_on_active_rule_01
的条件成立,此时规则也是不会执行的。
2、java代码编写
/**
* 一个简单的实体类
*
* @author huan.fu
* @date 2022/5/18 - 14:34
*/
@Getter
@Setter
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
}
public class DroolsLockOnActiveApplication {
public static void main(String[] args) {
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
// 激活组
kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
Person person = new Person("张三", 20);
kieSession.insert(person);
// 只匹配规则名称是已 lock_on_active_ 开头的规则,忽略其余的规则
kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("lock_on_active_"));
kieSession.dispose();
}
}
3、运行结果
lock_on_active_rule_02: 用户:[张三]当前的年龄是:[15]
可以看到只有规则二执行了,说明阻止了规则一的执行。
四、完整代码
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-rule-attributes
五、参考链接
1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#rules-attributes-ref_drl-rules
2、 https://stackoverflow.com/questions/6870192/understanding-agenda-group-in-drools
drools规则属性(rule attributes)的使用的更多相关文章
- Drools 规则文件语法概述
概述(Overview) 以.drl为扩展名的文件,是Drools中的规则文件,规则文件的编写,遵循Drools规则语法.下面详细介绍一下Drools规则文件语法.具体参考官方文档: https:// ...
- Drools 规则引擎应用
规则引擎-drools 1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 .... ...
- Drools 规则引擎应用 看这一篇就够了
1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 ...... 1.2传统做法 1 ...
- Drools规则引擎入门指南(一)
最近项目需要增加风控系统,在经过一番调研以后决定使用Drools规则引擎.因为项目是基于SpringCloud的架构,所以此次学习使用了SpringBoot2.0版本结合Drools7.14.0.Fi ...
- drools规则引擎初探
https://www.cnblogs.com/yuebintse/p/5767996.html 1.drools是什么 Drools是为Java量身定制的基于Charles Forgy的RETE算 ...
- Drools 规则引擎环境搭建
一.关于 drools 规则引擎 前面写过一篇 Drools 规则引擎相关的文章,这篇文章主要记录一下规则引擎的环境搭建和简单示例.不熟悉 drools 的朋友可以看看这篇文章: 自己写个 Drool ...
- Drools规则引擎-如果判断某个对象中的集合是否包含指定的值
规则引擎集合相关处理 在实际生产过程中,有很多关于集合的处理场景,比如一个Fact对象中包含有一个集合,而需要判断该集合是否包含某个值.而Drools规则引擎也提供了多种处理方式,比如通过from.c ...
- SpringBoot2 整合 Drools规则引擎,实现高效的业务规则
本文源码:GitHub·点这里 || GitEE·点这里 一.Drools引擎简介 1.基础简介 Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的 ...
- drools规则语法(一)
1.基本的匹配规则 1.1变量 drools使用匹配的方式对Fact进行比对, 比如 account : Account(balance > 100) 这个规则的含义就是在Fact中找到类型为A ...
随机推荐
- js技术之转换为大写toUpperCase()
案例:把所有单词以空格为分割并将首字母转为大写 <!DOCTYPE html><html lang="en"><head> <meta c ...
- IDEA问题之“微服务启动项目时,不会加载Spring Boot到Services中”
1.启动项目时,不会加载Spring Boot到Services中 现象解析: 启动项目时 会在debug的位置加载项目 注:这里没有配图,因为问题已解决,未记录图,需往后遇到记录 解决方案: 需要在 ...
- 错误问题之“Apache Log4j 漏洞,在版本为包含2.14以内!”
漏洞概述 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器. Log4j 1.2 中包含一个 SocketServer 类,该类容易受到不可信数据反序列化的影响,当侦听 ...
- 10分钟go crawler colly从入门到精通
Introduction 本文对colly如何使用,整个代码架构设计,以及一些使用实例的收集. Colly是Go语言开发的Crawler Framework,并不是一个完整的产品,Colly提供了类似 ...
- 《剑指offer》面试题3:二维数组中的查找
面试题3:二维数组中的查找 面试题3:二维数组中的查找题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的个二维数组和一个整数,判 ...
- sql语句中 left join,right join,inner join 的区别
看到了sql,发现好久没写sql甚是想念哈哈哈哈,好多当时学的东西都忘了,当时总结的好多的文档也怎么都找不到了..... 言归正传,找到了一张图感觉描述的还挺清晰,先贴图,再说说自己的理解. 1.LE ...
- Java中有关clone方法的用法
一.clone在数组基本数据类型中的使用 public class Main { public static void main(String[] args) { int[] arr= {7,8,9} ...
- CF #781 (Div. 2), (C) Tree Infection
Problem - C - Codeforces Example input 5 7 1 1 1 2 2 4 5 5 5 1 4 2 1 3 3 1 6 1 1 1 1 1 output 4 4 2 ...
- Codeforces Round #721 (Div. 2)A. And Then There Were K(位运算,二进制) B1. Palindrome Game (easy version)(博弈论)
半个月没看cf 手生了很多(手动大哭) Problem - A - Codeforces 题意 给定数字n, 求出最大数字k, 使得 n & (n−1) & (n−2) & ...
- IP协议/地址(IPv4&IPv6)概要
IP协议/地址(IPv4&IPv6)概要 IP协议 什么是IP协议 IP是Internet Protocol(网际互连协议)的缩写,是TCP/IP体系中的网络层协议. [1] 协议的特征 无连 ...