oj题库及答案java,GitHub - YooHoeh/JavaScriptOJ: ScriptOJ Web 前端开发评测系统, 从大量实战代码、面试题目中总结出精华题库和相应的测试,这里记录了题库...

JavascriptOJ

ScriptOJ Web 前端开发评测系统, 从大量实战代码、面试题目中总结出精华题库和相应的测试,这里记录了题库的答案,

答案均为记录自己测试时通过的代码,每道题可能存在更优解,如有更好解决方案可以一起讨论。

0. Hello World

在 id 为 content 的 div 中只显示 Hello World 字样。(注意不要有多余空白字符)

Hello World

1. 用 React.js 在页面上渲染标题

在页面上增加一个 id 为 root 的

元素。然后请你完成一个 renderContent 函数,这个函数会把传入的任意字符串都包装到一个

元素中并且渲染到页面上。例如:

renderContent("Hello World");

页面上就有相应的内容:

Hello World

只能通过 React.js 来实现。

/* 环境中已经注入了 React,ReactDOM */

function renderContent(content) {

ReactDOM.render(

{content}

, document.getElementById("root"));

}

2. 使用 React.js 构建一个未读消息组件 Notification

通过 getNotificationsCount() 来获取未读消息的数量 ,如果有未读消息 N 条,而且 N > 0,那么 Notification 组件渲染显示:

有(N)条未读消息

否则显示:

没有未读消息

(你只需要完成组件部分,不需要调用 ReactDOM)

// 函数 getNotificationsCount 已经可以直接调用

class Notification extends Component {

render() {

const count = getNotificationsCount();

return count > 0 ? (

有(

{count}

)条未读消息

) : (

没有未读消息

);

}

}

3. JSX 元素变量

用 JSX 完成两个变量的定义:

第一个变量 title 为一个具有类名为 title 的

元素,其内容为 ScriptOJ;

第二个变量 page 为一个具有类名为 content 的

元素,将之前定义的 title 变量插入其中作为它的内容。

const title =

ScriptOJ

;

const page =

{title}
;

4. 用 React.js 组建的房子

一个房子里面有一个房间和一个洗手间,房间里面有一个人和两条狗。

请你完成组件:House,Room,Bathroom,Man,Dog,它们的最外层都用 div 标签包裹起来,类名分别为:house,room,bathroom,man,dog。组件的实现应该具有上述的嵌套关系。

// Component 已经可以直接使用

class House extends Component {

render() {

return (

);

}

}

class Room extends Component {

render() {

return (

);

}

}

class Bathroom extends Component {

render() {

return

}

}

class Man extends Component {

render() {

return

}

}

class Dog extends Component {

render() {

return

}

}

5. 不能摸的狗(一)

有一只狗,不允许别人摸它,一旦摸它就会叫,然后就跑了。

完成 Dog 组件,当用户点击的时候会执行自身的 bark 和 run 方法。

class Dog extends Component {

bark() {

console.log("bark");

this.run();

}

run() {

console.log("run");

}

render() {

return

DOG
;

}

}

6. 不能摸的狗(二)

有一只狗,不允许别人摸它,一旦摸它就会叫,然后就跑了;这只狗跑一段时间(20~50ms)以后就会停下来,也不叫了。

完成 Dog 组件,当用户点击的时候会执行自身的 bark 和 run 方法。给这个 Dog 组件加上状态 isRunning 和 isBarking,在进行相应的动作的时候设置为 true,停下来的时候设置为 false。

class Dog extends Component {

constructor() {

super();

this.state = {

isRunning: false,

isBarking: false

};

}

bark() {

this.setState({ isBarking: true });

setTimeout(() => this.setState({ isBarking: false }), 20);

this.run();

}

run() {

this.setState({ isRunning: true });

setTimeout(() => this.setState({ isRunning: false }), 20);

}

render() {

return

DOG
;

}

}

8. 打印章节标题

现在需要在页面上显示一本书的章节,章节内容存放到一个数组里面:

const lessons = [

{ title: 'Lesson 1: title', description: 'Lesson 1: description' },

{ title: 'Lesson 2: title', description: 'Lesson 2: description' },

{ title: 'Lesson 3: title', description: 'Lesson 3: description' },

{ title: 'Lesson 4: title', description: 'Lesson 4: description' }

...

]

