首页 > 解决方案 > 这是一个有效的 Javascript 算法来判断一个变量是否是一个素数?

问题描述

在我的网络编程课上,我们通过创建一个程序来练习一些基本的 JavaScript 技能,该程序通过提示获取用户输入,通过一些代码运行它,并判断它是否是质数。该算法的说明在这里:

  1. 开始。
  2. 显示一个提示对话框并将用户的输入存储在 UI 中。
    • 存储从提示对话框获取的 UI。
    • 将 UI 解析为 Base-10 整数并将其分配给变量 TV。
  3. 将 HITS 计数器初始化为零。
  4. 将 DD 变量初始化为 TV 的值。
  5. 当 DD 大于零时,重复以下两步:
    • 测试 TV 是否可以被 DD 整除(即 TV/DD 的余数是否为零)。如果是这样,将 HITS 增加 1。
    • 将 DD 减 1。
  6. 在浏览器文档窗口的 HTML 段落中显示结果,如示例输出中所示。
    • 字符串 UI。
    • 字符串“是”
    • 如果 HITS 大于 2,则显示字符串“not”
    • 字符串“素数”。
  7. 结尾。

我尝试遵循这些说明并提出了这个算法。

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 已经很生疏了。这个算法似乎有效吗?另外,如果可能的话,如何在每次刷新页面时触发该算法运行?

标签: javascriptalgorithm

解决方案


该代码将不起作用:它将永远循环,因为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获取用户输入并不是那么好。我怀疑在培训课上用它好不好,后来才告诉学生真的不应该用它,而是用inputbutton元素。

  • 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那么很明显该数字不是素数,因此您可以退出循环。


推荐阅读