为什么在 React 的排列计算器上得到荒谬的结果?
Why getting absurd result on Permutation caluclator in React?
我有一个用于计算排列的计算器:
当 r 的值超过 n.When r 小于或等于 n 时,它会显示一条警告消息,它应该给出准确的 result.But 它的行为是荒谬的。
我写的 React.js 中相同的代码:
const PnC = () => {
const [n, setN] = useState(null);
const [r, setR] = useState(null);
const [choice, setChoice] = useState("Permutation");
const [choiceData, setChoiceData] = useState({
name: "Permutation",
});
const [result, setResult] = useState(null);
useEffect(() => {
if (choice == "Permutation")
setChoiceData({ name:"Permutation" });
else
setChoiceData({ name:"Combination" });
}, [choice]);
const handleChange = (e) => {
reset();
setChoice(e.target.value);
}
function reset() {
setN(null);
setR(null);
setResult(null);
}
function factorial(x){
var result = 1;
for (let i = 1; i <= x; i++)
result *= i;
return result;
}
const calcResult = () => {
console.log(n,r);
if (choice == "Permutation") {
if (n < r)
alert("The value of n should not be less than r.Please enter valid values for n and r");
else
setResult(factorial(n) / factorial(n - r));
}
else if(choice=="Combination"){
if (n < r)
alert("The value of n should not be less than r.Please enter valid values for n and r");
else
setResult(factorial(n) / (factorial(r) * factorial(n - r)));
}
}
return (
<>
<Form>
<Form.Group className="mb-4" controlId="choice">
<Form.Label>Select the type of calculation</Form.Label>
<Form.Control
as="select"
className="select-custom-res"
onChange={(e) => handleChange(e)}
>
<option value="Permutation">Permutation</option>
<option value="Combination">Combination</option>
</Form.Control>
</Form.Group>
<Form.Group className="mb-4" controlId="text">
<Form.Text className="text">
<strong>
To find the {choiceData.name}, Enter the following values
</strong>
<br />
</Form.Text>
</Form.Group>
<Form.Group className="mb-4">
<Form.Label>Value of N</Form.Label>
<Form.Control
onChange={(e) => setN(e.target.value)}
type="number"
placeholder={"Enter the value of n"}
value={n === null ? "" : n}
/>
</Form.Group>
<Form.Group className="mb-4">
<Form.Label>Value of R</Form.Label>
<Form.Control
onChange={(e) => setR(e.target.value)}
type="number"
placeholder={"Enter the value of r"}
value={r === null ? "" : r}
/>
</Form.Group>
<Form.Group className="mb-4">
<Form.Control
readOnly
type="number"
placeholder={result === null ? "Result" : result + " "}
/>
</Form.Group>
</Form>
<div className="button-custom-grp">
<Button variant="primary" onClick={calcResult}>
Calculate
</Button>
<Button variant="dark" onClick={() => reset()} type="reset">
Reset
</Button>
</div>
</>
)
}
对于像 n=8,r=2
这样的值,我得到了预期的结果,但是对于像 n=13,r=2
这样的值,我得到了我的自定义警报消息 The value of n should not be less than r. Please enter valid values for n and r
。组合计算器也是如此。为什么我会得到如此荒谬的结果?
问题
n
和r
从输入更新后的类型是字符串类型,不是数字。在您尝试与它们进行数值比较之前,这不是问题。
if (n < r)
此时是字符串比较position-by-position。
console.log('"8" < "2"', "8" < "2"); // false
console.log('"13" < "2"', "13" < "2"); // true
"1"
字符代码小于 "2"
,因此比较 "13" < "2"
的计算结果为真。
解决方案
更新状态时将n
和r
转换为数字类型。
<Form.Group className="mb-4">
<Form.Label>Value of N</Form.Label>
<Form.Control
onChange={(e) => setN(Number(e.target.value))} // <-- convert to number
type="number"
placeholder={"Enter the value of n"}
value={n === null ? "" : n}
/>
</Form.Group>
<Form.Group className="mb-4">
<Form.Label>Value of R</Form.Label>
<Form.Control
onChange={(e) => setR(Number(e.target.value))} // <-- convert to number
type="number"
placeholder={"Enter the value of r"}
value={r === null ? "" : r}
/>
</Form.Group>
我有一个用于计算排列的计算器: 当 r 的值超过 n.When r 小于或等于 n 时,它会显示一条警告消息,它应该给出准确的 result.But 它的行为是荒谬的。 我写的 React.js 中相同的代码:
const PnC = () => {
const [n, setN] = useState(null);
const [r, setR] = useState(null);
const [choice, setChoice] = useState("Permutation");
const [choiceData, setChoiceData] = useState({
name: "Permutation",
});
const [result, setResult] = useState(null);
useEffect(() => {
if (choice == "Permutation")
setChoiceData({ name:"Permutation" });
else
setChoiceData({ name:"Combination" });
}, [choice]);
const handleChange = (e) => {
reset();
setChoice(e.target.value);
}
function reset() {
setN(null);
setR(null);
setResult(null);
}
function factorial(x){
var result = 1;
for (let i = 1; i <= x; i++)
result *= i;
return result;
}
const calcResult = () => {
console.log(n,r);
if (choice == "Permutation") {
if (n < r)
alert("The value of n should not be less than r.Please enter valid values for n and r");
else
setResult(factorial(n) / factorial(n - r));
}
else if(choice=="Combination"){
if (n < r)
alert("The value of n should not be less than r.Please enter valid values for n and r");
else
setResult(factorial(n) / (factorial(r) * factorial(n - r)));
}
}
return (
<>
<Form>
<Form.Group className="mb-4" controlId="choice">
<Form.Label>Select the type of calculation</Form.Label>
<Form.Control
as="select"
className="select-custom-res"
onChange={(e) => handleChange(e)}
>
<option value="Permutation">Permutation</option>
<option value="Combination">Combination</option>
</Form.Control>
</Form.Group>
<Form.Group className="mb-4" controlId="text">
<Form.Text className="text">
<strong>
To find the {choiceData.name}, Enter the following values
</strong>
<br />
</Form.Text>
</Form.Group>
<Form.Group className="mb-4">
<Form.Label>Value of N</Form.Label>
<Form.Control
onChange={(e) => setN(e.target.value)}
type="number"
placeholder={"Enter the value of n"}
value={n === null ? "" : n}
/>
</Form.Group>
<Form.Group className="mb-4">
<Form.Label>Value of R</Form.Label>
<Form.Control
onChange={(e) => setR(e.target.value)}
type="number"
placeholder={"Enter the value of r"}
value={r === null ? "" : r}
/>
</Form.Group>
<Form.Group className="mb-4">
<Form.Control
readOnly
type="number"
placeholder={result === null ? "Result" : result + " "}
/>
</Form.Group>
</Form>
<div className="button-custom-grp">
<Button variant="primary" onClick={calcResult}>
Calculate
</Button>
<Button variant="dark" onClick={() => reset()} type="reset">
Reset
</Button>
</div>
</>
)
}
对于像 n=8,r=2
这样的值,我得到了预期的结果,但是对于像 n=13,r=2
这样的值,我得到了我的自定义警报消息 The value of n should not be less than r. Please enter valid values for n and r
。组合计算器也是如此。为什么我会得到如此荒谬的结果?
问题
n
和r
从输入更新后的类型是字符串类型,不是数字。在您尝试与它们进行数值比较之前,这不是问题。
if (n < r)
此时是字符串比较position-by-position。
console.log('"8" < "2"', "8" < "2"); // false
console.log('"13" < "2"', "13" < "2"); // true
"1"
字符代码小于 "2"
,因此比较 "13" < "2"
的计算结果为真。
解决方案
更新状态时将n
和r
转换为数字类型。
<Form.Group className="mb-4">
<Form.Label>Value of N</Form.Label>
<Form.Control
onChange={(e) => setN(Number(e.target.value))} // <-- convert to number
type="number"
placeholder={"Enter the value of n"}
value={n === null ? "" : n}
/>
</Form.Group>
<Form.Group className="mb-4">
<Form.Label>Value of R</Form.Label>
<Form.Control
onChange={(e) => setR(Number(e.target.value))} // <-- convert to number
type="number"
placeholder={"Enter the value of r"}
value={r === null ? "" : r}
/>
</Form.Group>