现在需要你构建两个组件。一个组件为 Lesson 组件,渲染特定章节的内容。可以接受一个名为 lesson 的 props,并且把章节以下面的格式显示出来:

Lesson 1: title

Lesson 1: description

点击每个章节的时候,需要把章节在列表中的下标和它的标题打印(console.log)出来,例如第一个章节打印: 0 - Lesson 1: title,第二个章节打印:1 - Lesson 2: title。

另外一个组件为 LessonsList,接受一个名为 lessons 的 props,它会使用 Lesson 组件把章节列表渲染出来。

class Lesson extends Component {

handleClick(title, key) {}

render() {

const { lesson, index } = this.props;

return (

console.log(index + " - " + lesson.title)}>

{lesson.title}

{lesson.description}

);

}

}

class LessonsList extends Component {

renderList(lessonsList) {

return lessonsList.map((item, index) => (

));

}

render() {

const { lessons } = this.props;

return

{this.renderList(lessons)}
;

}

}

9. 百分比换算器

做一个百分比换算器,需要你完成三个组件::封装了原生的,可以输入任意数字:实时 显示 中的数字内容,但是需要把它转换成百分比,例如 输入的是 0.1,那么就要显示 10.00%,保留两位小数。:组合上述两个组件。

class Input extends Component {

render() {

const { value, handleChange } = this.props;

return (

);

}

}

class PercentageShower extends Component {

render() {

const { value } = this.props;

return

{(value * 100).toFixed(2) + "%"}
;

}

}

class PercentageApp extends Component {

state = {

value: 2

};

handleChange(e) {

this.setState({

value: e.target.value

});

}

render() {

return (

handleChange={this.handleChange.bind(this)}

value={this.state.value}

/>

);

}

}

11. 获取文本的高度

完成 Post 组件,接受一个字符串的 content 作为 props,Post 会把它显示到自己的

元素内。

并且,点击

元素的时候,会使用 console.log 把元素的高度打印出来。

class Post extends Component {

showEleHeight(e) {

console.log(e.target.clientHeight);

}

render() {

const { content } = this.props;

return

{content}

;

}

}

19. 获取文件的扩展名

完成 extname 函数,它会接受一个文件名作为参数,你需要返回它的扩展名。例如,输入 emoji.png,返回 .png。

const extname = filename => {

const dot = filename.lastIndexOf(".");

if (dot === -1 || dot === 0) return "";

return filename.slice(dot);

};

23. 肥猫列表

现在有很多只猫,都很肥:

const cats = [

{ name: 'Tom', weight: 300 },

{ name: 'Lucy', weight: 400 },

{ name: 'Lily', weight: 700 },

{ name: 'Jerry', weight: 600 },

...

]

现在你需要把它们按照由胖到瘦的顺序把它们渲染到 id 为 cats-list 的 div 元素当中:

Lily 700

Jerry 600

Lucy 400

Tom 300

...

完成 renderFatCats 函数,接受一个 cats 数组作为参数,然后它会往 div#cats-list 元素内渲染类似以上的结果。注意类名需要保持一致;另外renderFatCats 可能会被多次调用,注意清空上一次渲染的数据。

你可以使用 jQuery、React.js 等方式来完成。

(你不需要调用 renderFatCats)。

function renderFatCats(cats) {

const list = document.getElementById("cats-list");

list.innerHTML = "";

cats.sort((a, b) => {

return a.weight > b.weight ? -1 : 1;

});

let renders = "";

cats.forEach(item => {

renders += `

${item.name}

${item.weight}

`;

});

list.innerHTML = renders.trim();

}

24. +1s 程序

完成一个生成计数器的函数 plusFor,调用它会返回一个计数器。计数器本身也是一个函数,每次调用会返回一个字符串。达到以下的效果:

const counter1 = plusFor('小明')

counter1() // => 为小明+1s

counter1() // => 为小明+2s

counter1() // => 为小明+3s

...

const counter2 = plusFor('李梅')

counter2() // => 为李梅+1s

counter2() // => 为李梅+2s

counter2() // => 为李梅+3s

...

注意你只需要完成 plusFor 函数,不要使用额外的全局变量。

