Utilizzo di un'equazione definita dall'utente per calcolare un intero elenco di numeri e memorizzare l'elenco in una matrice

2

Un esempio di ciò che voglio fare:

L'utente mette i numeri in un elenco su una GUI simile a questa

 | L1 | L2 | l3 |
 ----------------
 | 3  |  6 |    |
 | 5  |  3 |    |
  ...

Scrive in un'area di testo un'equazione come questa; L1 + L2 [STO >] L3 e hits calcolano e aggiorna l'elenco a questo

 | L1 | L2 | L3 |
 ----------------
 | 3  |  6 |  9 |
 | 5  |  3 |  8 |

Nella riga uno, 3 + 6 = 9, quindi la riga corrispondente dei numeri corrisponde alla casella, la riga corrispondente nell'elenco 3 viene aggiornata. Ne abbiamo selezionato una lista digitando L1, e abbiamo usato un opperator del negozio ([STO >]) per memorizzare i numeri nella lista 3. Non è una novità, ho trovato questa idea su ti-83, ti-84 e programmi stat che usa questo.

All'inizio sembrava semplice; Potrei risolverlo conoscendo l'equazione in anticipo con un semplice algoritmo. Ad esempio, con un'equazione come L1 + L2 [STO >] L3 I potrebbe eseguire il ciclo attraverso l'array 2d utilizzando il valore di indice e memorizzare i numeri in una matrice per elaborare i numeri da lì. Per illustrare ho scritto un semplice snippet di codice

for(int i = 0; i <= 100; i++) {
    data[i][0] + data[i][1] = data[i][2];
}
//Then update GUI

//So the data array was how I store user data from the gui, 
//index 1 grabs the value from the row and index 2 is the corresponding list item.

Il problema:

Non so come procedere quando non conosco l'equazione definita dall'utente. L'utente dovrebbe essere in grado di inserire tutto ciò che è possibile inserire in una calcolatrice. Ad esempio, gli ingressi validi potrebbero anche essere L1 * 3455 [STO >] L2, L1 / L2 [STO >] L3 ect.

    
posta user275564 03.12.2015 - 01:09
fonte

2 risposte

3

Hai due opzioni.

Opzione 1: scrivi il tuo parser. Inizia leggendo su "albero di analisi" e "parser di discesa ricorsivo". Quindi, l'utente inserisce l'espressione come testo in qualunque sintassi si decida, si analizza il testo, si costruisce un albero di espressioni, alcuni dei nodi dell'albero saranno identificativi di riga, alcuni saranno costanti, alcuni saranno operatori, si sostituirà identificatori con valori, eseguire l'albero per valutare gli operatori, si riceve un risultato. Non è facile, ma non è nemmeno scienza missilistica.

Opzione 2: incorpora un motore javascript come Rhino nella tua applicazione java. Ancora una volta, l'utente inserisce un'espressione come testo nella sintassi javascript, il motore javascript lo analizza, tu fornisci al motore un valore per ogni variabile, esegui il motore per valutare l'espressione, ottieni un risultato. Non è nemmeno facile, ma è molto più probabile trovare tutorial che faranno la maggior parte del lavoro per te. Non puoi scegliere la sintassi delle espressioni, ma se confronto la sintassi javascript con la cosa strana che hai descritto sopra, penso che sia una buona cosa che tu non possa scegliere la sintassi.

    
risposta data 03.12.2015 - 02:11
fonte
0

Ho deciso di risolvere questo problema prendendo l'equazione e valutandola in PostFix, quindi valutando l'espressione post-correzione. Questa è la mia implementazione in C ++.

string convertToPostfix(string& infix)
{
std::stack<char> stack;
string output;

infix.erase(std::remove(infix.begin(), infix.end(), ' '), infix.end());

for (size_t i = 0; i < infix.size(); i++) {
    if (isdigit(infix[i])) {
        if (i >= 1 && !(isdigit(infix[i - 1])))
            output.push_back(' ');

        output.push_back(infix[i]);
    }
    else if (infix[i] == '(') {
        stack.push(infix[i]);
    }
    else if (isOperator(infix[i])) {

        while ((!stack.empty()) && stack.top() != '(') {
            if (precedence(stack.top(), infix[i])) {
                output.push_back(' ');
                output.push_back(stack.top());
                stack.pop();
            }
            else {
                break;
            }
        }

        stack.push(infix[i]);
    }
    else if (infix[i] == ')') {
        while (!stack.empty() && (stack.top() != '(')) {
            output.push_back(' ');
            output.push_back(stack.top());
            stack.pop();
        }

        if (!stack.empty()) {
            stack.pop();
        }
    }
}
while (!stack.empty()) {
    output.push_back(' ');
    output.push_back(stack.top());
    stack.pop();
}

return output;
}

int evaluatePostFix(string postfix) {
stack<int> resultStack;

int length = postfix.length();

int accumlatedMultipleDigits = 0;

for (int i = 0; i < length; i++) {

    if (isOperator(postfix[i])) {
        int first = resultStack.top();
        resultStack.pop();
        int second = resultStack.top();
        resultStack.pop();

        int result = applyOperator(first, second, postfix[i]);
        resultStack.push(result);
    }
    else if ((postfix[i] >= '0') || (postfix[i] <= '9') && !postfix[i] == ' ') {

        int postfixValue = postfix[i] - 48;

        if (i >= 1) {
            if (postfix[i - 1] == ' ') {

                /* FIRST VALUE */

                accumlatedMultipleDigits = postfixValue;
            }
            else {
                //add new value to end of accumlatedMultipleDigits
                accumlatedMultipleDigits = accumlatedMultipleDigits * 10 + postfixValue;
            }
        }
        else { /*It is 0 or less index of string, means must be value */
            accumlatedMultipleDigits = postfixValue;
        }

        if (postfix.length() > i) {

            if (postfix[i + 1] == ' ') {/* END OF VALUE*/
                resultStack.push(accumlatedMultipleDigits);
                accumlatedMultipleDigits = 0;
            }
        }

    }
}
return resultStack.top();
}

Con questo possiamo risolvere questo problema linea per linea e archiviare nella riga corrispondente corretta.

    
risposta data 31.01.2017 - 20:27
fonte

Leggi altre domande sui tag