我是靠谱客的博主 现实机器猫,这篇文章主要介绍手撕代码ing,现在分享给大家,希望可以做个参考。

桶排序:

引入include

核心代码:

int a[10]= {9,6,3,8,5,2,7,4,1,0};
for(int i=0; i<10; i++)
cout<<a[i]<<" “;
cout<<endl;
sort(a,a+10); #注意这是a+10
for(int i=0; i<10; i++)
cout<<a[i]<<” ";
return 0;

冒泡排序:

思路:如果是升序,相邻的两个数进行比较,比较大的放在后面,比较了n-1次,第一次循环结束后,最大数被排在了最后面,一次进行循环,需要进行n-1次循环,

#include
using namespace std;
int main () {
int n;
int temp;
int a[100];
cin>>n;
for(int i=0;i<n;i++) {
cin>>a[i];
}
for(int i=0;i<n-1;i++) {
for (int j = 1;j<n-i;j++) {
if(a[j-1] > a[j]) {
temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
}
for(int i=0;i<n;i++) {
cout<<a[i];
}
return 0;
}

选择排序(升序):

具体思路:第一次循环,将第一个数与后面的n-1个数进行比较,选出最小的放在第一个位置,;下一轮,从第二个数开始,与剩下的n-2个数进行比较,以此类推;

#include
using namespace std;

void print(int array[],int n) {
for(int i=0;i<n;i++) {
cout<<array[i]<<" ";
}
cout<<endl;
}

int selectsort(int array[],int n) {
int count = 0;//记录交换次数
int temp;
int min_index = 0;//假设最小值所在的位置,默认为0,即第一个元素
for(int i=0;i<n-1;i++) {
//假设当前的元素是第i小的元素,保存当前位置
min_index = i;
for(int j = i+1;j<n;j++) {
cout << “第” << (i + 1) << “趟第” << (j + 1) << “次排序” << endl;
//判断当前的元素是否小于假设的第i小元素
if (array[min_index]>array[j]) {
//重新设置第i小的元素位置
min_index = j;
}
}
//判断当前位置的元素是否等于假设的第i小元素,如果不等于则交换这两个元素
if (min_index != i)
{
temp = array[min_index];
array[min_index] = array[i];
array[i] = temp;
count++;
}
}
return count;
}

int main () {
// 定义排序的数组
int array[] = {1,3,8,5,9,4,10,7,2,6};
// 对数组进行排序
int count = selectsort(array,10);
// 对排序后的数组进行输出
print(array,10);
cout<<count;
return 0;
}

快速排序:

先看这样一个未排序之前的数列 6 1 2 7 9 3 4 5 10 8 ,然后再看一下它的变形:3 1 2 5 4 6 9 7 10 8。

会发现这十个数以6为基准分成了两个阵营:左边都比6小,右边都比6大。这里将6称为基准数,它将扮演重要的角色。

快速排序正是这样一个利用基准数不断分阵营的过程。

#include
using namespace std;
int a[100],n;
void quicksort(int left,int right) {
int i,j,t,temp;
if(left>right)
return;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
temp=a[left]; i=left; j=right; while(i!=j) { while(a[j]>=temp&&j>i) j--; while(a[i]<=temp&&j>i) i++; if(i<j) { t=a[i]; a[i]=a[j]; a[j]=t; } } a[left]=a[i]; a[i]=temp;//交换基数 quicksort(left,i-1); quicksort(i+1,right);

}
int main() {
cout<<“排几个数:”;
cin>>n;
for(int i=0; i<n; i++) {
cin>>a[i];
}
quicksort(0,n-1);
for(int i=0; i<n; i++) {
cout<<a[i]<<" ";
}
}

一、数组扁平化

复制代码
1
2
3
4
5
6
7
8
const bianping = (array) => { return bianping.reduce((result,item) => { return arrar.concat(Array.isArray(item) ? bianping(item):item) }) } let arr = [1,2,3,[22,5]]; console.log(bianping(arr));

二、深拷贝浅拷贝

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function deepClone(target) { // 基本数据类型直接返回 if (typeof target !== 'object') { return target } // 引用数据类型特殊处理 // 判断数组还是对象 const temp = Array.isArray(target) ? [] : {} for (const key in target) { // 递归 temp[key] = deepClone(target[key]) } return temp } const a = { name: 'sunshine_lin', age: 23, hobbies: { sports: '篮球', tv: '雍正王朝' }, works: ['2020', '2021'] } const b = deepClone(a) console.log(b)

三、数组去重

复制代码
1
2
3
4
5
6
7
8
let set = new Set([1,2,5,4,4,4,5,3]); let a = [...set]; console.log(a); for(let item of a){ console.log(item) } console.log(Object.prototype.stringfl.call(a));

四、各类数组方法

filter:一个新的、由通过测试的元素组成的新数组,如果没有数组元素通过测试,则 返回空数组

map:由原数组的每个元素执行回调函数后的结果组成的新数组

foreach: 方法对数组的每个元素执行一次给定的函数。

**concat:**用于合并两个或者多个数组,此方法不会改变现有数组,而是返回一个新数组

**entries:**返回一个新的数组迭代对象,该对象包含数组中每个索引的键值对

复制代码
1
2
3
4
5
6
7
8
9
10
const array1 = ['a', 'b', 'c']; const iterator1 = array1.entries(); console.log(iterator1.next().value); // expected output: Array [0, "a"] console.log(iterator1.next().value); // expected output: Array [1, "b"]

**every:**测试一个数组内的所有元素是否都能通过某个指定函数的测试,返回一个布尔值

**fill:**用一个固定值填充数组中从起始索引到终止索引内的全部元素,不包括终止索引

**find:**返回数组中满足提供等我函数测试的第一个元素的值,否则返回undefined

findIndex:返回数组中满足提供等我函数测试的第一个元素的索引,没有则返回-1

**flat:**按照一个可以指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

**foreach:**对数组的每一个元素执行一次给定的函数

**Array.from():**从一个类似数组或者可迭代对象(类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map))创建一个新的,浅拷贝的数组实例

**includes:**判断一个数组是否包含指定的值,返回的是一个bool类型

shift:从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

unshift:将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组**)**

五、apply()、bind()、call()

call:

call核心:

1.它接受一个参数obj,这个参数就是函数的作用域,这个obj参数是一个Object类型,如果_call()方法没有传递任何参数,则默认执行作用域为window对象,代码实现如下:

复制代码
1
2
3
4
5
6
// 全局添加一个_call方法 Function.prototype._call = function(obj) { // 参数是否存在,如果存在则转为Object类型,否则直接取window对象为默认对象 var _obj = obj ? Object(obj) : window }

2.重要的步骤来了,要让函数的执行作用域为参数obj,那么这个函数必须是obj的一个属性或方法,因此这里为_obj添加一个fn方法,并把这个函数赋给这个方法:

复制代码
1
2
3
4
5
6
7
// 全局添加一个_call方法 Function.prototype._call = function(obj) { // 参数是否存在,如果存在则转为Object类型,否则直接取window对象为默认对象 var _obj = obj ? Object(obj) : window _obj.fn = this }

3.接下来该获取其他函数参数了,因为这里正在实现call方法,我们只好去遍历arguments对象,把这些参数转为真正的数组,并拆分为参数传给函数并执行:

复制代码
1
2
3
4
5
6
7
8
9
var argArr = [] // 遍历参数,因为首项是obj,所以要从次项开始遍历才是参数 for (var i = 1; i < arguments.length; i++) { argArr.push('arguments['+ i + ']') } // 执行obj的fn方法,把arg拆分 eval("_obj.fn(" + argArr + ")") // _obj.fn(...argArr)

也可以用es6的数组方法Array.from()去遍历arguments对象

完整代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 全局添加一个_call方法 Function.prototype._call = function(obj) { // 参数是否存在,如果存在则转为Object类型,否则直接取window对象为默认对象 var _obj = obj ? Object(obj) : window // 把调用_call()方法的那个函数保存在目标对象中 _obj.fn = this // 保存参数的数组 // var argArr = [...arguments].slice(1) var argArr = Array.from(arguments).slice(1) // 遍历参数,因为首项是obj,所以要从次项开始遍历才是参数 /* for (var i = 1; i < arguments.length; i++) { argArr.push('arguments['+ i + ']') } */ // 执行obj的fn方法,把arg拆分 // eval("_obj.fn(" + argArr + ")") _obj.fn(...argArr) // 执行完之后删除这个方法 delete _obj.fn }

apply:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Function.prototype._apply = function(obj, argArr) { // 如果obj不存在则默认window对象 var _obj = obj ? obj : window // 给_obj添加fn方法 _obj.fn = this // 获取第二个数组参数 var arg = [] // 当这个参数数组不存在或者为空时,直接执行函数,否则把数组拆分后传递给函数并执行 if (!argArr || argArr.length == 0) { _obj.fn() } else { for (var i = 0; i < argArr.length; i++) { arg.push('argArr['+ i + ']') } // 执行obj的fn方法,把arg拆分 eval("_obj.fn(" + arg + ")") } // 移除这个方法 delete _obj.fn }

bind():

复制代码
1
2
太難了 孩子放棄了

六、防抖

七、节流

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body> <input id="search" type="text" placeholder="请输入要查询的内容"> <script> var search = document.getElementById('search'); function getUserAction() { console.log('执行查询操作', +new Date()); }; function debounce(func, wait) { var timeout; return (args) => { if (timeout) clearTimeout(timeout) timeout = setTimeout(func, wait); } } const debounceAjax = debounce(getUserAction, 1000) search.addEventListener('keyup', debounceAjax) </script> </body>

八、实现一个New操作符

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
function New(func) { var res{};//因为New创建的是一个对象,所以新建一个空对象 if(func.prototype !== null){ res._proto_ = func.prototype;//设置原型 } //更改this指向 var ret = func.apply(res,Array.prototype.slice.call(arguments,1))//Array.prototype.slice.call(arguments,1);这句话的意思就是说把调用方法的参数截取出来。 if ((typeof ret === "object" || typeof ret === "function") && ret !== null) { return ret; } return res; }

最后

以上就是现实机器猫最近收集整理的关于手撕代码ing的全部内容,更多相关手撕代码ing内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部