Skip to content

add:自动拉取题解&自动生成json #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

# production
/build
/spider

# misc
.DS_Store
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
|---App.js 主逻辑都在这里
```

## 构建


## 构建
- npm run auto 自动生成问题解答json
- npm run build
- 然后将 build 文件夹的内容添加到扩展中即可,具体方式见上面的`功能介绍`。

Expand Down
14,644 changes: 14,644 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"auto": "node scripts/curl-leetcode.js && node scripts/generate-leetcode.js"

},
"eslintConfig": {
"extends": "react-app"
Expand All @@ -31,5 +33,10 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"cheerio": "^1.0.0-rc.3",
"iconv-lite": "^0.5.1",
"log4js": "^6.3.0"
}
}
66 changes: 66 additions & 0 deletions scripts/LeetCodeProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@


const request = require('request')
const Iconv = require('iconv-lite')
const cheerio = require('cheerio')
const Logger = require('./Logger')



class LeetCodeProvider {


static getInstance() {
return this.oInstance || (this.oInstance = new LeetCodeProvider)
}

getProblemsTitle() {
return new Promise((ok,unExpect) => {

Logger.success('正在获取问题列表...')

request({
method:'GET',
url:'https://github.com/azl397985856/leetcode/tree/master/problems',
encoding:null},
(error,response,body) => {
if(error) {
unExpect(Logger.error('获取问题列表失败',error) && error)
} else {
let aProblemTitles =[]
let sHtml = Iconv.decode(body, 'utf-8').toString()
cheerio.load(sHtml)('.js-navigation-item .content .js-navigation-open ').each((idx,ele)=> aProblemTitles.push(ele.attribs['title']) )
Logger.success('获取问题列表成功')
ok(aProblemTitles)
}
})

})
}

getProblemDetail(problemNameWithExt) {
return new Promise((ok, unExpect) => {

Logger.success('正在抓取问题:', problemNameWithExt)

request({
method:'GET',
url:`https://raw.githubusercontent.com/azl397985856/leetcode/master/problems/${problemNameWithExt}`,
encoding:null
},
(error,response,body) => {
if (error) {
unExpect(Logger.error(`抓取问题 "${problemNameWithExt}" 失败`,error) && error)
} else {
let markdown = Iconv.decode(body, 'utf-8').toString()
Logger.success(`抓取问题 "${problemNameWithExt}" 成功!`)
ok(markdown)
}

})
})
}

}

module.exports = LeetCodeProvider
24 changes: 24 additions & 0 deletions scripts/Logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

const log4js = require("log4js");

const logger = log4js.getLogger()

logger.level = 'debug'

logger.category = 'LeetCode'

class Logger {



static success(...args) {
logger.info(...args)
}

static error(...args) {
logger.error(...args)
}

}

module.exports = Logger
10 changes: 10 additions & 0 deletions scripts/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@



module.exports = {
support_language: [
'java',
'python',
'js'
]
}
64 changes: 64 additions & 0 deletions scripts/curl-leetcode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const LeetCodeProvider = require('./LeetCodeProvider')

const Logger = require('./Logger')

const Utils = require('./utils')

/**
* 请求处理频率 ms
*/
const requestRate = 300

/**
* 当前请求问题索引
*/
let requsetNumber = 0


const getProblemDetail = (questionsName, requsetNumber) => {

const cachedFilesName = Utils.getDirsFileName('spider/row-markdown')

if ( cachedFilesName.includes(questionsName[requsetNumber]) ) {

Logger.success(`${questionsName[requsetNumber]}命中缓存, 跳过。。。`)

requsetNumber++

setTimeout(() => {

getProblemDetail(questionsName, requsetNumber)

}, requestRate)
}
else {

questionsName[requsetNumber] && LeetCodeProvider.getInstance().getProblemDetail(questionsName[requsetNumber]).then(markDown => {

Logger.success(`问题: "${questionsName[requsetNumber]}" | 结果: ${JSON.stringify(markDown)}`)

Utils.writeFileSync('spider/row-markdown/',questionsName[requsetNumber],markDown)

requsetNumber++
}).catch(Logger.error).then(() => {

setTimeout(() => {

questionsName[requsetNumber] && getProblemDetail(questionsName, requsetNumber)

}, requestRate)
})
}

}


