目录:
1.『攻略方式』 定义了算法族,分别封装起来,让它们之间能够并行替换,此方式让算法的转移独立于采取算法的客商。
//获取时间戳 .net framework
/*
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
int time = (int)(DateTime.Now - dt).TotalSeconds;
String Timestamp = time.ToString();
*/
// .net core 获取时间戳
DateTime dt = new DateTime(1970, 1, 1,0, 0, 0, DateTimeKind.Utc);
int time = (int)(DateTime.Now.AddHours(-8) - dt).TotalSeconds;
String Timestamp = time.ToString();
//随机正整数,用于防止重放攻击
Random rd = new Random();
int rd_i = rd.Next();
String nonce = Convert.ToString(rd_i);
//SecretId
String SecretId = "";
//参数(用于编码)
String PostStr = string.Format("Action=DescribeLVBChannelList&Nonce={0}&Region=bj&SecretId={1}&Timestamp={2}", nonce, SecretId, Timestamp);
//地址
String url = "https://live.api.qcloud.com/v2/index.php";
//编码
UTF8Encoding enc = new UTF8Encoding();
String qm = "POSTlive.api.qcloud.com/v2/index.php" + "?" + PostStr;
byte[] dataToHash = enc.GetBytes(qm);
/*
var sha1 = SHA1.Create();
var result = sha1.ComputeHash(dataToHash);
*/
HMACSHA1 hmac = new HMACSHA1()
{
Key = enc.GetBytes("")
};
var result = hmac.ComputeHash(dataToHash);
string Signature = Convert.ToBase64String(result);
//完整参数
var completeUrl = string.Format("Action=DescribeLVBChannelList&Nonce={0}&Region=bj&SecretId={1}&Signature={2}&Timestamp={3}", nonce, SecretId, Signature, Timestamp);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ProtocolVersion = HttpVersion.Version10;
byte[] data = Encoding.UTF8.GetBytes(completeUrl);
request.ContentLength = data.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
HttpWebResponse response = null;
int httpStatus = 200;
string content;
try
{
response = (HttpWebResponse)request.GetResponse();
httpStatus = (int)response.StatusCode;
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
content = reader.ReadToEnd();
}
catch (WebException e)
{
response = (HttpWebResponse)e.Response;
httpStatus = (int)response.StatusCode;
using (Stream errData = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(errData))
{
content = reader.ReadToEnd();
}
}
}
依靠Dapper叁遍封装了三个易用的ORM工具类:SqlDapperUtil,把通常能用到的种种CRUD都举行了简化封装,让日常工程师只需关怀专门的学业就能够,因为特简单,故直接贴源代码,我们若需使用能够平素复制到项目中,该SqlDapperUtil已司空见惯用于公司项目中。
亲自去做数组为:
1.time和datetime模块
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.IO;
using System.Collections.Concurrent;
using System.Data.SqlClient;
namespace Zuowj.Common
{
/// <summary>
/// 基于Dapper的数据操作类封装的工具类
/// Author:左文俊
/// Date:2017/12/11
/// </summary>
public class SqlDapperUtil
{
private static string dbConnectionStringConfigPath = null;
private readonly static ConcurrentDictionary<string, bool> dbConnNamesCacheDic = new ConcurrentDictionary<string, bool>();
private string dbConnectionName = null;
private string dbConnectionString = null;
private string dbProviderName = null;
private IDbConnection dbConnection = null;
private bool useDbTransaction = false;
private IDbTransaction dbTransaction = null;
#region 私有方法
private IDbConnection GetDbConnection()
{
bool needCreateNew = false;
if (dbConnection == null || string.IsNullOrWhiteSpace(dbConnection.ConnectionString))
{
needCreateNew = true;
}
else if (!MemoryCacheUtil.Contains(dbConnectionName))
{
needCreateNew = true;
}
if (needCreateNew)
{
dbConnectionString = GetDbConnectionString(dbConnectionName, out dbProviderName);
var dbProviderFactory = DbProviderFactories.GetFactory(dbProviderName);
dbConnection = dbProviderFactory.CreateConnection();
dbConnection.ConnectionString = dbConnectionString;
}
if (dbConnection.State == ConnectionState.Closed)
{
dbConnection.Open();
}
return dbConnection;
}
private string GetDbConnectionString(string dbConnName, out string dbProviderName)
{
//如果指定的连接字符串配置文件路径,则创建缓存依赖,一旦配置文件更改就失效,再重新读取
string[] connInfos = MemoryCacheUtil.GetOrAddCacheItem(dbConnName, () =>
{
var connStrSettings = ConfigUtil.GetConnectionStringForConfigPath(dbConnName, SqlDapperUtil.DbConnectionStringConfigPath);
string dbProdName = connStrSettings.ProviderName;
string dbConnStr = connStrSettings.ConnectionString;
//LogUtil.Info(string.Format("SqlDapperUtil.GetDbConnectionString>读取连接字符串配置节点[{0}]:{1},ProviderName:{2}", dbConnName, dbConnStr, dbProdName), "SqlDapperUtil.GetDbConnectionString");
return new[] { EncryptUtil.Decrypt(dbConnStr), dbProdName };
}, SqlDapperUtil.DbConnectionStringConfigPath);
dbProviderName = connInfos[1];
return connInfos[0];
}
private T UseDbConnection<T>(Func<IDbConnection, T> queryOrExecSqlFunc)
{
IDbConnection dbConn = null;
try
{
Type modelType = typeof(T);
var typeMap = Dapper.SqlMapper.GetTypeMap(modelType);
if (typeMap == null || !(typeMap is ColumnAttributeTypeMapper<T>))
{
Dapper.SqlMapper.SetTypeMap(modelType, new ColumnAttributeTypeMapper<T>());
}
dbConn = GetDbConnection();
if (useDbTransaction && dbTransaction == null)
{
dbTransaction = GetDbTransaction();
}
return queryOrExecSqlFunc(dbConn);
}
catch
{
throw;
}
finally
{
if (dbTransaction == null && dbConn != null)
{
CloseDbConnection(dbConn);
}
}
}
private void CloseDbConnection(IDbConnection dbConn, bool disposed = false)
{
if (dbConn != null)
{
if (disposed && dbTransaction != null)
{
dbTransaction.Rollback();
dbTransaction.Dispose();
dbTransaction = null;
}
if (dbConn.State != ConnectionState.Closed)
{
dbConn.Close();
}
dbConn.Dispose();
dbConn = null;
}
}
/// <summary>
/// 获取一个事务对象(如果需要确保多条执行语句的一致性,必需使用事务)
/// </summary>
/// <param name="il"></param>
/// <returns></returns>
private IDbTransaction GetDbTransaction(IsolationLevel il = IsolationLevel.Unspecified)
{
return GetDbConnection().BeginTransaction(il);
}
private DynamicParameters ToDynamicParameters(Dictionary<string, object> paramDic)
{
return new DynamicParameters(paramDic);
}
#endregion
public static string DbConnectionStringConfigPath
{
get
{
if (string.IsNullOrEmpty(dbConnectionStringConfigPath))//如果没有指定配置文件,则取默认的配置文件路径作为缓存依赖路径
{
dbConnectionStringConfigPath = BaseUtil.GetConfigPath();
}
return dbConnectionStringConfigPath;
}
set
{
if (!string.IsNullOrWhiteSpace(value) && !File.Exists(value))
{
throw new FileNotFoundException("指定的DB连接字符串配置文件不存在:" + value);
}
//如果配置文件改变,则可能导致连接字符串改变,故必需清除所有连接字符串的缓存以便后续重新加载字符串
if (!string.Equals(dbConnectionStringConfigPath, value, StringComparison.OrdinalIgnoreCase))
{
foreach (var item in dbConnNamesCacheDic)
{
MemoryCacheUtil.RemoveCacheItem(item.Key);
}
}
dbConnectionStringConfigPath = value;
}
}
public SqlDapperUtil(string connName)
{
dbConnectionName = connName;
if (!dbConnNamesCacheDic.ContainsKey(connName)) //如果静态缓存中没有,则加入到静态缓存中
{
dbConnNamesCacheDic[connName] = true;
}
}
/// <summary>
/// 使用事务
/// </summary>
public void UseDbTransaction()
{
useDbTransaction = true;
}
/// <summary>
/// 获取一个值,param可以是SQL参数也可以是匿名对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public T GetValue<T>(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null)
{
return UseDbConnection((dbConn) =>
{
return dbConn.ExecuteScalar<T>(sql, param, dbTransaction, commandTimeout, commandType);
});
}
/// <summary>
/// 获取第一行的所有值,param可以是SQL参数也可以是匿名对象
/// </summary>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public Dictionary<string, dynamic> GetFirstValues(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null)
{
return UseDbConnection((dbConn) =>
{
Dictionary<string, dynamic> firstValues = new Dictionary<string, dynamic>();
List<string> indexColNameMappings = new List<string>();
int rowIndex = 0;
using (var reader = dbConn.ExecuteReader(sql, param, dbTransaction, commandTimeout, commandType))
{
while (reader.Read())
{
if ((++rowIndex) > 1) break;
if (indexColNameMappings.Count == 0)
{
for (int i = 0; i < reader.FieldCount; i++)
{
indexColNameMappings.Add(reader.GetName(i));
}
}
for (int i = 0; i < reader.FieldCount; i++)
{
firstValues[indexColNameMappings[i]] = reader.GetValue(i);
}
}
reader.Close();
}
return firstValues;
});
}
/// <summary>
/// 获取一个数据模型实体类,param可以是SQL参数也可以是匿名对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public T GetModel<T>(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null) where T : class
{
return UseDbConnection((dbConn) =>
{
return dbConn.QueryFirstOrDefault<T>(sql, param, dbTransaction, commandTimeout, commandType);
});
}
/// <summary>
/// 获取符合条件的所有数据模型实体类列表,param可以是SQL参数也可以是匿名对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="buffered"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public List<T> GetModelList<T>(string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) where T : class
{
return UseDbConnection((dbConn) =>
{
return dbConn.Query<T>(sql, param, dbTransaction, buffered, commandTimeout, commandType).ToList();
});
}
/// <summary>
/// 获取符合条件的所有数据并根据动态构建Model类委托来创建合适的返回结果(适用于临时性结果且无对应的模型实体类的情况)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="buildModelFunc"></param>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <param name="buffered"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public T GetDynamicModel<T>(Func<IEnumerable<dynamic>, T> buildModelFunc, string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
var dynamicResult = UseDbConnection((dbConn) =>
{
return dbConn.Query(sql, param, dbTransaction, buffered, commandTimeout, commandType);
});
return buildModelFunc(dynamicResult);
}
/// <summary>
/// 获取符合条件的所有指定返回结果对象的列表(复合对象【如:1对多,1对1】),param可以是SQL参数也可以是匿名对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="types"></param>
/// <param name="map"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="buffered"></param>
/// <param name="splitOn"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public List<T> GetMultModelList<T>(string sql, Type[] types, Func<object[], T> map, object param = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
return UseDbConnection((dbConn) =>
{
return dbConn.Query<T>(sql, types, map, param, dbTransaction, buffered, splitOn, commandTimeout, commandType).ToList();
});
}
/// <summary>
/// 执行SQL命令(CRUD),param可以是SQL参数也可以是要添加的实体类
/// </summary>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public bool ExecuteCommand(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null)
{
return UseDbConnection((dbConn) =>
{
int result = dbConn.Execute(sql, param, dbTransaction, commandTimeout, commandType);
return (result > 0);
});
}
/// <summary>
/// 批量转移数据(利用SqlBulkCopy实现快速大批量插入到指定的目的表及SqlDataAdapter的批量删除)
/// </summary>
public bool BatchMoveData(string srcSelectSql, string srcTableName, List<SqlParameter> srcPrimarykeyParams, string destConnName, string destTableName)
{
using (SqlDataAdapter srcSqlDataAdapter = new SqlDataAdapter(srcSelectSql, GetDbConnectionString(dbConnectionName, out dbProviderName)))
{
DataTable srcTable = new DataTable();
SqlCommand deleteCommand = null;
try
{
srcSqlDataAdapter.AcceptChangesDuringFill = true;
srcSqlDataAdapter.AcceptChangesDuringUpdate = false;
srcSqlDataAdapter.Fill(srcTable);
if (srcTable == null || srcTable.Rows.Count <= 0) return true;
string notExistsDestSqlWhere = null;
string deleteSrcSqlWhere = null;
for (int i = 0; i < srcPrimarykeyParams.Count; i++)
{
string keyColName = srcPrimarykeyParams[i].ParameterName.Replace("@", "");
notExistsDestSqlWhere += string.Format(" AND told.{0}=tnew.{0}", keyColName);
deleteSrcSqlWhere += string.Format(" AND {0}=@{0}", keyColName);
}
string dbProviderName2 = null;
using (var destConn = new SqlConnection(GetDbConnectionString(destConnName, out dbProviderName2)))
{
destConn.Open();
string tempDestTableName = "#temp_" + destTableName;
destConn.Execute(string.Format("select top 0 * into {0} from {1}", tempDestTableName, destTableName));
string destInsertCols = null;
using (var destSqlBulkCopy = new SqlBulkCopy(destConn))
{
try
{
destSqlBulkCopy.BulkCopyTimeout = 120;
destSqlBulkCopy.DestinationTableName = tempDestTableName;
foreach (DataColumn col in srcTable.Columns)
{
destSqlBulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
destInsertCols += "," + col.ColumnName;
}
destSqlBulkCopy.BatchSize = 1000;
destSqlBulkCopy.WriteToServer(srcTable);
}
catch (Exception ex)
{
//LogUtil.Error("SqlDapperUtil.BatchMoveData.SqlBulkCopy:" + ex.ToString(), "SqlDapperUtil.BatchMoveData");
}
destInsertCols = destInsertCols.Substring(1);
destConn.Execute(string.Format("insert into {1}({0}) select {0} from {2} tnew where not exists(select 1 from {1} told where {3})",
destInsertCols, destTableName, tempDestTableName, notExistsDestSqlWhere.Trim().Substring(3)), null, null, 100);
}
destConn.Close();
}
deleteCommand = new SqlCommand(string.Format("DELETE FROM {0} WHERE {1}", srcTableName, deleteSrcSqlWhere.Trim().Substring(3)), srcSqlDataAdapter.SelectCommand.Connection);
deleteCommand.Parameters.AddRange(srcPrimarykeyParams.ToArray());
deleteCommand.UpdatedRowSource = UpdateRowSource.None;
deleteCommand.CommandTimeout = 200;
srcSqlDataAdapter.DeleteCommand = deleteCommand;
foreach (DataRow row in srcTable.Rows)
{
row.Delete();
}
srcSqlDataAdapter.UpdateBatchSize = 1000;
srcSqlDataAdapter.Update(srcTable);
srcTable.AcceptChanges();
return true;
}
catch (Exception ex)
{
//LogUtil.Error("SqlDapperUtil.BatchMoveData:" + ex.ToString(), "SqlDapperUtil.BatchMoveData");
return false;
}
finally
{
if (deleteCommand != null)
{
deleteCommand.Parameters.Clear();
}
}
}
}
/// <summary>
/// 批量复制数据(把源DB中根据SQL语句查出的结果批量COPY插入到目的DB的目的表中)
/// </summary>
public TResult BatchCopyData<TResult>(string srcSelectSql, string destConnName, string destTableName, IDictionary<string, string> colMappings, Func<IDbConnection, TResult> afterCoppyFunc)
{
using (SqlDataAdapter srcSqlDataAdapter = new SqlDataAdapter(srcSelectSql, GetDbConnectionString(dbConnectionName, out dbProviderName)))
{
DataTable srcTable = new DataTable();
TResult copyResult = default(TResult);
try
{
srcSqlDataAdapter.AcceptChangesDuringFill = true;
srcSqlDataAdapter.AcceptChangesDuringUpdate = false;
srcSqlDataAdapter.Fill(srcTable);
if (srcTable == null || srcTable.Rows.Count <= 0) return copyResult;
string dbProviderName2 = null;
using (var destConn = new SqlConnection(GetDbConnectionString(destConnName, out dbProviderName2)))
{
destConn.Open();
string tempDestTableName = "#temp_" + destTableName;
destConn.Execute(string.Format("select top 0 * into {0} from {1}", tempDestTableName, destTableName));
bool bcpResult = false;
using (var destSqlBulkCopy = new SqlBulkCopy(destConn))
{
try
{
destSqlBulkCopy.BulkCopyTimeout = 120;
destSqlBulkCopy.DestinationTableName = tempDestTableName;
foreach (var col in colMappings)
{
destSqlBulkCopy.ColumnMappings.Add(col.Key, col.Value);
}
destSqlBulkCopy.BatchSize = 1000;
destSqlBulkCopy.WriteToServer(srcTable);
bcpResult = true;
}
catch (Exception ex)
{
//LogUtil.Error("SqlDapperUtil.BatchMoveData.SqlBulkCopy:" + ex.ToString(), "SqlDapperUtil.BatchMoveData");
}
}
if (bcpResult)
{
copyResult = afterCoppyFunc(destConn);
}
destConn.Close();
}
return copyResult;
}
catch (Exception ex)
{
//LogUtil.Error("SqlDapperUtil.BatchCopyData:" + ex.ToString(), "SqlDapperUtil.BatchCopyData");
return copyResult;
}
}
}
/// <summary>
/// 当使用了事务,则最后需要调用该方法以提交所有操作
/// </summary>
/// <param name="dbTransaction"></param>
public void Commit()
{
try
{
if (dbTransaction.Connection != null && dbTransaction.Connection.State != ConnectionState.Closed)
{
dbTransaction.Commit();
}
}
catch
{
throw;
}
finally
{
if (dbTransaction.Connection != null)
{
CloseDbConnection(dbTransaction.Connection);
}
dbTransaction.Dispose();
dbTransaction = null;
useDbTransaction = false;
if (dbConnection != null)
{
CloseDbConnection(dbConnection);
}
}
}
/// <summary>
/// 当使用了事务,如果报错或需要中断执行,则需要调用该方法执行回滚操作
/// </summary>
/// <param name="dbTransaction"></param>
public void Rollback()
{
try
{
if (dbTransaction.Connection != null && dbTransaction.Connection.State != ConnectionState.Closed)
{
dbTransaction.Rollback();
}
}
catch
{
throw;
}
finally
{
if (dbTransaction.Connection != null)
{
CloseDbConnection(dbTransaction.Connection);
}
dbTransaction.Dispose();
dbTransaction = null;
useDbTransaction = false;
}
}
~SqlDapperUtil()
{
try
{
CloseDbConnection(dbConnection, true);
}
catch
{ }
}
}
}
调用Tencent云API的实例,基于Dapper二回封装了一个易用的ORM工具类云顶娱乐送6元救济官网金:。 $a = array(9,3,5,8,2,7); //下标为0,1,2,3,4,5
2. random模块
ColumnAttributeTypeMapper支持类相关代码如下:(假如不考虑实体类的性情与表字段不生龙活虎致的场所,如下映射类能够无需加上,同不时间SqlDapperUtil中移除相关依赖ColumnAttributeTypeMapper逻辑就可以)
演算进度描述:
3. OS模块(是与操作系统人机联作的三个接口卡塔尔
OO基础:抽象 封装 多态 继承
using Dapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace KYExpress.Common
{
public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
{
public ColumnAttributeTypeMapper()
: base(new SqlMapper.ITypeMap[]
{
new CustomPropertyTypeMap(
typeof(T),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName)
)
),
new DefaultTypeMap(typeof(T))
})
{
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class ColumnAttribute : Attribute
{
public string Name { get; set; }
}
public class FallbackTypeMapper : SqlMapper.ITypeMap
{
private readonly IEnumerable<SqlMapper.ITypeMap> _mappers;
public FallbackTypeMapper(IEnumerable<SqlMapper.ITypeMap> mappers)
{
_mappers = mappers;
}
public ConstructorInfo FindConstructor(string[] names, Type[] types)
{
foreach (var mapper in _mappers)
{
try
{
ConstructorInfo result = mapper.FindConstructor(names, types);
if (result != null)
{
return result;
}
}
catch (NotImplementedException)
{
}
}
return null;
}
public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
{
foreach (var mapper in _mappers)
{
try
{
var result = mapper.GetConstructorParameter(constructor, columnName);
if (result != null)
{
return result;
}
}
catch (NotImplementedException)
{
}
}
return null;
}
public SqlMapper.IMemberMap GetMember(string columnName)
{
foreach (var mapper in _mappers)
{
try
{
var result = mapper.GetMember(columnName);
if (result != null)
{
return result;
}
}
catch (NotImplementedException)
{
}
}
return null;
}
public ConstructorInfo FindExplicitConstructor()
{
return _mappers
.Select(mapper => mapper.FindExplicitConstructor())
.FirstOrDefault(result => result != null);
}
}
}
从数组的左侧起始,依次两两比较相邻的2个数据的分寸,借使发掘右侧包车型地铁比左侧的大,则将他们实行调换。那样实行“生龙活虎趟”之后,必然能够分明最大的叁个数码放在最右边。
云顶娱乐送6元救济官网金,4. sys模块(sys模块是与python解释器交互作用的二个接口卡塔尔
OO原则:封装变化 多用组合,小用继承 针对接口编制程序,不针对贯彻编制程序。
动用示例方法如下:
按此措施,对“剩余的数据”继续拓展下生机勃勃趟,则终将能够规定这几个剩余数量的最大值放在剩余地点的最左边。
本文由云顶集团线路检测发布,转载请注明来源
关键词: