diff --git a/typescript/.eslintrc.js b/typescript/.eslintrc.cjs similarity index 100% rename from typescript/.eslintrc.js rename to typescript/.eslintrc.cjs diff --git a/typescript/.prettierrc.js b/typescript/.prettierrc.cjs similarity index 100% rename from typescript/.prettierrc.js rename to typescript/.prettierrc.cjs diff --git a/typescript/nodemon.json b/typescript/nodemon.json index 4edb065..a472a8e 100644 --- a/typescript/nodemon.json +++ b/typescript/nodemon.json @@ -1,9 +1,10 @@ -{ - "watch": ["src"], - "ext": "ts", - "ignore": ["*.test.ts"], - "delay": "0", - "execMap": { - "ts": "ts-node" - } -} +{ + "watch": ["src"], + "ext": "ts,js", + "ignore": ["*.test.ts"], + "delay": "0", + "execMap": { + "ts": "ts-node", + "js": "node --harmony" + } +} diff --git a/typescript/package.json b/typescript/package.json index 4c6a952..7194928 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -3,10 +3,12 @@ "version": "1.0.0", "description": "", "scripts": { - "start": "nodemon src/index.ts", + "dev:ts": "nodemon src/index.ts", + "dev:js": "nodemon src/index.js", "lint": "eslint ./src --fix" }, "author": "", + "type": "module", "license": "ISC", "devDependencies": { "@types/node": "^18.6.5", diff --git a/typescript/readme.md b/typescript/readme.md new file mode 100644 index 0000000..e2cbcb5 --- /dev/null +++ b/typescript/readme.md @@ -0,0 +1,3 @@ +## nodemon + +https://github.com/remy/nodemon/blob/master/doc/sample-nodemon.md diff --git a/typescript/src/index.js b/typescript/src/index.js new file mode 100644 index 0000000..b97bbc9 --- /dev/null +++ b/typescript/src/index.js @@ -0,0 +1,4 @@ +import './nowcoder/examHuawei.js' +import './nowcoder/examTop101.js' +import './nowcoder/quickSort.js' +import './nowcoder/microTask.js' diff --git a/typescript/src/nowcoder/examHuawei.js b/typescript/src/nowcoder/examHuawei.js new file mode 100644 index 0000000..ccaa98e --- /dev/null +++ b/typescript/src/nowcoder/examHuawei.js @@ -0,0 +1,259 @@ +// 华为机试 +// https://www.nowcoder.com/exam/oj/ta?page=1&tpId=37&type=37 + +console.time('time') +function test1() { + const line = 'hello nowcoder' + const tokens = line.split(' ') + console.log(tokens[tokens.length - 1].length) +} + +let text = '' +function test2(line) { + if (!text) { + text = line + } else { + const reg = new RegExp(line, 'gi') + console.log(text.match(reg)?.length ?? 0) + } +} +// test2('ABCabc') +// test2('A') + +let total = 0 +const set = new Set() +function test3(line) { + if (total === 0) { + total = line + } else { + set.add(line) + } +} +// test3(4) +// test3(123) +// test3(2) +// test3(27) +// test3(2) +// test3(1) +// Array.from(set) +// .sort((a, b) => a - b) +// .forEach((s) => console.log(s)) + +function test4() { + let line = '123456789123456789123456789123456789123456789' + // for (let i = 0; i <= parseInt((line.length - 1) / 8); i++) { + // let str = line.slice(i * 8, i * 8 + 8) + // if (str.length < 8) { + // str = str + '0'.repeat(8 - str.length) + // // str = str.padEnd(8, '0') + // } + // console.log(str) + // } + let str = line + '00000000' + for (let i = 8; i < str.length; i += 8) { + console.log(str.substring(i - 8, i)) + } +} +// test4() + +function test5(number) { + console.log(parseInt(number, 16)) + console.log(Number(number)) + console.log(number.toString(10)) +} +// test5('0xAA') + +function test6() { + let num = 180 + const arr = [] + for (let i = 2; i * i <= num; i++) { + while (num % i === 0) { + console.log(num, i) + arr.push(i) + num = num / i + } + } + if (num > 1) { + arr.push(num) + } + console.log(arr.join(' ')) +} +// test6() + +function test7(num) { + console.log(Number(num).toFixed(0)) +} +// test7('5.5') +// test7('5.4') +// test7('2.499') + +const obj8 = {} +function test8(str) { + const strs = str.split(' ') + if (strs[1]) { + const value = obj8[strs[0]] + if (value) { + obj8[strs[0]] = Number(strs[1]) + Number(value) + } else { + obj8[strs[0]] = strs[1] + } + } +} +// test8('4') +// test8('3 4') +// test8('0 1') +// test8('1 2') +// test8('0 2') +// test8('0 2') +// Object.entries(map) +// .sort(([ak], [bk]) => ak - bk) +// .forEach(([k, v]) => console.log(k, v)) + +function test9(str) { + console.log([...new Set([...str].reverse())].join('')) + // console.log([...new Set(str)].reverse().join('')) +} +// test9('9876673') + +function test10(str) { + // const map10 = new Map() + // for (let i = 0; i < str.length; i++) { + // const s = str[i] + // const value = map10.get(s) + // map10.set(s, value) + // } + // console.log(map10.size) + console.log(new Set([...str]).size) +} +// test10('abc') +// test10('aaa') + +function test11(str) { + console.log([...str].reverse().join('')) +} +// test11('1516000') + +function test12(str) { + console.log([...str].reverse().join('')) +} +// test12('abcd') + +function test13(str) { + const strs = str.split(' ') + console.log(strs.reverse().join(' ')) +} +// test13('I am a boy') + +const arr14 = [] +let count14 +function test14(str) { + if (!count14) { + count14 = str + } else { + arr14.push(str) + } +} +// test14('9') +// test14('cap') +// test14('too') +// test14('boot') +// arr14.sort().forEach((a) => console.log(a)) + +function test15(str) { + console.log(parseInt(str, 10).toString(2).match(/1/g).length) +} +// test15('5') + +function shoppingCart() { + let items16 = [] + let n + let m + let id = 1 + function test16(str) { + const strs = str.split(' ') + const q = strs[2] + if (q === undefined) { + n = strs[0] + m = strs[1] + } else { + const v = strs[0] + const p = strs[1] + items16.push([v, p, q, id]) + id++ + } + } + test16('1000 5') + // test16('20 3 5') + // test16('20 3 5') + // test16('10 3 0') + // test16('10 2 0') + // test16('10 1 0') + test16('800 2 0') + test16('400 5 1') + test16('300 5 1') + test16('400 3 0') + test16('500 2 0') + // 分类 + // subItems16.forEach((si) => { + // // console.log(si) + // const index = mainItems16.findIndex((mi) => mi[3] == si[2]) + // mainItems16[index].childs.push(si) + // }) + // 穷举购物车 + function getAllSubsets(arr) { + const subsets = [[]] + for (const item of arr) { + const newSubsets = subsets.map((subset) => { + // console.log(subset, 'subset') + return [...subset, item] + }) + subsets.push(...newSubsets) + } + return subsets + } + items16 = getAllSubsets(items16) + // console.log(subsets) + + // 穷举结果 + let results = [] + items16 = items16.filter((sbs) => { + if (sbs.length == 0) { + return true + } else if (sbs.length == 1) { + if (sbs[0][0] < n) { + return true + } + } + let isParentIn = true + const childs = sbs.filter((sb) => sb[2] != 0) + if (childs.length) { + isParentIn = childs.every((s) => sbs.some((b) => b[3] == s[2])) + } + if (isParentIn) { + return true + } + }) + + items16 = items16.forEach((sbs) => { + let totalPrice = 0 + let satisfaction = 0 + sbs.forEach((item) => { + totalPrice += Number(item[0]) + satisfaction += Number(item[0]) * Number(item[1]) + // console.log(item) + }) + // console.log(sbs) + + if (totalPrice <= n) { + // console.log(totalPrice) + results.push(satisfaction) + } + }) + items16 = undefined + // console.log(results) + results = results.sort((a, b) => b - a) + + console.log(results[0]) +} + +console.timeEnd('time') diff --git a/typescript/src/nowcoder/examTop101.js b/typescript/src/nowcoder/examTop101.js new file mode 100644 index 0000000..cf78d1e --- /dev/null +++ b/typescript/src/nowcoder/examTop101.js @@ -0,0 +1,129 @@ +// 面试必刷TOP101 +// https://www.nowcoder.com/exam/oj?page=1 + +function BM1() { + class ListNode { + constructor(x) { + this.val = x + if (x < 3) { + this.next = new ListNode(x + 1) + } + } + } + + function ReverseList(head) { + // write code here + let pre = null + let cur = head + while (cur) { + // 前插法 + const nextTemp = cur.next + cur.next = pre // 反转当前节点 + pre = cur // 前置节点后移 + cur = nextTemp // 当前节点后移 + } + return pre + } + + console.log(new ListNode(1)) + console.log(ReverseList(new ListNode(1))) +} +// BM1() + +function BM17() { + // 二分查找 + const target = 13 + const arr = [-1, 0, 3, 4, 6, 10, 13, 14] + + const search = function (nums, target) { + // 在区间[left,right]中查找元素,左闭右闭 + let left = 0 + let right = nums.length - 1 + while (left <= right) { + // 计算中间点 + let mid = parseInt(left + (right - left) / 2) + if (target == nums[mid]) { + return mid + // 如果target < nums[mid],表示目标值可能在左半边 + } else if (target < nums[mid]) { + right = mid - 1 + // 如果target > nums[mid],表示目标值可能在右半边 + } else if (target > nums[mid]) { + left = mid + 1 + } + } + // 未找到返回-1 + return -1 + } + + console.log(search(arr, target)) +} +// BM17() + +function BM23() { + // 二叉树的前序遍历 + class TreeNode { + constructor(val) { + this.val = val + this.left = null + this.right = null + } + } + + function preorderTraversal(root) { + const result = [] + + function traverse(node) { + if (node === null) { + return + } + // 访问当前节点的值 + result.push(node.val) + // 递归遍历左子树 + traverse(node.left) + // 递归遍历右子树 + traverse(node.right) + } + + traverse(root) // 从根节点开始遍历 + + return result + } + + // 创建一个二叉树 + const root = new TreeNode(1) + root.left = new TreeNode(2) + root.right = new TreeNode(3) + root.left.left = new TreeNode(4) + root.left.right = new TreeNode(5) + + // 执行前序遍历 + const result = preorderTraversal(root) + console.log(result) // 输出 [1, 2, 4, 5, 3] +} +// BM23() + +function match() { + const str = 'aeiou wolppzxc alwmdf String prototype' + const result = str.match(/a|e|i|o|u/g) + console.log(result, result.length) +} +// match() + +function getMaxDepth() { + const arr = [1, 1, [2, 2], [2, [3, 3, [4, 4], [4, [5, 5]]]]] + const depth = [] + const getDepth = (arr, deep) => { + arr.forEach((a) => { + if (Array.isArray(a)) { + getDepth(a, deep + 1) + } else { + depth.push(deep) + } + }) + } + + getDepth(arr, 1) + console.log(Math.max(...depth)) +} +getMaxDepth() diff --git a/typescript/src/nowcoder/microTask.js b/typescript/src/nowcoder/microTask.js new file mode 100644 index 0000000..311be5b --- /dev/null +++ b/typescript/src/nowcoder/microTask.js @@ -0,0 +1,58 @@ +// 面试题目一 + +function events() { + async function async1() { + console.log('async1 start') // 2 + await async2() + console.log('async1 end') // 7 + } + + async function async2() { + console.log('async2') // 3 + } + + console.log('script start') // 1 + + setTimeout(function () { + console.log('setTimeout0') + }, 0) // 12 + + setTimeout(function () { + console.log('setTimeout2') + }, 300) // 13 + + setImmediate(() => console.log('setImmediate')) // 11 + + process.nextTick(() => console.log('nextTick1')) // 9 + + async1() // 2 + + new Promise(function (resolve) { + console.log('promise1') // 4 + resolve() + console.log('promise2') // 5 + }).then(function () { + console.log('promise3') // 8 + }) + + process.nextTick(() => console.log('nextTick2')) // 10 + + console.log('script end') // 6 +} +// events() + +/** + * script start +async1 start +async2 +promise1 +promise2 +script end +async1 end +promise3 +nextTick1 +nextTick2 +setImmediate +setTimeout0 +setTimeout2 + */ diff --git a/typescript/src/nowcoder/quickSort.js b/typescript/src/nowcoder/quickSort.js new file mode 100644 index 0000000..1d71964 --- /dev/null +++ b/typescript/src/nowcoder/quickSort.js @@ -0,0 +1,54 @@ +function partition(arr, start, end) { + // 以最后一个元素为基准 + const pivotValue = arr[end] + let pivotIndex = start + for (let i = start; i < end; i++) { + if (arr[i] < pivotValue) { + // 交换元素 + ;[arr[i], arr[pivotIndex]] = [arr[pivotIndex], arr[i]] + // 移动到下一个元素 + pivotIndex++ + } + } + + // 把基准值放在中间 + ;[arr[pivotIndex], arr[end]] = [arr[end], arr[pivotIndex]] + return pivotIndex +} + +function quickSortRecursive(arr, start, end) { + // 终止条件 + if (start >= end) { + return + } + + // 返回 pivotIndex + let index = partition(arr, start, end) + + // 将相同的逻辑递归地用于左右子数组 + quickSortRecursive(arr, start, index - 1) + quickSortRecursive(arr, index + 1, end) +} +const array = [7, -2, 4, 7, 1, 3, 6, 5, 3, 0, -4, 2] +// quickSortRecursive(array, 0, array.length - 1) +// console.log(array) + +const myQuickSort = (arr) => { + if (arr.length <= 1) { + return arr + } + const pivotIndex = Math.floor(arr.length / 2) + const pivot = arr.splice(pivotIndex, 1)[0] + const left = [] + const right = [] + + arr.forEach((num) => { + if (num < pivot) { + left.push(num) + } else { + right.push(num) + } + }) + return myQuickSort(left).concat([pivot], myQuickSort(right)) +} +// console.log(myQuickSort(array)) diff --git a/typescript/tsconfig.json b/typescript/tsconfig.json index 8c2935e..dc9a5de 100644 --- a/typescript/tsconfig.json +++ b/typescript/tsconfig.json @@ -1,55 +1,55 @@ -{ - // "extends": "@tsconfig/node16/tsconfig.json", - "compilerOptions": { - /* 基本选项 */ - "target": "ES6", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' - "module": "CommonJS", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015' - "lib": [], // 指定要包含在编译中的库文件 - "allowJs": true, // 允许编译 javascript 文件 - "checkJs": true, // 报告 javascript 文件中的错误 - "jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react' - "declaration": true, // 生成相应的 '.d.ts' 文件 - // "sourceMap": true, // 生成相应的 '.map' 文件 - // "outFile": "./", // 将输出文件合并为一个文件 - "outDir": "./build", // 指定输出目录 - "rootDir": "./", // 用来控制输出目录结构 --outDir. - "removeComments": true, // 删除编译后的所有的注释 - "noEmit": false, // 不生成输出文件 - "importHelpers": false, // 从 tslib 导入辅助工具函数 - "isolatedModules": false, // 将每个文件作为单独的模块 (与 'ts.transpileModule' 类似). - - /* 严格的类型检查选项 */ - "strict": true, // 启用所有严格类型检查选项 - "noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错 - "strictNullChecks": true, // 启用严格的 null 检查 - "noImplicitThis": true, // 当 this 表达式值为 any 类型的时候,生成一个错误 - "alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict' - - /* 额外的检查 */ - "noUnusedLocals": false, // 有未使用的变量时,抛出错误 - "noUnusedParameters": false, // 有未使用的参数时,抛出错误 - "noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误 - "noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿) - - /* 模块解析选项 */ - "moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) - "baseUrl": "./", // 用于解析非相对模块名称的基目录 - "paths": {}, // 模块名到基于 baseUrl 的路径映射的列表 - "rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容 - // "typeRoots": [], // 包含类型声明的文件列表 - // "types": [], // 需要包含的类型声明文件名列表 - "allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。 - - /* Source Map Options */ - // "sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置 - // "mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置 - // "inlineSourceMap": true, // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件 - // "inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性 - - /* 其他选项 */ - "experimentalDecorators": true, // 启用装饰器 - "emitDecoratorMetadata": true // 为装饰器提供元数据的支持 - }, - "include": ["./src"], - "exclude": ["./node_modules"] -} +{ + // "extends": "@tsconfig/node16/tsconfig.json", + "compilerOptions": { + /* 基本选项 */ + "target": "ES6", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' + "module": "CommonJS", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "lib": [], // 指定要包含在编译中的库文件 + "allowJs": true, // 允许编译 javascript 文件 + "checkJs": true, // 报告 javascript 文件中的错误 + "jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react' + "declaration": true, // 生成相应的 '.d.ts' 文件 + // "sourceMap": true, // 生成相应的 '.map' 文件 + // "outFile": "./", // 将输出文件合并为一个文件 + "outDir": "./build", // 指定输出目录 + "rootDir": "./", // 用来控制输出目录结构 --outDir. + "removeComments": true, // 删除编译后的所有的注释 + "noEmit": false, // 不生成输出文件 + "importHelpers": false, // 从 tslib 导入辅助工具函数 + "isolatedModules": false, // 将每个文件作为单独的模块 (与 'ts.transpileModule' 类似). + + /* 严格的类型检查选项 */ + "strict": true, // 启用所有严格类型检查选项 + "noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错 + "strictNullChecks": true, // 启用严格的 null 检查 + "noImplicitThis": true, // 当 this 表达式值为 any 类型的时候,生成一个错误 + "alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict' + + /* 额外的检查 */ + "noUnusedLocals": false, // 有未使用的变量时,抛出错误 + "noUnusedParameters": false, // 有未使用的参数时,抛出错误 + "noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误 + "noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿) + + /* 模块解析选项 */ + "moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) + "baseUrl": "./", // 用于解析非相对模块名称的基目录 + "paths": {}, // 模块名到基于 baseUrl 的路径映射的列表 + "rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容 + // "typeRoots": [], // 包含类型声明的文件列表 + // "types": [], // 需要包含的类型声明文件名列表 + "allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。 + + /* Source Map Options */ + // "sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置 + // "mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置 + // "inlineSourceMap": true, // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件 + // "inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性 + + /* 其他选项 */ + "experimentalDecorators": true, // 启用装饰器 + "emitDecoratorMetadata": true // 为装饰器提供元数据的支持 + }, + "include": ["./src/**/*.ts"], + "exclude": ["./node_modules", "**/*.js"] +}