LeetCodeProvider.getInstance().getProblemsTitle().then(questionsName => {

getProblemDetail(questionsName, requsetNumber)

})




74 changes: 74 additions & 0 deletions scripts/generate-leetcode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const Utils = require('./utils')
const Logger = require('./Logger')
const { support_language } = require('./constants')




const genertateLeetcodeToJson = () => {
const rowMarkdowns = Utils.getDirsFileName('spider/row-markdown')

rowMarkdowns.forEach(filename => {

let languageResloved = []
let markdown

try {

Logger.success(`开始读取${filename}`)

markdown = Utils.readFileSync(`spider/row-markdown/`,filename)

Logger.success(`读取${filename}完毕`)

}
catch (error) {

Logger.error(`读取${filename}失败`,error)
}


/**
* 此替换是为了解决正则匹配java时出现的问题
*/

markdown = markdown.replace(/```javascript/g, '```js')

support_language.forEach(lang => {

markdown.replace(Utils.genRegByLang(lang), (noUseMatch, $1) => {

languageResloved.push({
lang,
code: $1
})

})


let oCustomStruct = {
question: filename.slice(0,-3),
companys: ['TODO'],
tags: ['TODO'],
reslove: languageResloved
}



Logger.success(`开始生成 "${filename}"`)

Utils.writeFileSync('spider/yield-db-json',`${filename.slice(0,-3)}.json`, JSON.stringify(oCustomStruct, null, 2))

Logger.success(`生成 "${filename}" 完毕`)

})




})


}

genertateLeetcodeToJson()
46 changes: 46 additions & 0 deletions scripts/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const fs = require('fs')
const { resolve : pathResolve } = require('path')

const { support_language } = require('./constants')


class Utils {


/**
* 获取不同语言的正则表达式
*
* @static
* @param {*} lang
* @returns
* @memberof Utils
*/
static genRegByLang(lang) {
return new RegExp( `(?:\`\`\`${lang})((.|[\r\n])*?)(?:\`\`\`)`,'g')
}


static readFileSync(relativePath,filename) {
return fs.readFileSync(pathResolve(__dirname, '../',relativePath,filename),{encoding:'utf8'})
}

static getDirsFileName(dir) {
return fs.readdirSync(pathResolve(__dirname, '../', dir), {encoding:'utf8'})
}



static writeFileSync(dir,name,content) {
fs.writeFileSync(pathResolve(__dirname, '../', dir ,name),content)
}



}






module.exports = Utils
50 changes: 50 additions & 0 deletions spider/row-markdown/1.TwoSum.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## Problem
https://leetcode-cn.com/problems/two-sum

## Problem Description
```
Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
```

## Solution
The easiest solution to come up with is Brute Force. We could write two for-loops to traverse every element, and find the target numbers that meet the requirement. However, the time complexity of this solution is O(N^2), while the space complexity is O(1). Apparently, we need to find a way to optimize this solution since the time complexity is too high. What we could do is to record the numbers we have traversed and the relevant index with a Map. Whenever we meet a new number during traversal, we go back to the Map and check whether the `diff` between this number and the target number appeared before. If it did, the problem has been solved and there's no need to continue.

## Key Points
- Find the difference instead of the sum
- Connect every number with its index through the help of Map
- Less time by more space. Reduce the time complexity from O(N) to O(1)

## Code
- Support Language: JS

```js
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
const twoSum = function (nums, target) {
const map = new Map();
for (let i = 0; i < nums.length; i++) {
const diff = target - nums[i];
if (map.has(diff)) {
return [map.get(diff), i];
}
map.set(nums[i], i);
}
}
```

***Complexity Anlysis***

- *Time Complexity*: O(N)
- *Space Complexity*:O(N)
Loading