基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式
-之动态查询,查询逻辑封装复用
https://www.cnblogs.com/neozhu/p/13174234.html
需求
- 配合EasyUI datagird filter实现多字段(任意字段)的筛选
- 根据业务需求筛选特定的状态或条件,如:查看结案的订单,最近30天的订单,查看属于我的订单.等等,这些逻辑是固定也是可以被重用,但又不想每次写相同的条件,那么下面我会给我的解决方案.
需求1只是一个偷懒的实现方式,因为datagrid自带这个功能,但又不想根据具体的需求来画查询条件,如果需求必须要再datagrid上面做一块查询条件的输入那目前只能在前端自己手工添加,在组织后传入后台,暂时不在这里讨论
需求2可能不太好解释,看完代码就自然理解为什么要这么做了,这么做的好处有哪些
具体实现的方式

默认情况下 datagrid 有几列就可以对这几列进行筛选,对于日期型的字段会采用between,选择2个时间之间进行筛选,数字类型会提供大于小于等符号选择,可以自行尝试,其原理是datagrid 会根据datagrid 头部输入的值生成一个Json字符串发送后台请求数据
JSON:格式
filterRules: [
{field:field,op:op,value:value},{field:field,op:op,value:value},]
- 通常的做法是一个一个判断加条件

var filters = JsonConvert.DeserializeObject<IEnumerable<filterRule>>(filterRules);
foreach (var rule in filters)
{
if (rule.field == "Id" && !string.IsNullOrEmpty(rule.value) && rule.value.IsInt())
{
var val = Convert.ToInt32(rule.value);
switch (rule.op)
{
case "equal":
this.And(x => x.Id == val);
break;
case "notequal":
this.And(x => x.Id != val);
break;
case "less":
this.And(x => x.Id < val);
break;
case "lessorequal":
this.And(x => x.Id <= val);
break;
case "greater":
this.And(x => x.Id > val);
break;
case "greaterorequal":
this.And(x => x.Id >= val);
break;
default:
this.And(x => x.Id == val);
break;
}
}
if (rule.field == "Name" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Name.Contains(rule.value));
}
if (rule.field == "Code" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Code.Contains(rule.value));
} if (rule.field == "Address" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Address.Contains(rule.value));
} if (rule.field == "Contect" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Contect.Contains(rule.value));
} if (rule.field == "PhoneNumber" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.PhoneNumber.Contains(rule.value));
} if (rule.field == "RegisterDate" && !string.IsNullOrEmpty(rule.value))
{
if (rule.op == "between")
{
var datearray = rule.value.Split(new char[] { '-' });
var start = Convert.ToDateTime(datearray[]);
var end = Convert.ToDateTime(datearray[]); this.And(x => SqlFunctions.DateDiff("d", start, x.RegisterDate) >= );
this.And(x => SqlFunctions.DateDiff("d", end, x.RegisterDate) <= );
}
}
if (rule.field == "CreatedDate" && !string.IsNullOrEmpty(rule.value))
{
if (rule.op == "between")
{
var datearray = rule.value.Split(new char[] { '-' });
var start = Convert.ToDateTime(datearray[]);
var end = Convert.ToDateTime(datearray[]); this.And(x => SqlFunctions.DateDiff("d", start, x.CreatedDate) >= );
this.And(x => SqlFunctions.DateDiff("d", end, x.CreatedDate) <= );
}
} if (rule.field == "CreatedBy" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.CreatedBy.Contains(rule.value));
} if (rule.field == "LastModifiedDate" && !string.IsNullOrEmpty(rule.value))
{
if (rule.op == "between")
{
var datearray = rule.value.Split(new char[] { '-' });
var start = Convert.ToDateTime(datearray[]);
var end = Convert.ToDateTime(datearray[]); this.And(x => SqlFunctions.DateDiff("d", start, x.LastModifiedDate) >= );
this.And(x => SqlFunctions.DateDiff("d", end, x.LastModifiedDate) <= );
}
} if (rule.field == "LastModifiedBy" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.LastModifiedBy.Contains(rule.value));
} }
- 新的做法是动态根据field,op,value生成一个linq 表达式,不用再做繁琐的判断,这块代码也可以被其它项目使用,非常好用

