Leetcode 26-30题

删除有序数组中的重复项

给定一个有序数组,要求原地删除重复出现的元素,返回删除后的数组的长度。

这里的原地删除其实可以这样表示,用双指针从前往后扫一遍,遇到新的没出现过的元素就放到前面去,就可以实现删除后的数组前面都是不重复的元素。类似如下过程:

1 1 2 3 41 1 2
1 2 21 2 1 3
1 2 2 3
1 2 3 3
int removeDuplicates(vector<int>& nums) {int k = 1;  // 第一个元素不用判断for(int i = 1; i < nums.size(); i ++) {if(i && nums[i] != nums[i - 1]) {nums[k] = nums[i];k ++;}}return k;
}

移除元素

给定数组和值val,原地删除所有数值等于val的元素,返回移除后数组的新长度。

和上一题的思想一样。

int removeElement(vector<int>& nums, int val) {int k = 0;for(int i = 0; i < nums.size(); i ++) {if(nums[i] != val) {nums[k] = nums[i];k ++;}}return k;
}

找出字符串中第一个匹配项的下标

给定字符串S,和模式串P,求P在S中所有出现的位置的起始下标

暴力做法:

//S长度为n,P长度为m
for (int i = 1; i <= n; i ++ )
{//寻找原串bool flag = true;for (int j = 1; j <= m; j ++ ){if (s[i + j - 1] != p[j]){flag=false;break;}}
}

利用字符串的特殊信息来减少暴力枚举的次数

当我们匹配了一段失败后,会将模式串向后移动以希望能够继续匹配上

那么就存在第二次开始匹配能成功的一段字符串的前缀等于上一次匹配能成功的一段字符串的后缀

对于每一个点预处理出来一段后缀,要最长的一段后缀和前缀相等

字符串的某一段前后缀相等

n e x t next next记录的就是当前作为后缀末位的 j j j对应的前缀末位的位置

n e x t [ i ] = j next[i] = j next[i]=j

p [ 1 , j ] = p [ i − j + 1 , i ] p[1,j] = p[i - j + 1, i] p[1,j]=p[ij+1,i]

S = "abababc"
P = "abababab"12345678
// 长度为i的前缀的border
//P的next数组
ne[1] = 0;	//a
ne[2] = 0;	//ab
ne[3] = 1;	//aba
ne[4] = 2;	//abab
ne[5] = 3;	//ababa
ne[6] = 4;	//ababab
ne[7] = 5;	//abababa
ne[8] = 6;	//abababab

KMP算法模板:

O ( n ) O(n) O(n)

