4月25日星期二

文章提供了两个编程问题的解决方案。第一个问题是找到数组中需要升序排序的最长子数组,通过从两端寻找不同元素的索引并进行排序来实现。第二个问题涉及字符串处理,通过暴力穷举计算最少操作步数使字符串满足特定条件。

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

一、第一周任务 - Virtual Judge (vjudge.net)

1、这题是说有两个数组,对其中一个数组的子数组,进行升序排序后当前数组和另一个数组一致,我们需要找出这个最长子数组。

2、首先我们需要先确定基础范围,在向两边试探性搜索。

3、就是先(从左往右和从右往左)找出当前数组和另一个数组不一样的开始下表,l,r;

4、再然后我们需要l往左试探,r往右试探,l的左边比l小,r的右边比r打,就l--,r++,直到不满足试探条件或是到了边界就停止;

附代码

#include <iostream>
#include <algorithm>
#include <map>
#include <string>
using namespace std;

int a1[300005];
int a2[300005];

main(){
	int n;
	cin>>n;
	while(n--){
	int m,l,r;
	cin>>m;
	
	for(int i=1;i<=m;i++)
	cin>>a1[i];
	
	for(int i=1;i<=m;i++)
	cin>>a2[i];
	
	for(int i=1;i<=m;i++)
	if(a1[i]!=a2[i]){
		l=i;
		break;
	}
	
	for(int i=m;i>=1;i--)
	if(a1[i]!=a2[i]){
		r=i;
		break;
	}
	
	sort(a1+l,a1+r+1);
	
	for(int i=l-1;i>=1;i--){
		if(a1[i]<=a1[i+1])l=i;
		else break;
	}
	
	for(int i=r+1;i<=m;i++){
		if(a1[i]>=a1[i-1])r=i;
		else break;
	}
	
	cout<<l<<" "<<r<<endl;
	}
}

二、第一周任务 - Virtual Judge (vjudge.net)

1、这一题其实就是暴力穷举,我们首先获取这个字符串有多少种字符,放到一个数组。

2、并且获得这个字符在字符串中有多少个,然后就枚举每种字符,当做最后剩的字符,将其他字符按照删除规则删掉其他字符,算出有多少步,取所有枚举情况中最少的次数

附代码

#include <iostream>
#include<algorithm>
#include<map>
#include<string.h>

using namespace std;

int pd(string str,char max,int cs){
	int k=0,x2=0;
	char jl2[200005];
	
	for(int i=0;i<str.length();i++)
	{jl2[i]=str[i];jl2[i+1]='\0';}
	
	while(cs!=strlen(jl2)){
			k++;
			int cd=strlen(jl2);
		    for(int i=0;i<cd;i++){
		    	if(jl2[i]!=max){jl2[x2++]=jl2[++i];}
		    	else {jl2[x2++]=jl2[i];}
			}
			jl2[x2]='\0';
			x2=0;
		}
		
	return k;
}

main(){
	int n;
	cin>>n;
	while(n--){
		string str;
		char jl[200005];
		
		int x=0,cs=0,k=1000000;
		
		map<char,int>pj;
		
		cin>>str;
		
		for(int i=0;i<str.length();i++){
			if(pj[str[i]]==0)jl[x++]=str[i];
			
			pj[str[i]]++;
		}
		
		jl[x]='\0';
		
		for(int i=0;i<x;i++)
		if(pj[jl[i]]>cs){
			cs=pj[jl[i]];
		}
		
		if(cs>1){
		 for(int i=0;i<x;i++){
			  int m=pd(str,jl[i],pj[jl[i]]);	
			  if(m<k)k=m;
		 }
		 cout<<k<<endl;
		}
		else {
			int cd=str.length();
			int k=0;
			while(cd!=1){
				cd/=2;
				k++;
			}
			cout<<k<<endl;
		}
	}
}