namespace SmartAdmin
{ public static class PredicateBuilder
{ public static Expression<Func<T, bool>> FromFilter<T>(string filtergroup) {
Expression<Func<T, bool>> any = x => true;
if (!string.IsNullOrEmpty(filtergroup))
{
var filters = JsonSerializer.Deserialize<filter[]>(filtergroup); foreach (var filter in filters)
{
if (Enum.TryParse(filter.op, out OperationExpression op) && !string.IsNullOrEmpty(filter.value))
{
var expression = GetCriteriaWhere<T>(filter.field, op, filter.value);
any = any.And(expression);
}
}
} return any;
} #region -- Public methods --
public static Expression<Func<T, bool>> GetCriteriaWhere<T>(Expression<Func<T, object>> e, OperationExpression selectedOperator, object fieldValue)
{
var name = GetOperand<T>(e);
return GetCriteriaWhere<T>(name, selectedOperator, fieldValue);
} public static Expression<Func<T, bool>> GetCriteriaWhere<T, T2>(Expression<Func<T, object>> e, OperationExpression selectedOperator, object fieldValue)
{
var name = GetOperand<T>(e);
return GetCriteriaWhere<T, T2>(name, selectedOperator, fieldValue);
} public static Expression<Func<T, bool>> GetCriteriaWhere<T>(string fieldName, OperationExpression selectedOperator, object fieldValue)
{
var props = TypeDescriptor.GetProperties(typeof(T));
var prop = GetProperty(props, fieldName, true);
var parameter = Expression.Parameter(typeof(T));
var expressionParameter = GetMemberExpression<T>(parameter, fieldName);
if (prop != null && fieldValue != null)
{ BinaryExpression body = null;
switch (selectedOperator)
{
case OperationExpression.equal:
body = Expression.Equal(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType)?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.notequal:
body = Expression.NotEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.less:
body = Expression.LessThan(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.lessorequal:
body = Expression.LessThanOrEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.greater:
body = Expression.GreaterThan(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.greaterorequal:
body = Expression.GreaterThanOrEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.contains:
var contains = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var bodyLike = Expression.Call(expressionParameter, contains, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(bodyLike, parameter);
case OperationExpression.endwith:
var endswith = typeof(string).GetMethod("EndsWith",new[] { typeof(string) });
var bodyendwith = Expression.Call(expressionParameter, endswith, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(bodyendwith, parameter);
case OperationExpression.beginwith:
var startswith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var bodystartswith = Expression.Call(expressionParameter, startswith, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(bodystartswith, parameter);
case OperationExpression.includes:
return Includes<T>(fieldValue, parameter, expressionParameter, prop.PropertyType);
case OperationExpression.between:
return Between<T>(fieldValue, parameter, expressionParameter, prop.PropertyType);
default:
throw new Exception("Not implement Operation");
}
}
else
{
Expression<Func<T, bool>> filter = x => true;
return filter;
}
} public static Expression<Func<T, bool>> GetCriteriaWhere<T, T2>(string fieldName, OperationExpression selectedOperator, object fieldValue)
{ var props = TypeDescriptor.GetProperties(typeof(T));
var prop = GetProperty(props, fieldName, true); var parameter = Expression.Parameter(typeof(T));
var expressionParameter = GetMemberExpression<T>(parameter, fieldName); if (prop != null && fieldValue != null)
{
switch (selectedOperator)
{
case OperationExpression.any:
return Any<T, T2>(fieldValue, parameter, expressionParameter); default:
throw new Exception("Not implement Operation");
}
}
else
{
Expression<Func<T, bool>> filter = x => true;
return filter;
}
} public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr, Expression<Func<T, bool>> or)
{
if (expr == null)
{
return or;
} return Expression.Lambda<Func<T, bool>>(Expression.OrElse(new SwapVisitor(expr.Parameters[], or.Parameters[]).Visit(expr.Body), or.Body), or.Parameters);
} public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr, Expression<Func<T, bool>> and)
{
if (expr == null)
{
return and;
} return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(new SwapVisitor(expr.Parameters[], and.Parameters[]).Visit(expr.Body), and.Body), and.Parameters);
} #endregion
#region -- Private methods -- private static string GetOperand<T>(Expression<Func<T, object>> exp)
{
if (!( exp.Body is MemberExpression body ))
{
var ubody = (UnaryExpression)exp.Body;
body = ubody.Operand as MemberExpression;
} var operand = body.ToString(); return operand.Substring(); } private static MemberExpression GetMemberExpression<T>(ParameterExpression parameter, string propName)
{
if (string.IsNullOrEmpty(propName))
{
return null;
} var propertiesName = propName.Split('.');
if (propertiesName.Count() == )
{
return Expression.Property(Expression.Property(parameter, propertiesName[]), propertiesName[]);
} return Expression.Property(parameter, propName);
} private static Expression<Func<T, bool>> Includes<T>(object fieldValue, ParameterExpression parameterExpression, MemberExpression memberExpression ,Type type)
{
var safetype= Nullable.GetUnderlyingType(type) ?? type; switch (safetype.Name.ToLower())
{
case "string":
var strlist = (IEnumerable<string>)fieldValue;
if (strlist == null || strlist.Count() == )
{
return x => true;
}
var strmethod = typeof(List<string>).GetMethod("Contains", new Type[] { typeof(string) });
var strcallexp = Expression.Call(Expression.Constant(strlist.ToList()), strmethod, memberExpression);
return Expression.Lambda<Func<T, bool>>(strcallexp, parameterExpression);
case "int32":
var intlist = (IEnumerable<int>)fieldValue;
if (intlist == null || intlist.Count() == )
{
return x => true;
}
var intmethod = typeof(List<int>).GetMethod("Contains", new Type[] { typeof(int) });
var intcallexp = Expression.Call(Expression.Constant(intlist.ToList()), intmethod, memberExpression);
return Expression.Lambda<Func<T, bool>>(intcallexp, parameterExpression);
case "float":
var floatlist = (IEnumerable<float>)fieldValue;
if (floatlist == null || floatlist.Count() == )
{
return x => true;
}
var floatmethod = typeof(List<int>).GetMethod("Contains", new Type[] { typeof(int) });
var floatcallexp = Expression.Call(Expression.Constant(floatlist.ToList()), floatmethod, memberExpression);
return Expression.Lambda<Func<T, bool>>(floatcallexp, parameterExpression);
default:
return x => true;
} }
private static Expression<Func<T, bool>> Between<T>(object fieldValue, ParameterExpression parameterExpression, MemberExpression memberExpression, Type type)
{ var safetype = Nullable.GetUnderlyingType(type) ?? type;
switch (safetype.Name.ToLower())
{
case "datetime":
var datearray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var start = Convert.ToDateTime(datearray[] + " 00:00:00", CultureInfo.CurrentCulture);
var end = Convert.ToDateTime(datearray[] + " 23:59:59", CultureInfo.CurrentCulture);
var greater = Expression.GreaterThan(memberExpression, Expression.Constant(start, type));
var less = Expression.LessThan(memberExpression, Expression.Constant(end, type));
return Expression.Lambda<Func<T, bool>>(greater, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(less, parameterExpression));
case "int":
case "int32":
var intarray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var min = Convert.ToInt32(intarray[] , CultureInfo.CurrentCulture);
var max = Convert.ToInt32(intarray[], CultureInfo.CurrentCulture);
var maxthen = Expression.GreaterThan(memberExpression, Expression.Constant(min, type));
var minthen = Expression.LessThan(memberExpression, Expression.Constant(max, type));
return Expression.Lambda<Func<T, bool>>(maxthen, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(minthen, parameterExpression));
case "decimal":
var decarray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var dmin = Convert.ToDecimal(decarray[], CultureInfo.CurrentCulture);
var dmax = Convert.ToDecimal(decarray[], CultureInfo.CurrentCulture);
var dmaxthen = Expression.GreaterThan(memberExpression, Expression.Constant(dmin, type));
var dminthen = Expression.LessThan(memberExpression, Expression.Constant(dmax, type));
return Expression.Lambda<Func<T, bool>>(dmaxthen, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(dminthen, parameterExpression));
case "float":
var farray = ((string)fieldValue).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var fmin = Convert.ToDecimal(farray[], CultureInfo.CurrentCulture);
var fmax = Convert.ToDecimal(farray[], CultureInfo.CurrentCulture);
var fmaxthen = Expression.GreaterThan(memberExpression, Expression.Constant(fmin, type));
var fminthen = Expression.LessThan(memberExpression, Expression.Constant(fmax, type));
return Expression.Lambda<Func<T, bool>>(fmaxthen, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(fminthen, parameterExpression));
case "string":
var strarray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var smin = strarray[];
var smax = strarray[]; var strmethod = typeof(string).GetMethod("Contains");
var mm = Expression.Call(memberExpression, strmethod, Expression.Constant(smin, type));
var nn = Expression.Call(memberExpression, strmethod, Expression.Constant(smax, type)); return Expression.Lambda<Func<T, bool>>(mm, parameterExpression)
.Or(Expression.Lambda<Func<T, bool>>(nn, parameterExpression));
default:
return x => true;
} } private static Expression<Func<T, bool>> Any<T, T2>(object fieldValue, ParameterExpression parameterExpression, MemberExpression memberExpression)
{
var lambda = (Expression<Func<T2, bool>>)fieldValue;
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
.First(m => m.Name == "Any" && m.GetParameters().Count() == ).MakeGenericMethod(typeof(T2)); var body = Expression.Call(anyMethod, memberExpression, lambda); return Expression.Lambda<Func<T, bool>>(body, parameterExpression);
} private static PropertyDescriptor GetProperty(PropertyDescriptorCollection props, string fieldName, bool ignoreCase)
{
if (!fieldName.Contains('.'))
{
return props.Find(fieldName, ignoreCase);
} var fieldNameProperty = fieldName.Split('.');
return props.Find(fieldNameProperty[], ignoreCase).GetChildProperties().Find(fieldNameProperty[], ignoreCase); }
#endregion
} internal class SwapVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node) => node == from ? to : base.Visit(node);
}
public enum OperationExpression
{
equal,
notequal,
less,
lessorequal,
greater,
greaterorequal,
contains,
beginwith,
endwith,
includes,
between,
any
}
}

