2016-03-23 13 views
7

Sono un C++ autodidatta e il libro "Princìpi di programmazione e pratiche con C++" di Bjarne Stroustrup. Uno dei "Try This" richiede questo:Creazione di una funzione square() senza x * x in C++

Implementare square() senza utilizzare l'operatore di moltiplicazione; cioè, esegui x * x aggiungendo ripetutamente (avvia un risultato variabile a 0 e aggiungi x ad esso x volte). Quindi esegui una versione del "primo programma" usando quel quadrato().

Fondamentalmente, ho bisogno di creare una funzione square (int x) che restituisca il quadrato di esso senza utilizzare l'operatore di moltiplicazione. Finora ho questo:

int square(int x) 
{ 
    int i = 0; 
    for(int counter = 0; counter < x; ++counter) 
    { 
     i = i + x; 
    } 

return i; 
} 

Ma mi stavo chiedendo se ci fosse un modo migliore per farlo. La funzione sopra funziona, ma sono sicuro che non è il modo migliore per farlo. Qualsiasi aiuto?

+1

È possibile utilizzare turni e si preoccupano solo i bit che sono impostati a sinistra-mano-lato. Questo è il modo in cui il multiplo binario generico funziona. –

+0

http://stackoverflow.com/questions/2776211/how-can-i-multiply-and-divide-using-only-bit-shifting-and-adding Si può anche usare la funzione di libreria standard pow e il quadrato x. –

+1

Questa implementazione è chiara ed è esattamente il metodo con il quale la domanda a cui hai fatto riferimento per chiederti di farlo. "Migliore" è un termine un po 'ambiguo. – moreON

risposta

-1

In termini di corsa complessità temporale, l'implementazione è chiaro e abbastanza semplicemente, il suo tempo di esecuzione è T (n) = Θ (n) per l'ingresso n elements.Of Naturalmente è anche possibile utilizzare Divide-e -Conquer metodo, assumendo split n elementi in n/2: n/2, e infine ricorsivo calcola quindi riassume due parti, che il tempo di esecuzione sarà come T (n) = 2T (n/2) + Θ (n) = Θ (nlgn), possiamo constatare che la complessità del tempo di esecuzione peggiora rispetto all'implementazione.

+0

No, Divide-and-Conquer eseguito correttamente porta a ** T (n) = T (n/2) + Θ (1) **, molto meglio di ** Θ (n) **. –

+0

@Yves: Penso che tu abbia torto, supponendo che tu abbia diviso l'array nella dimensione media, puoi ottenere due sotto-alberi e la sua dimensione dovrebbe essere ** n/2 **, e quando ricorsivi verso le foglie, dovresti riassume ogni livello dell'albero ricorsivo che costerà ** Θ (n) ** tempo di esecuzione. Quindi, hai due sotto-alberi e attraversa ogni livello dell'albero ricorsivo per sommarlo, e quindi il tempo totale dovrebbe essere ** T (n) = 2T (n/2) + Θ (n) = Θ (nlgn) **. –

+0

Penso di avere ragione, ** n/2 = n/2 ** e non c'è bisogno di due chiamate ricorsive, e non esiste un termine ** Θ (n) **. –

4

Mats Petersson mi ha rubato l'idea prima ancora che pensassi di pensarlo.

#include <iostream> 

template <typename T> 
T square(T x) { 
    if(x < 0) x = T(0)-x; 
    T sum{0}, s{x}; 
    while(s) { 
     if(s & 1) sum += x; 
     x <<= 1; 
     s >>= 1; 
    } 
    return sum; 
} 

int main() { 
    auto sq = square(80); 
    std::cout << sq << "\n"; 
} 
+2

Probabilmente vuoi dire che gli antichi egizi hanno rubato l'idea: https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication –

+2

Da una parte erano un gruppo di cretini per rubare la mia idea, d'altra parte le loro abilità psichiche erano incredibilmente potenti , più di Mats '. Ya devi rispettarlo. –

+2

Ripensandoci, dopo aver letto completamente il link di Wikipedia, mi rendo conto che i contadini russi in effetti hanno rubato la tua idea, e loro stessi hanno ispirato gli egiziani secoli prima. –

-1

È possibile includere o <math.h><cmath> e utilizzare la funzione sqrt():

#include <iostream> 
#include <math.h> 
int square(int); 

int main() 
{ 
    int no; 
    std::cin >> no; 

    std::cout << square(no); 
    return 0; 
} 

int square(int no) 
{ 
    return pow(no, 2); 
} 
+0

Quadrato, radice non quadrata. –

+0

Sry usa la funzione pow() invece – JedaiCoder

+0

Troverete che questo è inaccurato a causa di errori di arrotondamento in virgola mobile. –

0
int square(int x) 
{ 
    int result = 0; 
    for (int counter = 0; counter < x; ++counter) result += x; 
    return result; 
} 
Problemi correlati