句子单词统计 Key→Value 动态可视化

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>单词统计 Key→Value 动态可视化</title>
<style>
  body {
    font-family: Arial, sans-serif;
    padding: 20px;
    text-align: center;
  }

  #inputArea {
    margin-bottom: 20px;
  }

  #kvContainer {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 20px;
    max-width: 400px;
    margin-left: auto;
    margin-right: auto;
  }

  .kvPair {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 10px;
    border: 1px solid #888;
    border-radius: 5px;
    transition: background-color 0.3s, color 0.3s;
  }

  .kvPair.active {
    background-color: orange;
    color: white;
  }

  .key, .value {
    min-width: 60px;
    text-align: center;
    font-weight: bold;
  }

  .arrow {
    font-size: 16px;
  }

  #controls {
    margin-top: 20px;
  }

  input[type="text"] {
    width: 300px;
    padding: 5px;
    font-size: 16px;
  }

  button {
    padding: 5px 15px;
    font-size: 16px;
    margin-left: 10px;
    cursor: pointer;
  }
</style>
</head>
<body>

<h2>句子单词统计 Key→Value 动态可视化</h2>
<div id="inputArea">
  <input type="text" id="sentenceInput" value="I love coding and I love teaching">
  <button id="startBtn">开始</button>
</div>

<div id="kvContainer">
  <!-- KeyValuePair 会动态生成 -->
</div>

<div id="controls">
  <button id="prevBtn">上一步</button>
  <button id="nextBtn">下一步</button>
</div>

<script>
const sentenceInput = document.getElementById('sentenceInput');
const startBtn = document.getElementById('startBtn');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const kvContainer = document.getElementById('kvContainer');

let steps = [];        // 保存每一步 Map 状态
let currentStep = -1;
let words = [];
let wordMap = new Map();

// 重置可视化
function resetVisualization() {
  kvContainer.innerHTML = '';
  steps = [];
  currentStep = -1;
  wordMap.clear();
}

// 生成每步状态
function recordSteps(sentence) {
  words = sentence.trim().split(/\s+/);
  wordMap.clear();
  steps = [];
  for (let i = 0; i < words.length; i++) {
    const word = words[i].toLowerCase();
    wordMap.set(word, (wordMap.get(word) || 0) + 1);
    const snapshot = new Map(wordMap); // 保存 Map 副本
    steps.push({
      current: word,
      map: snapshot
    });
  }
}

// 渲染指定步骤
function renderStep(stepIndex) {
  if (stepIndex < 0 || stepIndex >= steps.length) return;

  const step = steps[stepIndex];
  const currentWord = step.current;
  const map = step.map;

  kvContainer.innerHTML = ''; // 清空容器

  map.forEach((value, key) => {
    const kvDiv = document.createElement('div');
    kvDiv.classList.add('kvPair');
    if (key === currentWord) kvDiv.classList.add('active');

    const keyDiv = document.createElement('div');
    keyDiv.classList.add('key');
    keyDiv.innerText = key;

    const arrowDiv = document.createElement('div');
    arrowDiv.classList.add('arrow');
    arrowDiv.innerText = '→';

    const valueDiv = document.createElement('div');
    valueDiv.classList.add('value');
    valueDiv.innerText = value;

    kvDiv.appendChild(keyDiv);
    kvDiv.appendChild(arrowDiv);
    kvDiv.appendChild(valueDiv);

    kvContainer.appendChild(kvDiv);
  });

  currentStep = stepIndex;
}

// 按钮事件
startBtn.addEventListener('click', () => {
  const sentence = sentenceInput.value.trim();
  if (!sentence) {
    alert('请输入句子!');
    return;
  }
  resetVisualization();
  recordSteps(sentence);
  renderStep(0);
});

nextBtn.addEventListener('click', () => {
  if (currentStep < steps.length - 1) {
    renderStep(currentStep + 1);
  }
});

prevBtn.addEventListener('click', () => {
  if (currentStep > 0) {
    renderStep(currentStep - 1);
  }
});
</script>

</body>
</html>
相关推荐
仿生狮子1 小时前
OpenAI 攻下千禧年难题之后,开发者似乎无动于衷
前端·数学·vibecoding
夏幻灵5 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
Lvan的前端笔记5 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
程序猿编码5 小时前
榨干 RTX5090 算力!Qwen3 专用单卡推理引擎,手写C++/CUDA 算子实现 MTP 推测解码
开发语言·c++·大模型推理·qwen3·多模态推理
三天不学习5 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194056 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
bkspiderx6 小时前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
程序员老陆6 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光7 小时前
C语言入门,深入理解指针(3)
c语言·开发语言
明月_清风7 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js