Untitled
unknown
plain_text
a year ago
5.5 kB
8
Indexable
Aby stworzyć kalkulator, który obsługuje kilka operacji na raz w czystym JavaScript, bez użycia eval(), możesz zaimplementować własny parser wyrażeń matematycznych. Podejście to polega na podzieleniu wyrażenia na liczby i operatory, a następnie zastosowaniu reguł priorytetów matematycznych (nawiasy, mnożenie, dzielenie, dodawanie, odejmowanie).
Poniżej znajdziesz przykład prostego kalkulatora w czystym JavaScript, który obsługuje podstawowe operacje arytmetyczne z poprawnym uwzględnieniem priorytetów działań.
Kalkulator obsługujący kilka operacji:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kalkulator z obsługą wielu operacji</title>
</head>
<body>
<h2>Kalkulator</h2>
<label for="expression">Wpisz wyrażenie (np. 3 + 5 * 2 - 4 / 2): </label>
<input type="text" id="expression" placeholder="Np. 3 + 5 * 2 - 4 / 2"><br><br>
<button onclick="calculate()">Oblicz</button>
<h3>Wynik: <span id="result"></span></h3>
<script>
function calculate() {
const expression = document.getElementById("expression").value;
try {
const result = evaluateExpression(expression);
document.getElementById("result").textContent = result;
} catch (error) {
document.getElementById("result").textContent = "Błąd w wyrażeniu!";
}
}
function evaluateExpression(expression) {
// Usuwamy białe znaki
expression = expression.replace(/\s+/g, '');
// Rozwiążemy działania w nawiasach (rekurencyjnie)
while (expression.includes('(')) {
expression = expression.replace(/([^()]+)/g, function(match, subExpr) {
return evaluateSimpleExpression(subExpr);
});
}
// Rozwiązujemy pozostałe działania bez nawiasów
return evaluateSimpleExpression(expression);
}
function evaluateSimpleExpression(expression) {
// Rozwiązujemy mnożenie i dzielenie jako pierwsze
let numbers = expression.split(/([+\-])/); // Rozdzielamy liczby od operatorów dodawania/odejmowania
for (let i = 0; i < numbers.length; i++) {
if (numbers[i].includes('*') || numbers[i].includes('/')) {
let subExpression = numbers[i].split(/([*/])/); // Rozdzielamy liczby od operatorów mnożenia/dzielenia
let result = parseFloat(subExpression[0]);
for (let j = 1; j < subExpression.length; j += 2) {
let operator = subExpression[j];
let nextNumber = parseFloat(subExpression[j + 1]);
if (operator === '*') {
result *= nextNumber;
} else if (operator === '/') {
if (nextNumber === 0) throw new Error("Dzielenie przez zero");
result /= nextNumber;
}
}
numbers[i] = result.toString(); // Zastępujemy wynik w tablicy
}
}
// Teraz rozwiążemy dodawanie i odejmowanie
let result = parseFloat(numbers[0]);
for (let i = 1; i < numbers.length; i += 2) {
let operator = numbers[i];
let nextNumber = parseFloat(numbers[i + 1]);
if (operator === '+') {
result += nextNumber;
} else if (operator === '-') {
result -= nextNumber;
}
}
return result;
}
</script>
</body>
</html>
Jak to działa:
1. Wprowadzanie wyrażenia: Użytkownik wprowadza matematyczne wyrażenie (np. "3 + 5 * 2 - 4 / 2").
2. Usuwanie białych znaków: Metoda replace(/\s+/g, '') usuwa wszystkie spacje, aby uprościć analizowanie wyrażenia.
3. Nawiasy: Wyrażenia w nawiasach są rozwiązywane jako pierwsze przy użyciu rekurencji. Dla każdego fragmentu wyrażenia wewnątrz nawiasów wywołujemy ponownie funkcję evaluateSimpleExpression().
4. Rozwiązywanie operacji:
Mnożenie i dzielenie: Najpierw przetwarzamy operacje mnożenia i dzielenia. Każdy fragment wyrażenia zawierający te operatory jest rozdzielany i obliczany, a wynik jest zastępowany w tablicy.
Dodawanie i odejmowanie: Po przetworzeniu mnożenia i dzielenia, przystępujemy do operacji dodawania i odejmowania.
5. Obsługa błędów: Jeśli w trakcie obliczeń napotkamy błędy (np. dzielenie przez zero), zostanie wyświetlony komunikat o błędzie.
Przykłady:
Wejście: "3 + 5 * 2 - 4 / 2"
Wynik: 10
Wejście: "10 + 2 * (5 - 3)"
Wynik: 14
Wejście: "(2 + 3) * 5"
Wynik: 25
Jak działa parser:
1. Podział wyrażenia: Wyrażenie jest dzielone na podstawie operatorów, przy czym priorytet ma mnożenie i dzielenie.
2. Obliczenia krok po kroku: Najpierw wykonujemy operacje o wyższym priorytecie (mnożenie i dzielenie), a następnie przechodzimy do dodawania i odejmowania.
3. Obsługa nawiasów: Jeśli wyrażenie zawiera nawiasy, są one przetwarzane w pierwszej kolejności.
To podejście jest bezpieczniejsze niż użycie eval(), ponieważ analizuje wyrażenie krok po kroku bez wykonywania potencjalnie niebezpiecznego kodu.
Editor is loading...
Leave a Comment