题目
数组去重:以数组去重为例提升我们平时编程的素养,leetcode的题目也是为了让我们写成干净简洁的代码。
代码规范
模块化(包) 代码要写的模块化
在编程中,模块化是指将代码按照功能进行划分,将不同的功能放到不同的模块中去。这样做的好处是提高了代码的可读性、可维护性和复用性,方便团队协作和项目的扩展。
下面是一些关于模块化设计的良好编程素养要求:
- 一个文件一个类:每个文件应该只包含一个类的定义,这样可以使代码更加清晰和易于理解。同时,文件名应该与类名保持一致,便于快速定位。
- 一个文件一些功能函数:如果某个文件中不只包含一个类,还包含一些功能函数,那么这些功能函数应该与类相关,并且互相之间有一定的联系。这样可以提高代码的内聚性,便于维护和测试。
- 一个函数只完成一个功能:函数应该尽量保持单一职责原则,即一个函数只完成一个具体的功能。如果某个功能比较复杂,应该将其拆分成多个子函数,每个子函数负责完成其中的一部分功能。这样可以提高代码的可读性和可维护性。
- 使用模块化机制:在LeetCode中,我们使用了Node.js的CommonJS模块化机制。通过使用
module.exports
将需要输出的对象进行导出,然后在其他文件中使用require
来引入这些对象。这样可以实现代码的模块化,方便代码的组织和管理。 - 缓存数组的长度:在循环中,如果多次使用数组的长度,可以将其缓存起来,避免重复计算。这样可以提高代码的执行效率。
算法思想
暴力破解
js
function uniq(arr){
var res = []
// 暴力破解法 时间复杂度O(n*2)
// 两重for循环,外层循环arr,内层循环res
// arr的当前项,如果不在res中,则加入res
//否则跳过
// arr.length 对象在堆内存里 读取属性 循环多少次就要读多少次
// 用一个变量缓存 性能优化
for(var i = 0,arrLen = arr.length;i<arrLen;i++){
for(var j = 0,resLen = res.length;j<resLen;j++){
if(arr[i]===res[j]){ //恒等 三个会检查数据类型
break;
}
}
if(j == resLen){
res.push(arr[i])
}
}
return res
}
暴力破解虽然能够解决问题,但执行速度较慢。应该尽量避免使用暴力法,而是考虑使用更高效的算法。常见的优化思路有将O(n^2)的算法优化为O(nlogn)的算法,或者进一步优化为O(n)的算法。
数组方法:
使用indexOf
去重:indexOf
方法不仅可以判断元素是否存在,还可以用于去重。通过判断当前项的indexOf
在新数组中是否存在,从而进行去重操作。这样可以使代码更加优雅和简洁。
使用数组方法去除一层循环:在处理数组时,有一些方法可以帮助我们去除一层循环,简化代码逻辑。例如,可以使用arr.indexOf(1) >= 0
来判断数组中是否存在某个元素,从而避免使用循环进行查找。
js
function uniq(arr){
var res = []
for(var i = 0,len = arr.length;i<len;i++){
var current = arr[i]; //变量名的意义
// 数组从0开始是因为数组是连续的存储空间 arr[0]起始位置,0+i*item = i的位置
if(res.indexOf(current) === -1){ //查看数组下标 >=0 就存在
res.push(current)
}
}
return res
}
判断为false的条件:
在判断一个变量是否为false时,需要注意以下几种情况:0、''、false、undefined、null和NaN。可以通过逻辑非运算符!
来进行判断。
先排序再比较:
在某些情况下,如果需要对数组进行比较或者去重操作,可以先对数组进行排序,然后通过比较当前项是否和前一项相同来进行判断。这样可以简化代码逻辑,并提高执行效率。 利用sort()
方法先把数组排序,记得要使用concat()
方法,不然会改变原数组。
js
function uniq(arr){
var res = []
//先排序
var sortedArr = arr.concat().sort();
var seen;//前一项
for(var i = 0,len = arr.length;i< len;i++){
// 第一个元素或者
if(!i || seen !== sortedArr[i]){
res.push(sortedArr[i])
}
seen = sortedArr[i]
}
return res;
}
最后优化
js
// // 适用于所有场景
function uniq(arr,isSorted){
var res = []
var seen
for(var i = 0,len = arr.length;i< len;i++){
var val = arr[i]; //当前值
if(isSorted){
if(!i || seen !== val){
res.push(val)
}
seen = val
}else if(res.indexOf(val)=== -1){
res.push(val)
}
}
return res
}
模块化机制
1.js
function uniq(arr,isSorted){
var res = []
var seen
for(var i = 0,len = arr.length;i< len;i++){
var val = arr[i]; //当前值
if(isSorted){
if(!i || seen !== val){
res.push(val)
}
seen = val
}else if(res.indexOf(val)=== -1){
res.push(val)
}
}
return res
}
console.log(uniq(array,true));
// module 模块,当前模块是一个uniq模块
// export向外输出
//输出
module.exports = uniq
在下面这串代码可以通过module.exports = uniq
和const uniq = require('./1.js')
实现引入uniq方法
2.js
// 引用uniq方法
const uniq = require('./1.js') //引入1.js
// var result = uniq([1,1,'1','1'])
// console.log(result);
console.log(uniq([1,2,1,"1"]))
console.log(uniq([1, 1, "1", 2], true))
通过使用module.exports
将需要输出的对象进行导出,在其他文件中使用require
来引入这些对象。这样就实现了代码的模块化设计。
总结
本文详细介绍了如何按照良好的编程素养要求进行模块化设计。通过将代码按照功能进行划分,并使用适当的模块化机制,可以提高代码的可读性、可维护性和复用性。同时,还介绍了一些优化的算法思想和常用的数组操作方法。通过遵循这些良好编程素养要求,可以写出高质量的代码。
希望本文对你有所帮助,谢谢阅读!