// s[]是长文本,p[]是模式串,n是s的长度,m是p的长度
//在某个头文件里面有next,所以一般用ne作为数组名
int n, m;
string p, s;
int ne[N];cin >> n >> p >> m >> s;
p = " " + p, s = " " + s;//求模式串的Next数组:
for (int i = 2, j = 0; i <= n; i ++ )
{while (j && p[i] != p[j + 1]) j = ne[j];// 对于前一个border,我们往后延长一位,如果p[i] == p[j + 1],就可以得到长度+1的border// 如果不行,就去前缀的前缀判断if (p[i] == p[j + 1]) j ++ ;ne[i] = j;
}// 匹配
for (int i = 1, j = 0; i <= m; i ++ )
{while (j && s[i] != p[j + 1]) j = ne[j];if (s[i] == p[j + 1]) j ++ ;if (j == n){// 匹配成功,输出匹配位置下标(此处从0开始计数,如果要从1开始就是i - n + 1)printf("%d ", i - n);j = ne[j];}
}

全新的理解方式:

前置知识

字符串匹配问题中,给出两个字符串 text 和 pattern (本题中 text 为 S, pattern 为 P),需要判断 pattern 是否是 text 的子串。一般把 text 称为文本串,pattern 称为模式串。暴力的解法为:
枚举文本串 text 的起始位置 i ,然后从该位开始逐位与模式串 pattern 进行匹配。如果匹配过程中每一位都相同,则匹配成功;否则,只要出现某位不同,就让文本串 text 的起始位置变为 i + 1,并从头开始模式串 pattern 的匹配。假设 m 为文本串的长度,n 为模式串的长度。时间复杂度为 O(nm)。显然,当 n 和 m 都达到 1 0 5 10^5 105 级别时无法承受。

next直观理解

假设有一个字符串 s (下标从 0 开始),那么它以 i 号位作为结尾的子串就是 s[0…i]。对该子串来说,长度为 k + 1 的前缀与后缀分别是 s[0…k] 与 s[i-k…i]。我们构造一个 int 型数组(叫啥无所谓,就叫它 next吧)。其中,next[i] 表示使字串 s[0…i] 中前缀 s[0…k] 等于后缀 s[i-k…i] 的最大的 k。(注意相等的前缀、后缀在原字串中不能是 s[0…i] 本身。这点很重要,在后面感性分析时会用到);如果找不到相等的前后缀,就令 next[i] = -1。显然,next[i] 就是所求最长相等前后缀中前缀的最后一位的下标。

第一种方法直接画线画出子串 s[0…i] 的最长相等前后缀:

在这里插入图片描述

第二种方法在上部给出后缀,下部给出前缀,再将相等的最长前后缀框起来。

在这里插入图片描述

next[i] 就是使子串 s[0…i] 有最长相等前后缀的前缀的最后一位的下标。(这里是从0开始的下标)

我们假设已经求出了 next[0] ~ next[i-1],用它们来推算出 next[i]

还是用我们刚刚感性认识的 s = “abababc” 作为例子。假设已经有了 next[0] = -1、next[1] = -1、next[2] = 0、next[3] = 1,现在来求解 next[4]。如下图所示,当已经得到 next[3] = 1 时,最长相等前后缀为 “ab”,之后计算 next[4] 时,由于 s[4] == s[next[3] + 1] (这里的为什么要用 next[3]?想想至尊概念),因此可以把最长相等前后缀 “ab” 扩展为 “aba”,因此 next[4] = next[3] + 1,并令 j 指向 next[4]。

在这里插入图片描述

接着在此基础上求解 next[5]。如下图所示,当已经得到 next[4] = 2 时,最长相等前后缀为 “aba”,之后计算 next[5] 时,由于 s[5] != s[next[4] + 1],因此不能扩展当前相等前后缀,即不能直接通过 next[4] + 1 的方法得到 next[5]。既然相等前后缀没办法达到那么长,那不妨缩短一点!此时希望找到找到一个 j,使得 s[5] == s[j + 1] 成立,同时使得图中的波浪线 ~,也就是 s[0…j] 是 s[0…2] = “aba” 的后缀,而 s[0…j] 是 s[0…2] 的前缀是显然的。同时为了找到相等前后缀尽可能长,找到这个 j 应尽可能大。

在这里插入图片描述

实际上我们上图要求解的 ~ 部分,即 s[0…j] 既是 s[0…2] = “aba” 的前缀,又是 s[0…2] = “aba” 的后缀,同时又希望其长度尽可能长,那么 s[0…j] 就是 s[0…2] 的最长相等前后缀。也就是说,只需要令 j = next[2],然后再判断 s[5] == s[j + 1] 是否成立:如果成立,说明 s[0…j + 1] 是 s[0…5] 的最长相等前后缀,令 next[5] = j + 1 即可;如果不成立,就不断让 j = next[j],直到 j 回到了 -1,或是途中 s[5] == s[j + 1] 成立。

在这里插入图片描述

如上图所示,j 从 2 回退到 next[2] = 0,发现 s[5] == s[j + 1] 不成立,就继续让 j 从 0 回退到 next[0] = -1;由于 j 已经回退到了 -1,因此不再继续回退。这时发现 s[i] == s[j + 1] 成立,说明 s[0…j + 1] 是 s[0…5] 的最长相等前后缀,于是令 next[5] = j + 1 = -1 + 1 = 0,并令 j 指向 next[5]。

下面总结 next 数组的求解过程,并给出代码:

  1. 初始化 next 数组,令 j = next[0] = -1。
  2. 让 i 在 1 ~ len - 1范围内遍历,对每个 i ,执行 3、4,以求解 next[i]。
  3. 直到 j 回退为 -1,或是 s[i] == s[j + 1] 成立,否则不断令 j = next[j]。
  4. 如果 s[i] == s[j + 1],则 next[i] = j + 1;否则 next[i] = j。

在此基础上我们进入 kmp,有了上面求 next 数组的基础,kmp 算法就是在照葫芦画瓢,给定一个文本串 text 和一个模式串 pattern,然后判断模式串 pattern 是否是文本串 text 的子串。
以 text = “abababaabc”、pattern = “ababaab” 为例。令 i 指向 text 的当前欲比较位,令 j 指向 pattern 中当前已被匹配的最后位,这样只要 text[i] == pattern[j + 1] 成立,就说明 pattern[j + 1] 也被成功匹配,此时让 i、j 加 1 继续比较,直到 j 达到 m - 1(m 为 pattern 长度) 时说明 pattern 是 text 的子串。在这个例子中,i 指向 text[4]、j 指向 pattern[3],表明 pattern[0…3] 已经全部匹配成功了,此时发现 text[i] == pattern[j + 1] 成立,这说明 pattern[4] 成功匹配,于是令 i、j 加 1。

在这里插入图片描述

接着继续匹配,此时 i 指向 text[5]、j 指向 pattern[4],表明 pattern[0…4] 已经全部匹配成功。于是试着判断 text[i] == pattern[j + 1] 是否成立:如果成立,那么就有 pattern[0…5] 被成功匹配,可以令 i、j 加 1 以继续匹配下一位。但此处 text[5] != pattern[4 + 1],匹配失败。那么我们这里该怎么做?放弃之前 pattern[0…4] 的成功匹配成果,让 j 回退到 -1 开始重新匹配吗?那是暴力解的方法,我们来看一下 kmp 的处理。

为了不让 j 直接回退到 -1,应寻求回退到一个离当前的 j (此时 j 为 4)最近的 j’,使得 text[i] == pattern[j’ + 1] 能够成立,并且 pattern[0…j’] 仍然与 text 的相应位置处于匹配状态,即 pattern[0…j’] 是 pattern[0…j] 的后缀。这很容易令人想到之前的求 next 数组时碰到的类似问题。答案是 pattern[0…j’] 是 pattern[0…j] 的最长相等前后缀。也就是说,只需要不断令 j = next[j],直到 j 回退到 -1 或者是 text[i] == pattern[j + 1] 成立,然后继续匹配即可。next 数组的含义就是当 j + 1 位失配时,j 应该回退到的位置。对于刚刚的例子,当 text[5] 与 pattern[4 + 1] 失配时,令 j = next[4] = 2,然后我们会发现 text[i] == pattern[j + 1] 能够成立,因此就让它继续匹配,直到 j == 6 也匹配成功,这就意味着 pattern 是 text 的子串。

kmpxiugai1.jpg

kmp 算法的一般思路如下:

  1. 初始化 j = -1,表示 pattern 当前已被匹配的最后位。
  2. 让 i 遍历文本串 text,对每个 i,执行 3、4来试图匹配 text[i] 和 pattern[j + 1]。
  3. 直到 j 回退到 -1 或者是 text[i] == pattern[j + 1],否则不断令 j = next[j]。
  4. 如果 text[i] == pattern[j + 1],则令 j ++。如果 j 达到 pattern_len - 1,说明 pattern 是 text 的子串。

我们观察上面的分析,能否发现:求解 next 数组的过程其实就是模式串 pattern 进行自我匹配的过程。

考虑如何统计 pattern 在 text 中出现的起始下标:
当 j = m - 1 时表示 pattern 完全匹配,此时可以输出 i - j (text 的结束位置减去 pattern 的长度就是 pattern 在 text 中出现的下标)。但问题在于:之后应该从 pattern 的哪个位置开始进行下一次匹配? 由于 pattern 在 text 的多次出现可能是重叠的,因此不能什么都不做就让 i 加 1继续进行比较,而是必须先让 j 回退一段距离。此时 next[j] 代表着整个 pattern 的最长相等前后缀,从这个位置开始让 j 最大,即让已经匹配的部分最长,这样能保证既不漏解,又使下一次匹配省去许多无意义的比较。

综上,这题代码如下:

int strStr(string haystack, string needle) {// 文本串为haystack,模式串为needleint n = needle.size(), m = haystack.size();haystack = " " + haystack, needle = " " + needle;vector<int> ne(n + 10);for (int i = 2, j = 0; i <= n; i ++ ){while (j && needle[i] != needle[j + 1]) j = ne[j];if (needle[i] == needle[j + 1]) j ++ ;ne[i] = j;}for (int i = 1, j = 0; i <= m; i ++ ){while (j && haystack[i] != needle[j + 1]) j = ne[j];if (haystack[i] == needle[j + 1]) j ++ ;if (j == n){return i - n;j = ne[j];}}return -1;
}

两数相除

给定两个整数,被除数dividend,除数divisor,在不使用乘法、除法、整除运算的条件下实现两数整除。

只能存储32位有符号整数,若除法结果溢出,则返回 2 31 − 1 2^{31}-1 2311

首先根据除数和被除数来判断结果符号,然后将除法转换到负数域来做,就能有效避免爆int的情况。

很显然的暴力做法就是将除法转化为减法,将被除数一直减到小于除数为止,并记录减的次数,但这样一定会超时。

因此可以采用增加步长的方式,每次将步长扩大两倍,即 p p p 2 p 2p 2p 2 2 p 2^2p 22p,…, 2 k p < d i v i d e n d 2^kp<dividend 2kp<dividend

然后倒序遍历,如果dividend大于当前项,就用dividend减去这一项,累积答案。

2 0 × 3 = 3 , 2 1 × 3 = 6 , 2 2 × 3 = 12 , 2 3 × 3 = 24 , 2 4 × 3 = 48 , 2 5 × 3 = 96 2^0\times3=3,2^1\times3=6,2^2\times3=12,2^3\times3=24,2^4\times3=48,2^5\times3=96 20×3=3,21×3=6,22×3=12,23×3=24,24×3=48,25×3=96

100 − 96 = 4 100-96=4 10096=4,答案累积 2 5 2^5 25 4 − 3 = 1 4-3=1 43=1,答案累积 2 5 + 2 = 33 2^5+2=33 25+2=33

转换到负数域之后, ( − 100 ) − ( − 96 ) = − 4 (-100)-(-96)=-4 (100)(96)=4,答案累积 − 2 5 -2^5 25

int divide(int dividend, int divisor) {// 判断符号并转换到负数域bool flag = (dividend < 0) ^ (divisor < 0);if(dividend > 0)    dividend = -dividend;if(divisor > 0) divisor = -divisor;// 计算divisor倍数vector<int> vt;int t = divisor;while(t >= dividend) {vt.push_back(t);// 判断越界情况if(t < INT_MIN - t || t < dividend - t) break;t += t;}// 倒序相加int ans = 0;for(int i = vt.size() - 1; i >= 0; i --) {if(dividend <= vt[i]) {dividend -= vt[i];ans -= pow(2, i);}}// 判断越界及符号情况if(!flag) {if(ans == INT_MIN)  return INT_MAX;ans *= -1;}return ans;
}

串联所有单词的子串

给定字符串s和一个字符串数组words,字符串数组中的字符串长度相同。

s中的串联子串是指一个包含words中所有字符串以任意顺序排列连接起来的子串。

返回所有串联子串在s中的开始索引。

因为每个单词的长度相同,因此可以根据每次枚举的起始位置来将其划分为不同的组。

abcdefghijkl
若单词长度为3
划分1:abc def ghi jkl
划分2:bcd efg hij
划分3:cde fgh ijk

这样子划分之后,对于每个划分都可以转化为这样的滑动窗口问题:

将长度为m的组合看作一个个字母,在S中找一个子串,使得这个子串不重不漏的包含word中的所有字母。

首先枚举所有的划分起点,然后设立ij两个指针,用一个哈希表记录当前窗口内每个单词出现的次数,并记录满足条件的单词个数num

每次读入一个单词,如果不在字典中,那么ij这一段内不符合要求,将i移动到j位置。

如果在字典中并且之前没出现过,则更新哈希表以及num。如果在字典中,但之前出现过,则需要右移i指针直到只出现一次。

如果找到答案则更新答案序列,并继续右移i

vector<int> findSubstring(string s, vector<string>& words) {unordered_map<string, int> hash;vector<int> res;int n = s.size(), m = words.size(), len = words[0].size();if(n < m * len) return res;     // 如果字符串小于字典长度则没有匹配// 这里会有特使情况,比如字典里的字符串可能不止出现一次,这就需要另外记录字典里每个单词出现次数for(auto p : words) hash[p] ++; for(int k = 0; k < len; k ++) {     // 划分组合,一共有len组,对每组进行双指针int num = 0;    // 满足条件的单词个数unordered_map<string, int> ump;    // 存储窗口中的满足条件的单词数量for(int i = k, j = k; j <= n - len; ) {     // 双指针string str = s.substr(j, len);if(hash.find(str) == hash.end()) {      // 若字典没有这个单词j = j + len;i = j;ump.clear();num = 0;                // 那么[i,j]都不符合要求}else {// 若字典中有这个单词ump[str] ++;// 若满足数量条件if(ump[str] == hash[str])    num ++;else if(ump[str] > hash[str]) {     // 如果多了就要右移iwhile(i < j && ump[str] > hash[str]) {string st = s.substr(i, len);ump[st] --;         // 如果这个单词原来是满足要求的现在不满足要求了if(ump[st] == hash[st] - 1)   num --;i += len;}}if(num == hash.size()) {      // 满足要求res.push_back(i);// 将i加入答案后后移string st = s.substr(i, len);ump[st] --;num --;i = i + len;}j = j + len;}}}return res;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/700867.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux线程同步(2)死锁与互斥锁

死锁&#xff08;Deadlock&#xff09;是指两个或两个以上的进程&#xff08;或线程&#xff09;在执行过程中&#xff0c;由于竞争资源或者由于彼此通信而造成的一种阻塞的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。此时称系统处于死锁状态或系统产生了…

定频空调与变频空调的区别

变频空调是通过变频器来改变压缩机运转电压以及频率&#xff0c;从而改变压缩机转速的新型空调&#xff0c;那么他和定频空调有哪些区别呢&#xff1f; 一、控制启停的方式不同 定频空调控制方式为&#xff1a;当T环 < T设 - 2℃&#xff0c;压缩机停机。 当 T环 > T…

Java实现就医保险管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

【前端素材】推荐优质后台管理系统Qovex平台模板(附源码)

一、需求分析 1、定义 后台管理系统是一种用于管理和监控网站、应用程序或系统的在线工具。它通常是通过网页界面进行访问和操作&#xff0c;用于管理网站内容、用户权限、数据分析等。后台管理系统是网站或应用程序的控制中心&#xff0c;管理员可以通过后台系统进行各种管理…

构造函数,原型,实例,类的关系整理

视频来源js原型链、构造函数和类_哔哩哔哩_bilibili 如视频所说&#xff0c;构造函数的prototype指向原型&#xff0c;实例化的对象的__proto__指向原型&#xff0c;原型通过constructor指向构造函数&#xff0c;正如class里面的constructor方法就相当于Person构造函数一样&am…

基于PID-bang-bang控制算法的卫星姿态控制matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于PID-bang-bang控制算法的卫星姿态控制。仿真输出控制器的控制收敛曲线&#xff0c;卫星姿态调整过程的动画。 2.系统仿真结果 3.核心程序与模型 版本&#xff1a;MATLAB…

连接SFTP服务器报错host key for has changed and you have requested strict checking

背景&#xff1a;今天连接SFTP的时候&#xff0c;报错如下&#xff0c;记录一下 报错如下 WARNING: REMOTE HOST IDENTIFICATION HSS CHANGED!cccececccccceeteeacaaeapepeppeeecpeepeeecepeeeaeeeeeceeeeeeIT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!Someone co…

LeetCode每日一题——2583. Kth Largest Sum in a Binary Tree

文章目录 一、题目二、题解 一、题目 You are given the root of a binary tree and a positive integer k. The level sum in the tree is the sum of the values of the nodes that are on the same level. Return the kth largest level sum in the tree (not necessaril…

前后端联调可能出现的问题

调不到后端数据 前后端传参方式不一样 --- formdata 主要接收文件 或者有文件和数据 --- json 纯数据

智能成绩表(C语言)

题目来自于博主算法大师的专栏&#xff1a;最新华为OD机试C卷AB卷OJ&#xff08;CJavaJSPy&#xff09; https://blog.csdn.net/banxia_frontend/category_12225173.html 题目描述 小明来到某学校当老师&#xff0c;需要将学生按考试总分或单科分数进行排名&#xff0c;你能帮…

springboot+vue项目部署配置开机自启动

1.前端部属 下载nginx解压&#xff0c;在nginx\conf下找到nginx.conf 添加如下代码 server {listen 8081;server_name localhost;charset utf-8;location / {root F:/1ceshi/dist; #前端打包路径try_files $uri $uri/ /index.html;index index.html index.htm;}l…

本地创建Git仓库

在 Windows 下&#xff0c;可以通过以下步骤在本地创建一个 并模拟远程Git 仓库。 1、在命令行中打开模拟远程Git 仓库目标文件夹&#xff1a; 打开命令提示符或 PowerShell。例如&#xff1a; 创建裸仓库&#xff08;模拟远程仓库&#xff09;&#xff1a;创建一个裸仓库&am…

Redis进阶篇

Redis线程模型 redis是基于内存运行的高性能k-v数据库&#xff0c;6.x之前是单线程, 对外提供的键值存储服务的主要流程 是单线程&#xff0c;也就是网络 IO 和数据读写是由单个线程来完成&#xff0c;6.x之后引入多线程而键值对读写命 令仍然是单线程处理的&#xff0c;所以 …

【PX4SimulinkGazebo联合仿真】在Simulink中使用ROS2控制无人机进入Offboard模式起飞悬停并在Gazebo中可视化

在Simulink中使用ROS2控制无人机进入Offboard模式起飞悬停并在Gazebo中可视化 系统架构Matlab官方例程Control a Simulated UAV Using ROS 2 and PX4 Bridge运行所需的环境配置PX4&Simulink&Gazebo联合仿真实现方法建立Simulink模型并完成基本配置整体框架各子系统实现…

Java爬虫使用JSoup获取静态资源图片

import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.FileOutputStream;/*** 获取静态图片*/public class ImageDownloader {public static void main…

一分钟 由浅入深 学会Navigation

目录 1.官网正式概念 1.1 初认知 2.导入依赖 2.1 使用navigation 2.2 safe Args插件-> 传递数据时用 3.使用Navigation 3.1 搭建初始框架 3.2 确定action箭头的属性 3.3 为Activity添加NavHostFragment控件 3.4 NavController 管理应用导航的对象 3.5 数据传递(单…

Linux——基础IO

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、C语言IO1、写文件2、读文件3、stdin & stdout & stderr 二、系统文件I/O1、写文件…

常用显示屏学习——LCD12864(含高级驱动程序)

LCD12864液晶显示屏 屏幕介绍 ① 可显示四行字符&#xff0c;每行可显示8个汉字或者16个数字和字母&#xff1b; ②可串行通信和并行通信&#xff1b; ③ 串口接口管脚信号 通信方法 &#xff08;一&#xff09;八位并行通信方法 &#xff08;二&#xff09;串行通信方法 用…

基于springboot接口的编写

目录 1、模糊分页查询 2、批量删除 3、新增 4、编辑 此接口非彼接口。此接口是MVC的设计模式中的Controller层&#xff0c;一般我们会叫Controller层里的方法为接口。他们是负责接收前端或者其它服务的传来的请求&#xff0c;并对请求进行相应的处理&#xff0c;最终再将处…

工具方法合集-utils.js

通用 import get from lodash.get import cloneDeep from lodash.clonedeep // 深度clone export function deepClone(obj) {return obj ? cloneDeep(obj) : obj } export function lodashGet(obj, key, defaultValue ) {//这个 defaultValue 不能给默认 值 会报错&#xf…