<think>好的,我现在需要分析若依框架中hasPermi方法的实现原理。首先,我需要回忆一下若依框架的基本结构。若依是基于Spring BootSpring Security的权限管理系统,所以权限控制可能和这些技术有关。 用户提到的hasPermi方法,应该是在前端或后端用于检查用户是否有某个权限的。根据常见的权限设计,可能涉及到注解、拦截器或者AOP。比如,Spring Security通常使用@PreAuthorize这样的注解来控制权限,但若依可能有自己的实现方式。 查看引用中的资料,引用[3]提到RuoYi-Vue使用了Spring Security,配置了登录接口和权限控制,还有token生成。这可能意味着权限验证与Spring Security的整合有关。另外,引用[4]中提到了前端表单绑定和事件处理,但hasPermi可能在后端实现。 通常,权限方法如hasPermi会从用户的权限列表中检查是否存在对应的权限字符串。例如,用户登录后,其权限会被加载到SecurityContext中,然后在需要验证的地方,通过方法参数传入权限标识,检查当前用户是否有该权限。 在若依框架中,可能在后端有一个自定义的权限校验方法,结合了Spring Security的功能。比如,使用自定义注解,在方法执行前进行权限判断。源码中可能有类似@RequiresPermissions的注解,或者通过拦截器来实现。 另外,引用[3]提到“异步任务管理操作日志数据权限”,说明权限可能和数据权限有关联,但hasPermi更可能针对功能权限。需要查看若依的权限处理模块,可能在common模块或security模块中。 可能的实现步骤:用户登录后获取权限列表,存储到上下文中。调用hasPermi时,从上下文中取出权限列表,判断是否包含所需的权限字符串。源码中可能使用SecurityUtils.getLoginUser().getPermissions()来获取权限,然后进行contains检查。 需要确认hasPermi的具体代码位置,可能在权限服务类中,或者作为工具方法提供。此外,若依可能通过自定义的PermissionService来处理权限校验,结合Spring Security的认证信息。 总结:hasPermi方法的实现原理可能是基于当前用户的权限列表,检查传入的权限字符串是否存在其中。这涉及到用户权限的加载、存储及校验过程,结合Spring Security的上下文管理。</think>若依框架的`hasPermi`方法实现原理可分为以下几个关键步骤: --- ### 一、权限数据加载与存储 1. **用户登录时加载权限** 用户登录成功后,系统会从数据库查询用户的角色和权限标识(如`system:user:add`),并将这些权限绑定到用户对象中[^3]。 2. **存储到Security上下文** 权限数据通过Spring Security的`Authentication`对象存入安全上下文,可通过`SecurityContextHolder`获取: ```java LoginUser loginUser = SecurityUtils.getLoginUser(); Set<String> permissions = loginUser.getPermissions(); ``` --- ### 二、hasPermi方法源码分析 在`ruoyi-framework`模块的`com.ruoyi.framework.security.service.PermissionService`类中,核心逻辑如下: ```java public boolean hasPermi(String permission) { // 1. 超级管理员直接放行 if (SecurityUtils.isAdmin()) { return true; } // 2. 获取当前用户权限集合 Set<String> permissions = SecurityUtils.getLoginUser().getPermissions(); // 3. 检查权限标识是否存在 return permissions.contains(permission); } ``` **关键点解析**: - **管理员绕过校验**:若用户是管理员(如`isAdmin()`返回`true`),直接跳过权限检查。 - **权限集合来源**:权限数据在用户登录时已加载到`LoginUser`对象中。 - **精确匹配逻辑**:通过`contains`方法验证权限标识是否存在。 --- ### 三、权限控制的应用场景 1. **前端按钮级控制** 在Vue组件中使用`v-hasPermi`指令,动态隐藏无权限的按钮: ```vue <el-button v-hasPermi="'system:user:add'">新增用户</el-button> ``` 该指令底层调用`hasPermi`方法实现逻辑[^4]。 2. **后端接口拦截** 结合自定义注解`@RequiresPermissions`和AOP切面,在方法执行前校验权限: ```java @RequiresPermissions("system:user:edit") public void editUser(User user) { // 业务逻辑 } ``` --- ### 四、与其他模块的关联 1. **数据权限扩展** 若依框架通过`@DataScope`注解实现数据权限,与`hasPermi`的功能权限形成互补。 2. **动态数据源依赖** 权限数据查询依赖`ruoyi-common-datasource`模块,该模块封装了动态数据源配置[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值