Spaces:
Running
Running
<html lang="ja"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>数字列検索(πデータ)</title> | |
<style> | |
body { font-family: monospace; padding: 20px; } | |
#status { margin-bottom: 1em; } | |
#results { white-space: pre-wrap; } | |
</style> | |
</head> | |
<body> | |
<h1>πデータ内の数字列検索</h1> | |
<div id="status">読み込み準備中…</div> | |
<div> | |
<label>検索する数字列:<input type="text" id="query" /></label> | |
<button id="btn">検索開始</button> | |
</div> | |
<div id="results"></div> | |
<script> | |
const url = "https://ia800408.us.archive.org/16/items/Pi_500000000/Pi%20-%20Dec%20-%20Chudnovsky.txt"; | |
async function searchPi(query) { | |
const statusEl = document.getElementById("status"); | |
const resultsEl = document.getElementById("results"); | |
resultsEl.textContent = ""; | |
statusEl.textContent = "読み込み中…"; | |
const resp = await fetch(url); | |
if (!resp.body) { | |
statusEl.textContent = "Fetch API のストリーミングをサポートしていません"; | |
return; | |
} | |
const reader = resp.body.getReader(); | |
const decoder = new TextDecoder("utf-8"); | |
let chunkCount = 0; | |
let buffer = ""; | |
let fullText = ""; | |
while (true) { | |
const { done, value } = await reader.read(); | |
if (done) break; | |
chunkCount++; | |
const text = decoder.decode(value, { stream: true }); | |
fullText += text; | |
statusEl.textContent = `読み込み中…チャンク ${chunkCount}、全 ${fullText.length} 文字読み込み済み`; | |
// ※ここでは全体を保持しますが、巨大ファイルではメモリ注意 | |
} | |
statusEl.textContent = `読み込み完了。全 ${fullText.length} 文字`; | |
const q = query; | |
if (!q) { | |
resultsEl.textContent = "検索語を入力してください"; | |
return; | |
} | |
const matches = []; | |
let pos = fullText.indexOf(q, 0); | |
while (pos !== -1) { | |
matches.push(pos); | |
pos = fullText.indexOf(q, pos + 1); | |
} | |
resultsEl.textContent = `検索語 "${q}" の出現回数:${matches.length}\n\n`; | |
for (const idx of matches) { | |
const start = Math.max(0, idx - 10); | |
const end = Math.min(fullText.length, idx + q.length + 10); | |
const context = fullText.slice(start, end); | |
const before = context.slice(0, idx - start); | |
const after = context.slice(idx - start + q.length); | |
resultsEl.textContent += `${idx}文字目: …${before}[${q}]${after}…\n`; | |
} | |
} | |
document.getElementById("btn").addEventListener("click", () => { | |
const q = document.getElementById("query").value.trim(); | |
searchPi(q); | |
}); | |
</script> | |
</body> | |
</html> | |