头像

Gzm1317

伟大的黑色




离线:4小时前


最近来访(1138)
用户头像
kongkong1424
用户头像
77777777777
用户头像
一万小时定律
用户头像
syx123456
用户头像
spike_1
用户头像
Forms
用户头像
wKingYu
用户头像
蜉蝣
用户头像
Resurgence1001
用户头像
su尔
用户头像
jjj_k
用户头像
YoungOmari
用户头像
图灵机
用户头像
Raylv
用户头像
eon123
用户头像
507_7
用户头像
sinten
用户头像
天爱之白雨中船帆
用户头像
renaissance.
用户头像
Yan167


Gzm1317
16天前

我的项目地址

又写了一大堆代码,这时候都写了这么多了,虽然很多都是使用现成的玩意。可想而知构建一个完整的项目工程量巨大




Gzm1317
22天前

@TOC

前言

[更好的阅读体验] 可能正在审核
技术栈 : Spring Mysql Mybatis-Plus


模型介绍1

一般来说只有一个后端即(Springboot)
而一个后端服务多个Client

较为常见的是 :
每个用户会给服务器传送用户名和密码

而对于这些用户信息的存放我们采用数据库存放

这里采用Mysql
在这里插入图片描述

Mysql安装过程不在介绍


Mysql

0. 启动服务
我们在安装并且配置好Mysql环境变量的之后

我们需要先使用
net start mysql80 启动服务
当然我们也可以使用
net stop mysql80进行关闭服务

(至于需不需要手动关闭,这里我不清楚)

1.基本命令
我们通过mysql -u root -p之后输入密码,进行登录本地的数据库

进入数据库最大的变化就是命令行变为

mysql>

下面是基本命令的介绍 :
注意每个命令之后都需要紧跟着一个;
show databases;:列出所有数据库
create database kob;:创建数据库
drop database kob;:删除数据库
use kob;:使用数据库kob
show tables;:列出当前数据库的所有表
create table user(id int, username varchar(100)):创建名称为user的表,表中包含idusername两个属性。
drop table user;:删除表
insert into user values(1, 'yxc');:在表中插入数据
select * from user;:查询表中所有数据
delete from user where id = 2;:删除某行数据

(因为我们可以通过IDEA可视化的操作数据库,所以我们这里直接CV讲义)

因为Mysql关系型数据库,通俗的来说就是一个二维表所以其结构非常好懂

数据库1
    表1
                属性1  属性2
        行1  列1...
        行2      列2...
        行3      列3....
    表2
    表3
数据库2
....

IDEA操作Mysql

0.基本操作

在这里插入图片描述

在这里插入图片描述

通过IDEA直接链接我们的本地数据库,填入相关的账号和密码以及需要使用的数据库之后,直接应用即可

在这里插入图片描述
通过可视化界面,我们可以完成最基础的加一行和加一列操作
(其他操作就不一一列出了)

2.配置相关依赖


Spring Boot Starter JDBC
1. 实现对数据源的自动装配 (自动装配是Spring的基本概念)
- dataSource
2. 事务控制支持

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.7.1</version>
        </dependency>

Project Lombok
这个东西是一个懒人工具,没记错图标是一个小辣椒
(知乎上面 正反五五开)

对于以前我么需要手写或者自动生成的get,set,tostring方法

在安装了这个之后都可以直接使用@Data的注解进行简化

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>

MySQL Connector/J
这是一个MySQL的JDBC驱动

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>

mybatis-plus-boot-starter
这是Mybatis -plus,只学过Mybatis,plus还没学不清楚是什么

之前学Mybatis的时候一直在写xml文件管理SQL语句

但是看y总用plus没写过xml可能优化了这点

       <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

mybatis-plus-generator
这个不清楚百度到是代码生成器(第一次用)
y总说会自动生成一些函数

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>

3.配置application.properties
配置如下
这个基本上是一个模板,无需了解

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/kob?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

SpringBoot层次

pojo层 : 这里是将数据库中属性对应到Java的类中

mapper/Dao层 : 这个层是对pojo或者对数据库中的一张表的CRUD进行封装。没记错的话,SSMDao层都是接口,即只做原子操作,不考虑如何实现一个功能

service层 : 对多个Dao进行封装,也就是通过多个Dao实现具体的一个功能

serviceImpl层 : 这个是service接口的实现类,给controller层使用

Controller层 : 请求转发实现页面跳转(上节课的内容)


POJO

显然我们根据数据库中的表进行对应我们可以得到
一个User类包含id,username,password

数据库中的属性对应到Java中

@Data //小辣椒 简化了get set tostring
@NoArgsConstructor//无参构造
@AllArgsConstructor//有参构造 显然这两个市成对出现的
public class User {
    private  Integer id;
    private  String username;
    private  String password;
}

DAO

一个表对应一个DAO
BaseMapper是Mybatis-plus通用CRUD封装接口

即里面封装了很多CRUD的操作

(如果是Mybatis的话得手写QAQ)
[了解更多点击这里]