const plusFor = name => {

let count = 0;

return () => {

count++;

return `为${name}+${count}s`;

};

};

30. curry 函数

函数式编程当中有一个非常重要的概念就是 函数柯里化。一个接受 任意多个参数 的函数,如果执行的时候传入的参数不足,那么它会返回新的函数,新的函数会接受剩余的参数,直到所有参数都传入才执行操作。这种技术就叫柯里化。请你完成 curry 函数,它可以把任意的函数进行柯里化,效果如下:

const f = (a, b, c d) => { ... }

const curried = curry(f)

curried(a, b, c, d)

curried(a, b, c)(d)

curried(a)(b, c, d)

curried(a, b)(c, d)

curried(a)(b, c)(d)

curried(a)(b)(c, d)

curried(a, b)(c)(d)

// ...

// 这些函数执行结果都一样

// 经典加法例子

const add = curry((a, b) => a + b)

const add1 = add(1)

add1(1) // => 2

add1(2) // => 3

add1(3) // => 4

//注意,传给 curry 的函数可能会有任意多个参数。

ES5 做法:

function curry(fn) {

var curArgs = arguments[1] && arguments.length > 1 ? arguments[1] : [];

return function() {

// let args = Array.from(arguments); //es6

var args = Array.prototype.slice(arguments);

if (curArgs.length + arguments.length < fn.length) {

return curry(fn, curArgs.concat(args));

} else {

return fn.apply(undefined, curArgs.concat(args));

}

};

}

ES6 做法:

