SLF的消息记录(map记录字符串)

本文介绍了一个统计SLF男神收到最多短信的女孩的问题,并提供了一种解决方案,利用STL map来处理字符串,通过排序字符串来确保不同的顺序被视为同一个女孩。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SLF 的消息记录
Description
或许是人气过于旺盛,SLF 的手机一只叮叮叮响个不停。不用说,一定是女孩子发来的短信。
有一天,一直对此毫不在意的 SLF 男神来了兴趣,他想知道给他发消息最多的女孩是哪一位。
女孩的名字均由三个单词组成,由于女孩非常狡猾,她们有的时候会把自己的名字三个单词进行交换,所以名字的先后顺序不同也被视为是同一个女孩。
给出 n 条消息记录,每条记录包含三个单词,表示一个人,判定两条消息是否一样即判定三个单词交换顺序后(也可以不交换)是否完全相同,问出现次数最多的消息的出现的次数。

Input
第一行一个数 n。
接下来 n 行每行一条消息,三个用空格隔开的字符串,每个字符串只包含大写字母,
且长度大于 0 小于等于 10。

Output
一行一个数,表示发信息最多的女孩发消息的次数。

Sample Input
5
BESSIE ELSIE MATILDA
FRAN BESSIE INGRID
BESSIE ELSIE MATILDA
MATILDA INGRID FRAN
ELSIE BESSIE MATILDA


Sample Output
3

Hint
样例解释:{BESSIE, ELSIE, MATILDA}
对于 100%的数据,1 ≤ n ≤ 1000


思路

用stl封装的map映射可以方便的处理字符串

由于这里 名字的先后顺序不同也被视为是同一个女孩,先sort再存入map是很好的技巧


代码示例

#include<bits/stdc++.h>
using namespace std;
 
string str[1000][3];
map<string,int> ahu;
 
int main()
{
    string a;
    std::ios::sync_with_stdio(false);
    int n,max;
    max=-0x3fffffff;
    cin>>n;
    ahu.clear();
    for(int i=0;i<n;++i){
        cin>>str[i][0]>>str[i][1]>>str[i][2];
        sort(str[i],str[i]+3);
        a=str[i][0]+"+"+str[i][1]+"+"+str[i][2];
        ++ahu[a];//如果map中无a,则自动生成映射0,再加1 
        if(ahu[a]>max) max=ahu[a];
    }
    cout<<max<<endl;
    return 0;
}