@Mapper这个是Mybatis对接口层的一个注解,没有这个的话我们还需要写一个xml然后让Spring去扫描这个地址
(少走几十年弯路)

@Mapper
public interface UserMapper  extends BaseMapper<User> {
}

Controller

@RestController
为什么这里不是Controller而是RestController
查了一些博客之后,发现RestController会使得方法返回不再是跳转页面了,即不在返回jsp,html页面

@GetMapping(“/user/{userId}/ 这种写法会将第二个输入的东西变为userId变为己用


@RestController
public class UserController {
    @Autowired //完成自动装配

    UserMapper userMapper;

    @GetMapping("/user/all")//请求映射
    public List<User> getAll(){
        return userMapper.selectList(null);
    }

    @GetMapping("/user/{userID}/")
    public User getUser(@PathVariable int userId){
        return userMapper.selectById(null);
    }


    @GetMapping("/user/add/{userId}/{username}/{password}/")
    public String addUser(@PathVariable int userId,@PathVariable String username,@PathVariable String password){
        User user = new User(userId,username,password);
        userMapper.insert(user);
        return "Add user successfully";
    }

    @GetMapping("/user/delete/{userId}/")
    public String deleteUser(@PathVariable int userId){
        userMapper.deleteById(userId);
        return "dele successfully";
    }


}


权限判断

Spring Security
安装这个我安装高版本会报错,所以这里安装了一个低版本的

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.6.9</version>
        </dependency>

小插曲 :
这里balabala了一堆下节课的东西,说以前判断是用Session判断,但是Session存在跨域问题,所以我们现在 使用 token判断。(反正也听不懂,小插曲)


安装好这个依赖之后,我们再次启动服务就会发现需要登录了

在这里插入图片描述
然后我们就寄了,这里可能是因为Spring版本的问题或者是因为依赖版本的问题
导致输入后台给的密码的时候报错

这个明天在搞了

2022-07-21 01:12:20.158  WARN 18360 --- [nio-3000-exec-3] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt
2022-07-21 01:12:23.771  WARN 18360 --- [nio-3000-exec-8] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt
2022-07-21 01:12:31.217  WARN 18360 --- [nio-3000-exec-3] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt



Gzm1317
22天前

[我的项目地址]
最后的加密没有更上(不是在下载包就是在码代码的路上QAQ)




Gzm1317
27天前

前言

$tag :$模拟 STL 排序

传送门 :
这题10分钟才出货,题目看了好几遍,今天昏头了属于是

思路 :
我们只需要 排序,排序!,之后直接模拟即可

我们需要实时计算需要减的值

然后每次减的时候,及时的踢出已经减为$0$的值

code :

ll n,k;
vector<ll> v;
int i,j;
void solve(){
    cin>>n>>k;
    Fup(i,1,n){
    //for(int i=1;i<=n;i++) 等同于
        int x;cin>>x;
        if(!x)continue;
        v.pb(x);
    }

    sort(all(v),greater<int>());

    int d  = 0 ;
    //计算需要减去的差值
    while(k -- ){
        if(v.size() == 0){
            cout<<0<<endl;
            continue;
        }
        if(v.back() - d !=0){
            cout<<v.back()-d<<endl;
            d+=(v.back()-d);
            //可能有多个相同所以需要while 
            while(v.back() -d == 0)
            v.pop_back();
        }else cout<<0<<endl;
    }

}



Gzm1317
27天前

前言

$tag :$组合数学 dp

传送门 :

题意 :
给定$n$个人,$m$个水果,询问恰好有$k$个人拿到的水果和左边的人不一样的方案数

组合思路 :
我们在$n-1$个人中挑选出$k$个人

显然第一个人有$m$种选法,那么剩下的要么是和第一个人相同要么就是不同

因此总共有$(m-1)^k$种选法,而对应这$k$个人又有$C_{n-1}^k$种

所以总方案数 $C_{n-1}^k*m*(m-1)^k$

code :

ll qmi(ll a,ll b){
    ll res = 1;
    while(b){
        if(b&1) res = res*a%mod;
        a = a*a%mod;
        b>>=1;
    }
    return res;
}
ll f(ll x){
    ll res = 1;
    for(ll i=1;i<=x;i++) res = res*i%mod;
    return res%mod;
}
ll inv(ll x){
    return qmi(x,mod-2);
}
ll getC(ll a,ll b){
    return f(a)*inv(f(a-b)*f(b)%mod)%mod;
}
void solve(){
    cin>>n>>m>>k;
    cout<<(getC(n-1,k)*m%mod)*qmi(m-1,k)%mod<<endl;
}

dp思路 :
我们设状态
$dp[i][j]表示前i位有j个不同的方案数$

那么转移很好想到
$dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(m-1)$

(前面已经凑出来$j$个不同 $dp[i-1][k]$
(前面只凑出来$j-1$个不同,因此当前的选择需要乘上$(m-1)$

code :

ll dp[N][N];
ll n,m,k;
void solve(){
    cin>>n>>m>>k;
    for(int i=1;i<=k;i++) dp[1][i] = 0 ;
    //第一个不算
    for(int i=1;i<=n;i++) dp[i][0]=m;

    for(int i=2;i<=n;i++)
        for(int j=1;j<=k;j++)
        dp[i][j] = (dp[i-1][j]+dp[i-1][j-1]*(m-1)%mod)%mod;

    cout<<dp[n][k]<<endl;
}



Gzm1317
28天前



Gzm1317
30天前

今天写了一堆代码
https://git.acwing.com/Gzm/gzm_kob



活动打卡代码 AcWing 352. 闇の連鎖

Gzm1317
1个月前
// Problem: 闇の連鎖
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/description/354/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// Problem: B. Rising Sand
// Contest: Codeforces - Codeforces Round #803 (Div. 2)
// URL: https://codeforces.com/contest/1698/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <iostream>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <math.h>
#include <set>
#include <stack>
#include <algorithm>
using namespace std;
#define IOS  ios::sync_with_stdio(false);
#define CIT  cin.tie(0);
#define COT  cout.tie(0);

#define ll long long
#define x first
#define y second
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(),x.end()
#define Fup(i,a,b) for(int i=a;i<=b;i++)
#define Fde(i,a,b) for(int i=a;i>=b;i--)
#define cer(a) cerr<<#a<<'='<<(a)<<" @ line "<<__LINE__<<" "<<endl
typedef priority_queue<int,vector<int>,greater<int>>  Pri_m;
typedef pair<int,int> pii;
typedef vector<int> VI;
map<int,int> mp;
const int N = 2e5+10,INF = 0x3f3f3f3f;
const double eps = 1e-5;


struct node{
    int to,val;
};

int depth[N],fa[N][17],q[N];

int h[N],e[N],ne[N],idx;

int n,m;
//加边 写一下 如果vector被卡 这个也忘了 那就寄了

int ans;

int d[N];

void add(int a,int b){
    e[idx] = b , ne[idx] = h[a],h[a] = idx++;
}

//bfs tarjan
void bfs(){
    memset(depth,0x3f,sizeof depth);
    depth[0]=0 , depth[1] = 1;
    int hh = 0 , tt = 0 ;
    q[0] = 1;

    while(hh<=tt){
        int t = q[hh++];
        for(int i = h[t];~i;i=ne[i]){
            int j = e[i];
            if(depth[j] > depth[t] + 1){
                depth[j] = depth[t] + 1;
                q[++tt] = j;
                fa[j][0] = t;
                for(int k = 1;k<=16;k ++ )
                fa[j][k] = fa[fa[j][k-1]][k-1];
            }
        }
    }
}
int lca(int a, int b)
{
    if (depth[a] < depth[b]) swap(a, b);
    for (int k = 16; k >= 0; k -- )
        if (depth[fa[a][k]] >= depth[b])
            a = fa[a][k];
    if (a == b) return a;
    for (int k = 16; k >= 0; k -- )
        if (fa[a][k] != fa[b][k])
        {
            a = fa[a][k];
            b = fa[b][k];
        }
    return fa[a][0];
}

//从每个点开始计算其子树 
int dfs(int u,int father){
    int res = d[u];
    for(int i = h[u];~i;i=ne[i]){
        int j = e[i];
        if(j == father) continue;
        int s = dfs(j,u);

        if(s == 0 ) ans += m;
        else if(s == 1) ans ++ ;

        res += s;
    }
    return res;
}

void solve(){
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i = 1;i < n;i ++ ){
        int  a,b;cin>>a>>b;
        add(a,b);add(b,a);
    }

    bfs();

    for(int i = 1;i<=m; i ++ ){
        int a,b;cin>>a>>b;
        int p = lca(a,b);
        d[a]++,d[b]++,d[p]-=2;
    }

    dfs(1,-1);
    cout<<ans<<endl;
}

int main(){
    //int t;cin>>t;while(t--)
    solve();
    return 0 ;
}




Gzm1317
1个月前

前言

$tag :$ dfs 图的基本知识

思路 :
我们可以发现,一个联通分量中要使得满足环的要求

那么每个典的都需要是2,因此我们只需要统计度数

然后再跑一遍基础课中 深度优先遍历图即可

code :

vector<int> g[N];
int deg[N];

int st[N];
int n,m;

int flag ;

void dfs(int u){
    st[u] = 1;
    for(auto x : g[u]){
        if(!st[x]){
            if(deg[x]!=2)flag = 1;
            dfs(x);
        }
    }
}
void solve(){
    cin>>n>>m;

    for(int i=1;i<=m;i ++ ){
        int a,b;cin>>a>>b;
        g[a].pb(b);
        g[b].pb(a);
        deg[a] ++ ,deg[b]++;
    }

    int res =0  ;

    for(int i = 1;i <= n; i ++ ){
        if(st[i]) continue;
        if(deg[i]!=2) continue;
        flag = 0 ;

        dfs(i);
        if(flag) continue;


        ++res;
    }
    cout<<res<<endl;

}

int main(){
    //int t;cin>>t;while(t--)
    solve();
    return 0 ;
}


活动打卡代码 工程课 Web-1.6. homework_6

Gzm1317
1个月前
1123