public async Task<JsonResult> GetData(int page = , int rows = , string sort = "Id", string order = "asc", string filterRules = "")
{
try
{
var filters = PredicateBuilder.FromFilter<Company>(filterRules);
var total = await this.companyService
.Query(filters)
.AsNoTracking()
.CountAsync()
;
var pagerows = (await this.companyService
.Query(filters)
.AsNoTracking()
.OrderBy(n => n.OrderBy(sort, order))
.Skip(page - ).Take(rows)
.SelectAsync())
.Select(n => new
{
Id = n.Id,
Name = n.Name,
Code = n.Code,
Address = n.Address,
Contect = n.Contect,
PhoneNumber = n.PhoneNumber,
RegisterDate = n.RegisterDate.ToString("yyyy-MM-dd HH:mm:ss")
}).ToList();
var pagelist = new { total = total, rows = pagerows };
return Json(pagelist);
}
catch(Exception e) {
throw e;
} }
配合使用的代码
- 对于固定查询逻辑的封装和复用,当然除了复用还可以明显的提高代码的可读性.

public class OrderSalesQuery : QueryObject<Order>
{
public decimal Amount { get; set; }
public string Country { get; set; }
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; } public override Expression<Func<Order, bool>> Query()
{
return (x =>
x.OrderDetails.Sum(y => y.UnitPrice) > Amount &&
x.OrderDate >= FromDate &&
x.OrderDate <= ToDate &&
x.ShipCountry == Country);
}
}
查看订单的销售情况,条件 金额,国家,日期

var orderRepository = new Repository<Order>(this); var orders = orderRepository
.Query(new OrderSalesQuery(){
Amount = ,
Country = "USA",
FromDate = DateTime.Parse("01/01/1996"),
ToDate = DateTime.Parse("12/31/1996" )
})
.Select();
调用查询方法

public class CustomerLogisticsQuery : QueryObject<Customer>
{
public CustomerLogisticsQuery FromCountry(string country)
{
Add(x => x.Country == country);
return this;
} public CustomerLogisticsQuery LivesInCity(string city)
{
Add(x => x.City == city);
return this;
}
}
客户查询 根据国家和城市查询

public class CustomerSalesQuery : QueryObject<Customer>
{
public CustomerSalesQuery WithPurchasesMoreThan(decimal amount)
{
Add(x => x.Orders
.SelectMany(y => y.OrderDetails)
.Sum(z => z.UnitPrice * z.Quantity) > amount); return this;
} public CustomerSalesQuery WithQuantitiesMoreThan(decimal quantity)
{
Add(x => x.Orders
.SelectMany(y => y.OrderDetails)
.Sum(z => z.Quantity) > quantity); return this;
}
}
客户的销售情况,金额和数量

var customerRepository = new Repository<Customer>(this); var query1 = new CustomerLogisticsQuery()
.LivesInCity("London"); var query2 = new CustomerSalesQuery()
.WithPurchasesMoreThan()
.WithQuantitiesMoreThan(); customerRepository
.Query(query1.And(query2))
.Select()
.Dump();
复用上面的定义的查询方法
以上这些都是改项目提供的方法,非常的好用
基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式的更多相关文章
- 基于领域驱动设计(DDD)超轻量级快速开发架构
smartadmin.core.urf 这个项目是基于asp.net core 3.1(最新)基础上参照领域驱动设计(DDD)的理念,并参考目前最为了流行的abp架构开发的一套轻量级的快速开发web ...
- 领域驱动设计(DDD)
领域驱动设计(DDD)实现之路 2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱 ...
- 领域驱动设计(DDD:Domain-Driven Design)
领域驱动设计(DDD:Domain-Driven Design) Eric Evans的"Domain-Driven Design领域驱动设计"简称DDD,Evans DDD是一套 ...
- python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))
昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...
- 关于领域驱动设计 DDD(Domain-Driven Design)
以下旨在 理解DDD. 1. 什么是领域? 妈妈好是做母婴新零售的产品,应该属于电商平台,那么电商平台就是一个领域. 同一个领域的系统都有相同的核心业务. eg: 电商领域都有:商品浏览.购物 ...
- 分享我对领域驱动设计(DDD)的学习成果
本文内容提要: 1. 领域驱动设计之领域模型 2. 为什么建立一个领域模型是重要的 3. 领域通用语言(Ubiquitous Language) 4.将领域模型转换为代码实现的最佳实践 5. 领域建模 ...
- 我对领域驱动设计(DDD)的学习成果
领域驱动设计之领域模型 2004年Eric Evans发表Domain-Driven Design – Tackling Complexity in the Heart of Software (领域 ...
- 领域驱动设计(DDD)实践之路(一)
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/gk-Hb84Dt7JqBRVkMqM7Eg 作者:张文博 领域驱动设计(Domain Dr ...
- 领域驱动设计(DDD)实现之路
2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱动设计(DDD)已经是8年后的事 ...
随机推荐
- 03_K近邻算法
今天是2020年2月1日星期六,疫情延续,现在确诊人数达到了11821例,艰难困苦,玉汝于成,相信国家的力量!大家齐心协力干一件事,疫情会尽早结束的,武汉加油.前几天整理感知机算法的内容,发现写博客这 ...
- 轻便的一句话反弹shell语句
反弹shell往往是在攻击者无法直接连接受害者的情况下进行的操作,原因有很多,例如目标是局域网,或者开启防火墙的某些策略等情况,而这时,我们就可以让受害者主动向攻击者发起连接,被控端发起请求到控制端某 ...
- 潜入FLEXBOX——CSS弹性布局
介绍 Flexbox是CSS3中的一种新的布局模式,旨在满足现代Web的更复杂的需求.本文将详细介绍新近稳定化的Flexbox语法.浏览器支持将迅速增长,因此,当支持范围足够使Flexbox实用时,您 ...
- PAT1065 单身狗 (25分) 思路记录——参考大神柳婼
1065 单身狗 (25分) “单身狗”是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数 N(≤ 50 000), ...
- 腾讯云EMR大数据实时OLAP分析案例解析
OLAP(On-Line Analytical Processing),是数据仓库系统的主要应用形式,帮助分析人员多角度分析数据,挖掘数据价值.本文基于QQ音乐海量大数据实时分析场景,通过QQ音乐与腾 ...
- Java实现蓝桥杯 算法训练 ALGO-15 旅行家的预算
问题描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2.出发点每升汽油价格P和沿 ...
- (Java实现) 自然数的拆分
题目描述 任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和.拆分成的数字相同但顺序不同被看做是相同的方案,如果1+3与3+1被看做是同一种方案. 输入 输入待拆分的自然数n. 输出 如样 ...
- (Java实现) 洛谷 P1319 压缩技术
题目描述 设某汉字由N X N的0和1的点阵图案组成,如下图.我们依照以下规则生成压缩码.连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下.第一个数表示连续有几个0 ...
- Java实现 LeetCode 669 修剪二叉搜索树(遍历树)
669. 修剪二叉搜索树 给定一个二叉搜索树,同时给定最小边界L 和最大边界 R.通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) .你可能需要改变树的根节点,所以结果应当返回 ...
- Java实现子序列问题
一个串的子串是指该串的一个连续的局部.如果不要求连续,则可称为它的子序列. 比如对串: "abcdefg" 而言,"ab","abd",&q ...