const curry = (f, arr = []) => {

return (...args) => {

return (a) => {

return a.length === f.length ? f(a) : curry(f, a);

}([...arr, ...args]);

};

54. 你是五年的程序员吗

请写出一个函数 initArray ,接受两个参数 m 和 n,返回一个数组,它的长度是 m,每个值都是 n,不能用循环.

const initArray = (m, n) => {

return new Array(m).fill(n);

};

89. 数组去重

编写一个函数 unique(arr),返回一个去除数组内重复的元素的数组。例如:

unique([0, 1, 2, 2, 3, 3, 4]) // => [0, 1, 2, 3, 4]

unique([0, 1, '1', '1', 2]) // => [0, 1, '1', 2]

const unique = (arr) =>Array.from(new Set(arr))

91. 数组拍平(二)

编写一个 JavaScript generator 函数,接受一个仅包含数字的 多维数组 ,返回一个迭代器,可以遍历得到它拍平以后的结果。例如:

const numbers = flatten2([1, [[2], 3, 4], 5])

numbers.next().value // => 1

numbers.next().value // => 2

numbers.next().value // => 3

numbers.next().value // => 4

numbers.next().value // => 5

function *flatten2 (arr) {

const flatArr = arr.flat(Infinity);

while(flatArr){

yield flatArr.shift();

}

}

94. 按下标插入

现在有一个数组存放字符串数据:

['item1', 'item2', 'item3', 'item4', 'item5']

有另外一个数组存放一组对象:

[

{ content: 'section1', index: 0 },

{ content: 'section2', index: 2 }

]

它每个对象表示的是会往原来的数组的 index坐标插入 content 数据(index 不会重复):

0 1 2 3 4

item1 itme2 item3 item4 item5

^ ^

| |

section1 section2

最后结果是:['section1', 'item1', 'item2', 'section2', 'item3', 'item4', 'item5']

请你完成 injectSections 函数,可以达到上述的功能:

injectSections(

['item1', 'item2', 'item3', 'item4', 'item5'],

[

{ content: 'section1', index: 0 },

{ content: 'section2', index: 2 }

]

) // => ['section1', 'item1', 'item2', 'section2', 'item3', 'item4', 'item5']

const injectSections = (items, sections) => {

let rest = sections;

let result = items;

while(rest.length){

let section = rest.pop();

rest = rest.map(i => {

if( i.index > section.index ) {

return {

content:i.content,

index:i.index + 1

}

}

return i

})

result.splice(section.index,0,section.content)

}

return result;

}

这里分享几个网上找的神仙算法:

const injectSections = (items, sections) => {

sections.forEach(

(v,i)=>{

items[v.index]=[v.content,items[v.index]]

}

);

return [].concat.apply([],items);

}

const injectSections = (items, sections) =>

[].concat.apply(

[],

sections.reduce(

(o,s)=>(o[s.index]=[s.content,o[s.index]]) && o,

items

)

);

const injectSections = (items, sections) =>

sections

.sort((a,b)=>b.index-a.index)

.reduce((it,se)=>[].concat(it.splice(0,se.index),se.content,it),items)

96. spacify

请你给字符串都添加上原型方法 spacify,可以让一个字符串的每个字母都多出一个空格的间隔:

"ScriptOJ".spacify() // => "S c r i p t O J"

String.prototype.spacify = funcxtion() {

return this.split('').join(' ');

}

97. 类名操作

完成几个 DOM 元素类名操作的工具方法:

addClass(dom, name):给 dom 元素添加类名 name

removeClass(dom, name):把 dom 元素的类名 name 删除

hasClass(dom, name):判断 dom 元素是否有类名 name

const addClass = (dom, name) => dom.classList.add(name);

const removeClass = (dom, name) => dom.classList.remove(name);

const hasClass = (dom, name) => dom.classList.contains(name);

98. 判断两个矩形是否重叠

用一个对象的数据来表示一个矩形的位置和大小:

{

x: 100,

y: 100,

width: 150,

height: 250

}

它表示一个宽为 150 高为 250 的矩形在页面上的 (100, 100) 的位置。

请你完成一个函数 isOverlap 可以接受两个矩形作为参数,判断这两个矩形在页面上是否重叠。例如:

const rect1 = { x: 100, y: 100, width: 100, height: 100 };

const rect2 = { x: 150, y: 150, width: 100, height: 100 };

isOverlap(rect1, rect2); // => true

const isOverlap = (rect1, rect2) => {

let left, right, top, bottom;

if (rect1.x < rect2.x) {

left = rect1;

right = rect2;

} else {

left = rect2;

right = rect1;

}

if (left.x + left.width < right.x) return false;

if (rect1.y > rect2.y) {

top = rect1;

bottom = rect2;

} else {

top = rect2;

bottom = rect1;

}

if (top.y > bottom.y + bottom.height) return false;

return true;

};

99. safeGet

有时候我们需要访问一个对象较深的层次,但是如果这个对象某个属性不存在的话就会报错,例如:

var data = { a: { b: { c: 'ScriptOJ' } } }

data.a.b.c // => scriptoj

data.a.b.c.d // => 报错,代码停止执行

console.log('ScriptOJ') // => 不会被执行

请你完成一个 safeGet 函数,可以安全的获取无限多层次的数据,一旦数据不存在不会报错,会返回 undefined,例如:

var data = { a: { b: { c: 'ScriptOJ' } } }

safeGet(data, 'a.b.c') // => scriptoj

safeGet(data, 'a.b.c.d') // => 返回 undefined

safeGet(data, 'a.b.c.d.e.f.g') // => 返回 undefined

console.log('ScriptOJ') // => 打印 ScriptOJ

const safeGet = (data, path) => {

if(data == undefined) return undefined;

const pathArr = path.split('.');

let result = data;

for(let i = 0; i < pathArr.length; i++) {

if(result[pathArr[i]] == undefined) return undefined;

result = result[pathArr[i]];

}

return result

}

102. 记忆化斐波那契函数(Memoization)

斐波那契数列指的是类似于以下的数列:

1, 1, 2, 3, 5, 8, 13, ....

也就是,第 n 个数由数列的前两个相加而来:f(n) = f(n - 1) + f(n -2)

请你完成 fibonacci 函数,接受 n 作为参数,可以获取数列中第 n 个数,例如:

fibonacci(1); // => 1

fibonacci(2); // => 1

fibonacci(3); // => 2

测试程序会从按顺序依次获取斐波那契数列中的数,请注意程序不要超时,也不要添加额外的全局变量。

const fibonacci = n => {

// 这里添加一个方法内变量cache来保存前1000000个值

if (!fibonacci.cache) {

fibonacci.cache = [];

for (let i = 1; i <= 1000000; i++) {

if (i === 1 || i === 2) {

fibonacci.cache[i] = 1;

} else if (i > 2) {

fibonacci.cache[i] = fibonacci.cache[i - 1] + fibonacci.cache[i - 2];

}

}

}

return fibonacci.cache[n];

};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值