<think>我们讨论的是日志配置,用户问“一般会记录结果吗?”可能是指日志中是否记录方法的返回结果。 在日志记录中,是否记录方法的结果(返回值)取决于具体的业务需求和安全性考虑。通常,在调试或跟踪重要业务操作时,记录返回值是有帮助的,但需要注意以下几点: 1. **敏感信息**:如果返回值包含敏感数据(如用户密码、银行卡号等),则不应该记录。 2. **数据量**:如果返回值非常大(如一个大列表或文件内容),记录它可能会影响性能并占用大量磁盘空间。 3. **必要性**:在调试时,记录返回值有助于追踪问题;在生产环境中,可能只记录关键操作的返回值。 在AOP中记录方法返回值的示例: 我们可以使用Spring AOP来拦截方法,并在方法执行成功后记录返回值。以下是一个示例: 假设我们有一个自定义注解 `@LogResult`,用于标记需要记录返回值的方法: 1. 定义注解: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogResult { // 可以添加一些属性,比如日志级别、是否记录返回值等 } ``` 2. 创建切面: ```java import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Aspect @Component public class LogResultAspect { private static final Logger logger = LoggerFactory.getLogger(LogResultAspect.class); @Around("@annotation(logResult)") public Object logResult(ProceedingJoinPoint joinPoint, LogResult logResult) throws Throwable { // 执行方法 Object result = joinPoint.proceed(); // 记录返回值 // 注意:实际应用中应该考虑返回值的大小和敏感信息,这里简单记录 logger.info("Method {}.{} returned: {}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(), result); return result; } } ``` 3. 在需要记录返回值的方法上使用注解: ```java @Service public class UserService { @LogResult public User getUserById(Long id) { // 从数据库获取用户 return userRepository.findById(id).orElse(null); } } ``` **注意事项**: - 如果返回值是对象,确保重写了 `toString()` 方法,以便输出有意义的日志。但注意不要输出敏感字段。 - 对于集合类型,可能只记录集合大小而不是所有元素,以避免日志过大。 - 考虑使用JSON序列化来记录对象,但同样要过滤敏感字段。 **安全建议**: 在记录返回值时,应避免记录敏感信息。可以通过以下方式改进: - 在注解中添加一个属性,指定需要脱敏的字段(如密码、身份证号等)。 - 在切面中使用反射或序列化工具(如Jackson)来过滤敏感字段。 例如,使用Jackson过滤敏感字段: ```java ObjectMapper objectMapper = new ObjectMapper(); objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class); // 自定义过滤规则 String resultJson = objectMapper.writeValueAsString(result); logger.info("Result: {}", resultJson); ``` 其中,`PropertyFilterMixIn` 可以定义哪些字段需要被忽略。 总结:是否记录结果(返回值)取决于具体场景。在需要调试或审计关键操作时,可以记录返回值,但必须确保不记录敏感信息,并注意性能影响。 §§相关问题§§: 1. 在日志记录中,如何避免记录敏感信息? 2. 使用AOP记录日志时,如何避免记录过大的返回值(如大文件或大列表)? 3. 如何动态控制日志记录的详细程度(例如,在开发环境记录返回值,生产环境不记录)? 4. 除了返回值,还有哪些方法执行信息值得记录?</think># 日志记录中是否记录方法返回结果 在Java应用中是否记录方法的返回结果取决于具体场景和需求,但一般来说需要谨慎处理。以下是详细的解释和建议: ## 一、是否记录返回结果的决策因素 ### ✅ 应该记录返回结果的情况 1. **关键业务操作**:如支付结果、订单创建结果等 2. **外部服务调用**:如API响应、数据库操作结果 3. **调试复杂逻辑**:开发阶段跟踪数据流转 4. **审计需求**:金融、医疗等合规性要求高的领域 ### ⚠️ 不应记录返回结果的情况 1. **敏感数据**:密码、银行卡号、身份证号等 2. **大型数据集**:返回List/Map包含大量元素 3. **高频调用方法**:性能敏感的核心路径 4. **二进制数据**:图片、文件等非文本内容 ## 二、记录返回结果的最佳实践 ### 1. 使用AOP进行选择性记录 ```java @Aspect @Component public class ResultLoggingAspect { private static final Logger logger = LoggerFactory.getLogger(ResultLoggingAspect.class); // 只记录带有@LogResult注解的方法 @Around("@annotation(LogResult)") public Object logResult(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); String methodName = signature.getMethod().getName(); try { Object result = joinPoint.proceed(); // 安全记录结果 if (shouldLogResult(result)) { logger.info("Method {} returned: {}", methodName, sanitizeResult(result)); } return result; } catch (Exception e) { logger.error("Method {} failed: {}", methodName, e.getMessage()); throw e; } } private boolean shouldLogResult(Object result) { // 不记录大型集合 if (result instanceof Collection && ((Collection<?>) result).size() > 20) { return false; } // 不记录二进制数据 if (result instanceof byte[]) { return false; } return true; } private Object sanitizeResult(Object result) { // 实现敏感数据过滤 if (result instanceof User) { User user = (User) result; return user.copyWithoutSensitiveData(); // 返回脱敏后的副本 } return result; } } // 自定义注解标记需要记录的方法 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface LogResult { LogLevel value() default LogLevel.INFO; enum LogLevel { DEBUG, INFO } } ``` ### 2. 在Service中使用 ```java @Service public class PaymentService { @LogResult(LogLevel.INFO) public PaymentResult processPayment(PaymentRequest request) { // 支付处理逻辑 return paymentGateway.process(request); } // 不记录结果的方法 public User getUserDetails(String userId) { // 返回包含敏感信息的对象 return userRepository.findById(userId); } } ``` ### 3. 日志输出示例 ``` 2023-08-15 14:30:25.123 | INFO | processPayment returned: PaymentResult{status="SUCCESS", transactionId="TX-12345", amount=100.00} ``` ## 三、安全记录结果的策略 ### 1. 数据脱敏处理 ```java public class User { private String id; private String name; private String email; private String password; // 敏感字段 // 脱敏后的表示 public String toLogString() { return String.format("User{id=%s, name=%s, email=%s}", id, name, maskEmail(email)); } private String maskEmail(String email) { int atIndex = email.indexOf('@'); if (atIndex > 2) { return email.substring(0, 2) + "***" + email.substring(atIndex); } return "***"; } } ``` ### 2. 限制日志大小 ```java private String truncateLargeResult(Object result) { String resultStr = result.toString(); if (resultStr.length() > 500) { return resultStr.substring(0, 500) + "... [TRUNCATED]"; } return resultStr; } ``` ### 3. 使用JSON序列化并过滤字段 ```java private String toSafeJson(Object obj) { ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(Object.class, PropertyFilterMixIn.class); try { return mapper.writeValueAsString(obj); } catch (JsonProcessingException e) { return "[Unable to serialize]"; } } @JsonFilter("propertyFilter") class PropertyFilterMixIn { // 通过配置指定要过滤的字段 } ``` ## 四、性能优化建议 1. **使用条件日志**避免不必要的字符串拼接 ```java if (logger.isInfoEnabled()) { logger.info("Result: {}", expensiveToStringOperation()); } ``` 2. **异步记录**大结果集 ```java executorService.submit(() -> { logger.debug("Full result: {}", fullResult); }); ``` 3. **采样记录**高频方法 ```java private AtomicInteger counter = new AtomicInteger(); public void logResultConditionally(Object result) { if (counter.incrementAndGet() % 100 == 0) { logger.info("Sampled result: {}", result); } } ``` ## 五、总结建议 1. **默认不记录**返回结果,仅在必要时添加 2. **使用注解驱动**(如`@LogResult`)明确标记需要记录的方法 3. **始终对敏感数据脱敏** 4. **限制日志大小**,防止日志爆炸 5. **考虑性能影响**,高频方法使用采样或异步记录 在大多数企业应用中,推荐只记录关键业务方法的返回结果,并始终遵循最小化日志原则(记录必要信息但不超过需求)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值