提交 7f771bbc authored 作者: xiejiang's avatar xiejiang

feat: 新增知识markdown格式

上级 605a0e56
import type { PackageType as PackageType_0,RemoteKeys as RemoteKeys_0 } from './remote/apis.d.ts';
declare module "@module-federation/runtime" {
type RemoteKeys = RemoteKeys_0;
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
Y ;
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
}
declare module "@module-federation/enhanced/runtime" {
type RemoteKeys = RemoteKeys_0;
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
Y ;
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
}
declare module "@module-federation/runtime-tools" {
type RemoteKeys = RemoteKeys_0;
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
Y ;
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
}
\ No newline at end of file
export type RemoteKeys = 'remote/home';
type PackageType<T> = T extends 'remote/home' ? typeof import('remote/home') :any;
\ No newline at end of file
declare const _default: import("vue").DefineComponent<{
count: number;
}, () => any, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "increase"[], "increase", import("vue").PublicProps, Readonly<{
count: number;
}> & Readonly<{
onIncrease?: ((...args: any[]) => any) | undefined;
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
export default _default;
export * from './compiled-types/src/views/home/but';
export { default } from './compiled-types/src/views/home/but';
\ No newline at end of file
...@@ -13,7 +13,7 @@ import { pluginTypeCheck } from '@rsbuild/plugin-type-check' ...@@ -13,7 +13,7 @@ import { pluginTypeCheck } from '@rsbuild/plugin-type-check'
import { pluginSvgSpriteLoader } from 'rsbuild-plugin-svg-sprite-loader' import { pluginSvgSpriteLoader } from 'rsbuild-plugin-svg-sprite-loader'
import AutoImport from 'unplugin-auto-import/rspack' import AutoImport from 'unplugin-auto-import/rspack'
import Components from 'unplugin-vue-components/rspack' import Components from 'unplugin-vue-components/rspack'
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin' // import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'
import { TDesignResolver } from 'unplugin-vue-components/resolvers' import { TDesignResolver } from 'unplugin-vue-components/resolvers'
import { join } from 'path' import { join } from 'path'
export const createPlugins = () => { export const createPlugins = () => {
...@@ -22,18 +22,18 @@ export const createPlugins = () => { ...@@ -22,18 +22,18 @@ export const createPlugins = () => {
pluginBabel({ pluginBabel({
include: /\.(?:jsx|tsx)$/ include: /\.(?:jsx|tsx)$/
}), }),
pluginModuleFederation({ // pluginModuleFederation({
name: 'master', // name: 'master',
remotes: { // remotes: {
remote: 'remote@http://localhost:5174/mf-manifest.json' // remote: 'remote@http://localhost:5174/mf-manifest.json'
}, // },
shared: { // shared: {
lodash: { // lodash: {
singleton: true, // singleton: true,
eager: true // eager: true
} // }
} // }
}), // }),
pluginVue(), pluginVue(),
pluginVueJsx(), pluginVueJsx(),
pluginLess(), pluginLess(),
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vue.svg" /> <link rel="icon" type="image/svg+xml" href="/vue.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css" />
</head> </head>
<body> <body>
<div id="app"> <div id="app">
......
...@@ -30,16 +30,32 @@ ...@@ -30,16 +30,32 @@
"preinstall": "npx only-allow pnpm" "preinstall": "npx only-allow pnpm"
}, },
"dependencies": { "dependencies": {
"@module-federation/enhanced": "^0.10.0", "@DatatracCorporation/markdown-it-mermaid": "npm:@datatraccorporation/markdown-it-mermaid@^0.5.0",
"@module-federation/rsbuild-plugin": "^0.10.0",
"@types/vuedraggable": "^2.24.0", "@types/vuedraggable": "^2.24.0",
"@vueuse/core": "^11.1.0", "@vueuse/core": "^11.1.0",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12", "@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^1.7.7", "axios": "^1.7.7",
"clipboard": "^2.0.11",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"highlight.js": "^11.11.1",
"jquery": "^3.7.1",
"js-md5": "^0.8.3", "js-md5": "^0.8.3",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"markdown-it": "^14.1.0",
"markdown-it-abbr": "^2.0.0",
"markdown-it-container": "^4.0.0",
"markdown-it-deflist": "^3.0.0",
"markdown-it-emoji": "^3.0.0",
"markdown-it-footnote": "^4.0.0",
"markdown-it-ins": "^4.0.0",
"markdown-it-katex": "^2.0.3",
"markdown-it-mark": "^4.0.0",
"markdown-it-sub": "^1.0.0",
"markdown-it-sup": "^1.0.0",
"markdown-it-task-lists": "^2.1.1",
"markdown-it-toc": "^1.1.0",
"markdown-it-toc-done-right": "^4.2.0",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"only-allow": "^1.2.1", "only-allow": "^1.2.1",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-05 10:14:56 * @Date: 2024-11-05 10:14:56
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-11-28 16:32:10 * @LastEditTime: 2025-03-25 15:16:25
* @Description: * @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
*/ */
...@@ -14,6 +14,22 @@ declare module '*.vue' { ...@@ -14,6 +14,22 @@ declare module '*.vue' {
export default component export default component
} }
// markdown-it
declare module 'markdown-it'
declare module 'markdown-it-emoji'
declare module 'markdown-it-deflist'
declare module 'markdown-it-abbr'
declare module 'markdown-it-footnote'
declare module 'markdown-it-ins'
declare module 'markdown-it-mark'
declare module 'markdown-it-task-lists'
declare module 'markdown-it-container'
declare module 'markdown-it-toc-done-right'
declare module '@DatatracCorporation/markdown-it-mermaid'
declare module 'markdown-it-katex'
declare module 'jquery'
// jsx 报错 // jsx 报错
declare namespace JSX { declare namespace JSX {
interface IntrinsicElements { interface IntrinsicElements {
...@@ -21,8 +37,6 @@ declare namespace JSX { ...@@ -21,8 +37,6 @@ declare namespace JSX {
} }
} }
declare module 'remote/*'
/* Menu */ /* Menu */
declare namespace Menu { declare namespace Menu {
interface MenuOptions { interface MenuOptions {
......
...@@ -159,3 +159,21 @@ export const isPhoneNumber = function (phone: string): boolean { ...@@ -159,3 +159,21 @@ export const isPhoneNumber = function (phone: string): boolean {
const isMob = /^((\+?86)|(\(\+86\)))?(1[3-9][0-9]{9})$/ const isMob = /^((\+?86)|(\(\+86\)))?(1[3-9][0-9]{9})$/
return isMob.test(phone) return isMob.test(phone)
} }
// 格式化输出内容,将行间公式和行内公式替换为对应的数学公式组件
export function formatOutputKatex(content: string) {
if (!content) return ''
const replaceFormula = (formula: string) => {
formula = formula.replace(/\s+/g, ' ').trim() // 去除换行符和多余空格
return `$${formula}$`
}
// 替换行间公式 \[ ... \]
content = content.replace(/\\\[(.*?)\\\]/gs, (match, formula) => replaceFormula(formula))
// 替换行内公式 \( ... \)
content = content.replace(/\\\((.*?)\\\)/gs, (match, formula) => replaceFormula(formula))
return content
}
import './index.less'
import 'highlight.js/styles/atom-one-dark.css'
import $ from 'jquery'
import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
import vbscript from 'highlight.js/lib/languages/vbscript'
import python from 'highlight.js/lib/languages/python'
import matlab from 'highlight.js/lib/languages/matlab'
import csharp from 'highlight.js/lib/languages/csharp'
import shell from 'highlight.js/lib/languages/shell'
import vhdl from 'highlight.js/lib/languages/vhdl'
import java from 'highlight.js/lib/languages/java'
import css from 'highlight.js/lib/languages/css'
import xml from 'highlight.js/lib/languages/xml'
import sql from 'highlight.js/lib/languages/sql'
import cpp from 'highlight.js/lib/languages/cpp'
import c from 'highlight.js/lib/languages/c'
import ClipboardJS from 'clipboard'
hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('vbscript', vbscript)
hljs.registerLanguage('python', python)
hljs.registerLanguage('matlab', matlab)
hljs.registerLanguage('csharp', csharp)
hljs.registerLanguage('shell', shell)
hljs.registerLanguage('vhdl', vhdl)
hljs.registerLanguage('java', java)
hljs.registerLanguage('html', xml)
hljs.registerLanguage('xml', xml)
hljs.registerLanguage('css', css)
hljs.registerLanguage('sql', sql)
hljs.registerLanguage('cpp', cpp)
hljs.registerLanguage('c', c)
hljs.configure({ ignoreUnescapedHTML: true })
/**
* 高亮代码块
* @param {HTMLElement} element 包含 pre code 代码块的元素
*/
function highlightCode(element: HTMLElement): void {
const codeEls = element.querySelectorAll('pre code')
codeEls.forEach(el => {
hljs.highlightElement(el as HTMLElement)
})
}
/**
* 给代码块添加复制按钮
* @param {HTMLElement} element 包含 pre code 代码块的元素
*/
function buildCopyButton(element: HTMLElement): void {
const $pres = $(element).find('pre')
if (!$pres.length) return
$pres.each(function (this: HTMLElement) {
const t = $(this).children('code').text()
// 创建按钮
const btn = $('<span class="copy">复制</span>').attr('data-clipboard-text', t)
$(this).prepend(btn)
const c = new ClipboardJS(btn[0] as HTMLElement)
c.on('success', function () {
btn.addClass('copyed').text('复制成功')
setTimeout(function () {
btn.text('复制').removeClass('copyed')
}, 1000)
})
c.on('error', function () {
btn.text('复制失败')
})
})
}
/** 构建生成中的 markdown 的内容 */
export function buildCodeBlock(element: HTMLElement): void {
highlightCode(element)
buildCopyButton(element)
}
/** 核心函数, 对比节点的内容 实现动态更新 markdown 的 div 而不是用 innerHTML 的属性全部刷新 */
export function deepCloneAndUpdate(div1: HTMLElement, div2: HTMLElement): void {
// 递归比较和更新 div1 和 div2 的子节点
function compareAndUpdate(node1: Node, node2: Node): void {
// 情况 1:node1 是文本节点,更新文本内容
if (node1.nodeType === Node.TEXT_NODE && node2.nodeType === Node.TEXT_NODE) {
if (node1.nodeValue !== node2.nodeValue) {
// 更新文本内容
node1.nodeValue = node2.nodeValue
}
return
}
// 情况 2:node1 和 node2 的标签名不同,替换整个节点
if (node1.nodeType !== node2.nodeType || (node1 as HTMLElement).tagName !== (node2 as HTMLElement).tagName) {
const newNode = node2.cloneNode(true)
if (node1.parentNode) {
node1.parentNode.replaceChild(newNode, node1)
}
return
}
const el1 = node1 as HTMLElement
const el2 = node2 as HTMLElement
// 情况 3:节点的 class 或其他属性更新, 注意对root节点的保护
if (el1.className !== 'article-content' && el1.className !== el2.className) {
el1.className = el2.className
}
if (el1.id !== 'article-content' && el1.id !== el2.id) {
el1.id = el2.id
}
if (el1.style.cssText !== el2.style.cssText) {
el1.style.cssText = el2.style.cssText
}
// 情况 4:递归对比和更新子节点
const children1 = Array.from(el1.childNodes)
const children2 = Array.from(el2.childNodes)
children2.forEach((child2, index) => {
const child1 = children1[index]
if (!child1) {
const newChild = child2.cloneNode(true)
el1.appendChild(newChild)
} else {
compareAndUpdate(child1, child2)
}
})
if (children1.length > children2.length) {
for (let i = children2.length; i < children1.length; i++) {
el1.removeChild(children1[i])
}
}
}
compareAndUpdate(div1, div2)
}
.hljs,
.hljsln {
display: block;
overflow-x: auto;
padding: 0.7em 1em 0.7em 1.2em !important;
background: #282c34 !important;
border: 1px solid #282c34 !important;
color: #bababa;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace !important;
font-size: 14px !important;
position: relative;
/* 代码块不换行 */
white-space: pre;
word-break: normal;
&::-webkit-scrollbar {
height: 4px;
}
}
.hljs.ln-hide {
padding: 0.7em 1em !important;
}
.ln-bg {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 37px;
height: 100%;
background: #282c34;
border-radius: 7px 0 0 7px;
}
.ln-num {
position: absolute;
z-index: 2;
left: 0;
width: 37px;
text-align: center;
display: inline-block;
-webkit-touch-callout: none;
user-select: none;
&::before {
color: #999;
font-style: normal;
font-weight: normal;
text-align: center;
content: attr(data-num);
}
}
.hljs-comment,
.hljs-quote {
color: #5c6370;
font-style: italic;
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #c678dd;
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta-string {
color: #98c379;
}
.class_ {
color: #e5c07b !important;
}
.hljs-attr {
color: #d19a66 !important;
}
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #d19a66;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
color: #61afef;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}
.hljs-built_in {
color: #56b6c2;
}
.hljs-tag .hljs-name {
color: #e06c75;
}
.hljs-tag {
color: #bababa;
}
.hljs-attribute,
.hljs-doctag,
.hljs-keyword,
.hljs-meta .hljs-keyword,
.hljs-name,
.hljs-selector-tag,
.hljs-title {
font-weight: normal !important;
}
.hljs-punctuation {
color: #bababa;
}
// .hljs::-webkit-scrollbar,
// .hljsln::-webkit-scrollbar {
// height: 3px;
// }
.article-content pre,
.comment-item-content pre {
position: relative;
& > span {
position: absolute;
top: 0;
right: 0;
border-radius: 3px;
padding: 3px 10px;
font-size: 12px;
font-family: Lato, 'PingFang SC', 'Microsoft YaHei', sans-serif;
font-weight: normal;
background: #fff;
color: #000;
cursor: pointer;
opacity: 0;
margin: 8px 10px;
transition: all 0.3s;
z-index: 5;
&:hover {
background: #ddd;
}
}
&:hover > span {
opacity: 1;
transition: opacity 0.25s;
}
}
import MarkdownIt from 'markdown-it'
import { full as emoji } from 'markdown-it-emoji' // 使用 full 导出
import deflist from 'markdown-it-deflist'
import abbr from 'markdown-it-abbr'
import footnote from 'markdown-it-footnote'
import ins from 'markdown-it-ins'
import mark from 'markdown-it-mark'
import taskLists from 'markdown-it-task-lists'
import container from 'markdown-it-container'
import toc from 'markdown-it-toc-done-right'
import mermaid from '@DatatracCorporation/markdown-it-mermaid'
import katex from 'markdown-it-katex'
const config = {
html: true,
xhtmlOut: true,
breaks: true,
langPrefix: 'lang-',
linkify: false,
typographer: true,
quotes: '“”‘’'
}
const markdownIt = new MarkdownIt(config)
markdownIt
.use(emoji)
.use(deflist)
.use(abbr)
.use(footnote)
.use(ins)
.use(mark)
.use(taskLists)
.use(container)
.use(container, 'hljs-left')
.use(container, 'hljs-center')
.use(container, 'hljs-right')
.use(toc)
.use(mermaid)
.use(katex)
export default markdownIt
...@@ -2,112 +2,73 @@ ...@@ -2,112 +2,73 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-05 10:14:56 * @Date: 2024-11-05 10:14:56
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2025-03-04 11:02:32 * @LastEditTime: 2025-03-25 15:57:55
* @Description: 首页 * @Description: 首页
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
<template> <template>
<!-- <div class="home w-full h-full"> <div class="article-content" id="article-content"></div>
<div class="home-avatar flex items-center justify-center">
<div class="text-center">
<p class="text-[20px] bold">{{ userInfo && userInfo.userName }},您好!</p>
<p class="text-14">欢迎使用智慧教育平台</p>
</div>
</div>
<div class="home-line w-full"></div>
<div class="home-user flex flex-col items-center justify-center text-right">
<p>
<span>角色:</span>
<template v-if="userInfo?.userType == 2"><span>超级管理员</span></template>
<template v-else>
<span class="max-w-[calc(100%-90px)]">
<span v-for="v in userInfo?.roleNames || []" :key="v"> {{ v }}</span></span
>
<span v-if="!userInfo?.roleNames.length">-</span></template
>
</p>
<p>
<span>上次登录:</span>
<span class="max-w-[calc(100%-90px)]"
>{{ userInfo?.loginInfo.loginAddress || '-' }}、{{ userInfo?.loginInfo.loginIp || '-' }}、{{
userInfo?.loginInfo.time || '-'
}}、{{ userInfo?.loginInfo.device || '-' }}</span
>
</p>
</div>
<img :src="homeImg" class="mt-[80px]" width="502" alt="" />
</div> -->
<DetailTable />
<RemoteButton :count="count" @increase="count++" />
</template> </template>
<script setup lang="ts" name="home"> <script setup lang="ts" name="home">
// import { useUserStore } from '@/stores/modules/user' import markdownIt from '@/utils/markdown'
import { useBasic } from '@/hooks/useBasic' import { deepCloneAndUpdate, buildCodeBlock } from '@/utils/markdown/code-block'
// import homeImg from '@/assets/images/home-img.png' import { formatOutputKatex } from '@/utils'
// const userStore = useUserStore()
// const userInfo = computed(() => userStore.userInfo)
// import RemoteButton from 'remote/button'
const RemoteButton = defineAsyncComponent(() => import('remote/home')) let htmlData: string = ''
let el: HTMLElement | null = null
let isRendering = false
const renderQueue: string[] = []
const count = ref(1) /** Step 4. 渲染markdown的 HTML Element. */
const renderMarkdown = (data: string) => {
if (!el) el = document.getElementById('article-content')
if (!el) return
const { setMenuSign } = useBasic() const tmpDiv = document.createElement('div')
tmpDiv.innerHTML = markdownIt.render(formatOutputKatex(data)) // 只渲染当前的块
buildCodeBlock(tmpDiv)
onMounted(() => { // 这里不再拼接 htmlData,而是每次渲染独立的块
// 设置首页菜单打开 deepCloneAndUpdate(el, tmpDiv)
setMenuSign('home') }
})
</script>
<style lang="less" scoped>
.home {
position: relative;
top: 0;
background: var(--td-white);
text-align: center;
padding-top: 80px;
&-avatar {
text-align: left;
> img {
width: 80px;
height: 80px;
background: var(--td-white);
border: 1px solid var(--td-gray-color-2);
border-radius: 50%;
margin-right: 16px;
}
.bold { /** Step 3. 处理异步渲染 */
font-weight: bold; const processRenderQueue = () => {
} if (renderQueue.length === 0) {
isRendering = false // 队列为空时标记渲染完成
return
} }
&-line { const data = renderQueue.shift() // 获取并移除队列中的第一个渲染任务
height: 6px; if (data !== undefined) {
margin: 40px 0; // 确保数据有效
background: url('@/assets/images/home-line.jpg') no-repeat; renderMarkdown(data) // 执行渲染操作
background-repeat: repeat-x;
} }
&-user { // 继续处理下一个渲染任务
// width: 33%; setTimeout(processRenderQueue, 0)
width: 600px; }
margin: 0 auto;
> p { /** Step 2. 异步队列控制渲染 */
width: 100%; const enqueueRender = (data: string) => {
display: flex; if (!data) return // 避免空数据被添加
justify-content: space-between; htmlData += data
font-weight: 400; renderQueue.push(htmlData)
font-size: 14px; // 如果当前没有渲染任务在进行,启动渲染队列
color: var(--td-font-gray-3); if (!isRendering) {
line-height: 20px; isRendering = true
margin: 4px 0; processRenderQueue()
}
} }
} }
</style>
onMounted(() => {
enqueueRender(
'# Math Rulez! \n $\\sqrt[3x-1]+(1+x)^2$ 🎉当然!以下是一个使用Python实现的冒泡排序算法的示例:\n\n```python\ndef bubble_sort(arr):\n n = len(arr)\n # 遍历所有数组元素\n for i in range(n):\n # 最后i个元素已经是有序的\n for j in range(0, n-i-1):\n # 如果当前元素大于下一个元素,则交换它们测试最大的长度 ============================================================================================================ ==========\n if arr[j] > arr[j+1]:\n arr[j], arr[j+1] = arr[j+1], arr[j]\n # 打印每一轮排序结果用于调试\n print(f"第{i+1}轮排序结果: {arr}")\n return arr\n\n# 示例数组\narr = [64, 34, 25, 12, 22, 11, 90]\nprint("初始数组:", arr)\n\n# 调用冒泡排序函数\nsorted_arr = bubble_sort(arr)\nprint("排序后的数组:", sorted_arr)\n```\n\n在这个代码中:\n1. `bubble_sort`函数接受一个列表作为参数,并对其进行冒泡排序。\n2. 外层循环控制遍历的轮数。\n3. 内层循环用于比较和交换相邻的元素。\n4. 每一轮结束后,最大的元素都会被“冒泡”到列表的末尾。\n5. 在排序过程中,会打印出每一轮排序的中间结果,方便调试和观察排序过程。\n\n运行此代码将会输出每一轮排序后的数组状态,最终输出完全排序的数组。'
)
// enqueueRender(
// '非偶函数的定义是,如果一个函数 \\( f(x) \\) 满足 \\( f(-x) = -f(x) \\) 对所有 \\( x \\) 成立,那么这个函数就是非偶函数。对于偶函数,则满足 \\( f(-x) = f(x) \\)。\n\n给定的函数是 \\( y = x^2(1 - x^2) \\)。首先我们检查这个函数是否为非偶函数:\n\n计算 \\( f(-x) \\):\n\\[ f(-x) = (-x)^2(1 - (-x)^2) \\]\n\\[ f(-x) = x^2(1 - x^2) \\]\n\n显然,\\( f(-x) = x^2(1 - x^2) = f(x) \\),这意味着该函数是偶函数,而不是非偶函数。\n\n接下来,我们求解这个函数。注意到这个函数是一个三次多项式函数,我们可以通过展开和因式分解来求解。\n\n展开原函数:\n\\[ y = x^2(1 - x^2) \\]\n\\[ y = x^2 - x^4 \\]\n\n这是一个关于 \\( x \\) 的三次多项式,我们可以将其因式分解来求解:\n\n\\[ y = x^2(1 - x^2) \\]\n\\[ y = x^2(1 - x)(1 + x) \\]\n\n令 \\( y = 0 \\),我们得到:\n\n\\[ x^2 = 0 \\quad \\Rightarrow \\quad \\] 或 \\[\\quad (1 - x)(1 + x) = 0 \\]\n\n解得:\n\\[ x = 0 \\]\n\\[ 1 - x = 0 \\quad \\Rightarrow \\quad x = 1 \\]\n\\[ 1 + x = 0 \\quad \\Rightarrow \\quad x = -1 \\]\n\n因此,函数 \\( y = x^2(1 - x^2) \\) 的解是 \\( x = -1, 0, 1 \\)'
// )
})
</script>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论