我是靠谱客的博主 现实机器猫,最近开发中收集的这篇文章主要介绍手撕代码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;

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]<<" ";
}
}

一、数组扁平化

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));

二、深拷贝浅拷贝

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)


三、数组去重

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:**返回一个新的数组迭代对象,该对象包含数组中每个索引的键值对

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对象,代码实现如下:

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

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

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

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

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对象

完整代码:

// 全局添加一个_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:

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():

太難了 孩子放棄了

六、防抖

七、节流

<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操作符

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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部