javascript - 这是一个有效的 Javascript 算法来判断一个变量是否是一个素数?
问题描述
在我的网络编程课上,我们通过创建一个程序来练习一些基本的 JavaScript 技能,该程序通过提示获取用户输入,通过一些代码运行它,并判断它是否是质数。该算法的说明在这里:
- 开始。
- 显示一个提示对话框并将用户的输入存储在 UI 中。
- 存储从提示对话框获取的 UI。
- 将 UI 解析为 Base-10 整数并将其分配给变量 TV。
- 将 HITS 计数器初始化为零。
- 将 DD 变量初始化为 TV 的值。
- 当 DD 大于零时,重复以下两步:
- 测试 TV 是否可以被 DD 整除(即 TV/DD 的余数是否为零)。如果是这样,将 HITS 增加 1。
- 将 DD 减 1。
- 在浏览器文档窗口的 HTML 段落中显示结果,如示例输出中所示。
- 字符串 UI。
- 字符串“是”
- 如果 HITS 大于 2,则显示字符串“not”
- 字符串“素数”。
- 结尾。
我尝试遵循这些说明并提出了这个算法。
function checkPrime() {
var HITS = 0; // Quantity of successful integer divisions.
var UI = prompt("Please enter a whole number to test as a prime number."); // Prompts the user to enter a number to test, stored in User Input;
var TV = parseInt(UI,10); // Parses the string to int, stores it in Test Variable
var DD = TV; // Sets Division Denominator to the Test Variable
while (DD > 0) {
if (TV % DD == 0) {
HITS = HITS++;
} else {
DD = DD--;
}
if (HITS > 2 || TV == 1 ) {
document.getElementById('demo').innerHTML = UI + "is not a prime number.";
} else {
document.getElementById('demo').innerHTML = UI + "is a prime number.";
}
}
}
自从我开始我的 C++ 课程以来,我的 JavaScript 已经很生疏了。这个算法似乎有效吗?另外,如果可能的话,如何在每次刷新页面时触发该算法运行?
解决方案
该代码将不起作用:它将永远循环,因为DD
永远不会递减。这是因为几个原因:
的减量
DD
应该总是发生,不仅当TV
可被 整除DD
,所以你的代码不应该有else
.您可能认为
DD
在每次迭代中都为它分配了一个新值,因为代码的缩进是错误的(事实上,HTML 的输出发生在每次迭代中,由于这种误导性缩进很难发现)。即使
DD
赋值已经被执行,它实际上并没有改变任何东西,因为D--
和赋值的奇怪组合。D--
将评估为D
,并且在该评估之后发生递减,但由于评估的值被分配回D
,因此该递减被撤消。同样的问题发生在HITS
. 你应该做D--;
和HITS++;
也许您没有提供完整的解决方案,但您应该在某处调用您的函数。这可以是函数下方的普通调用,也可以是 HTML 页面上的一个按钮,该按钮具有将调用它的单击处理程序。
这是使代码与说明保持一致的更正:
function checkPrime() {
var HITS = 0; // Quantity of successful integer divisions.
var UI = prompt("Please enter a whole number to test as a prime number."); // Prompts the user to enter a number to test, stored in User Input;
var TV = parseInt(UI,10); // Parses the string to int, stores it in Test Variable
var DD = TV; // Sets Division Denominator to the Test Variable
while (DD > 0) {
if (TV % DD == 0) {
HITS++;
}
DD--;
}
document.getElementById('demo').textContent = UI + " is ";
if (HITS > 2) {
document.getElementById('demo').textContent += "not ";
}
document.getElementById('demo').textContent += "a prime number.";
}
checkPrime();
<p id="demo"></p>
其他的建议
与您的问题无关,但还有其他一些关于作业的评论:
所描述的算法有一个问题,显然您已检测到,因为您已在条件中添加了
TV == 1
测试。if
“ 如果 HITS 大于 2”测试不能正确识别 1 不是素数。我实际上认为意图是“如果 HITS不同于2”。在这种情况下,1 将被正确识别为不是素数,因为每个素数都有 2 个不同的除数(它本身和 1)。在 camelCase 中命名变量是一种常见的做法。所有大写字母通常保留给常量。
变量名称应该是描述性的。2 个字母的缩写不是一个好的做法。此规则有一些例外:单字母变量通常用于循环变量(如
i
),但这不是您的情况。innerHTML
当您实际拥有 HTML 编码的内容时,应保留分配给该属性,但对于纯文本(您的情况),您应该真正分配给该textContent
属性。用于
prompt
获取用户输入并不是那么好。我怀疑在培训课上用它好不好,后来才告诉学生真的不应该用它,而是用input
和button
元素。parseInt
不是很好,因为当输入为“13o”时它实际上会返回 13。使用一元+
或Number
函数是将输入转换为数字的更好方法。JavaScript(和其他语言)有
for
你需要用DD
. 它可以取代你的while
循环。确实应该检查输入是否可以转换为数字,如果没有,则应该向用户发送一些消息。
拥有一个同时处理业务逻辑(主要检查)和输入/输出问题的函数并不是一个好习惯。这些最好分开。
这是一个考虑到这一点的版本,但它(必然)不会遵循所有说明:
function checkPrime(testNumber) {
let hits = 0;
for (let denominator = testNumber; denominator > 0; denominator--) {
if (testNumber % denominator == 0) {
hits++;
}
}
return hits == 2; // a prime number has EXACTLY 2 divisors
}
const buttonCheck = document.getElementById('check');
const inputElement = document.getElementById('input');
const outputParagraph = document.getElementById('demo');
function handleClick() {
const userInput = inputElement.value;
const testNumber = +userInput;
if (Number.isNaN(testNumber)) {
outputParagraph.textContent = "This is not a valid number.";
} else if (checkPrime(testNumber)) {
outputParagraph.textContent = testNumber + " is prime.";
} else {
outputParagraph.textContent = testNumber + " is not prime.";
}
}
buttonCheck.addEventListener("click", handleClick);
Please enter a whole number to test as a prime number: <input id="input"><button id="check">Check</button><br>
<p id="demo"></p>
有更好、更有效的方法来进行质数检查。一个简单的改进是从denominator
存在开始inputNumber-1
并提前一步退出循环,即当denominator
不大于 1 时。这样你就排除了每个数字所具有的两个除数——没有必要对它们进行测试。如果通过这种改进,您的代码仍然找到一个均分的除数,inputNumber
那么很明显该数字不是素数,因此您可以退出循环。
推荐阅读
- powershell - 如何在 PowerShell 中修复 DLL LoaderExceptions
- excel - 用户表单日期格式文本框
- java - 为 XNAT 导入 Gradle 项目的问题 - 未解决的类型
- r - 使用 ggplot2 对象和自定义字体从终端运行 R 脚本(字体类型无效)
- python - 实现metropolis-hasting算法
- java - 获取一个空的 json 实体并且不能使用 Spring Boot 在运行时持久化
- c - Memcpy char** 的 typedef,它指向具有 4 个 uint64_t 类型变量的结构
- python - Ansible/molecule:服务 docker 守护进程/引擎不会启动
- arrays - 从命令行读取值到数组
- html - 为什么在引导程序中我的手风琴菜单旁边有一个空矩形?