Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

MEILLEURE MÉTHODE POUR CALCULER UN PUISSANCE


Information sur la source

Catégorie :Astuces Classé sous : exponentiation, extra, rapide Niveau : Initié Date de création : 19/11/2007 Date de mise à jour : 19/11/2007 18:44:46 Vu : 4 370

Note :
Aucune note

Commentaire sur cette source (7)
Ajouter un commentaire et/ou une note


Description

la méthode la plus naive pour calculer par ex:
x^15 = x*...*x(14 operations)
----------
mieux:
x * x = x2
x2 * x2 = x4
x4 * x4 = x8
x4 * x8 = x12
x12 * x2 = x14
x14 * x = x15(6 operations)
----------
n × n = n2
n2 × n = n3
n3 × n3 = n6
n6 × n6 = n12
n12 × n3 = n15
(5 operations)
ce programme donne les enchainements possible pour la plus rapide
méthode de calculer la puissance :)

 

Source

  • #include<iostream>
  • #include<set>
  • #include<queue>
  • #include<vector>
  • #define MAX 200
  • using namespace std;
  • int operations[MAX + 1] = {0};
  • // A tree struct
  • struct Tree
  • {
  • int Key, Level;
  • Tree * Parent;
  • vector<Tree* > children;
  • Tree(int Key, Tree* Parent)
  • {
  • this->Key = Key;
  • this->Parent = Parent;
  • if(Parent != NULL)
  • this->Level = Parent->Level + 1;
  • else
  • this->Level = 0;
  • }
  • };
  • // testing if all nodes are all computed
  • bool AllComputed()
  • {
  • for(int k = 1;k <= MAX;k++)
  • if(!operations[k])
  • return false;
  • return true;
  • }
  • // building tree with a given node and a range limit
  • void stacking(int n,Tree * T)
  • {
  • queue<Tree*> Q;
  • // using algorithm to parse a tree by levels
  • Q.push(T);
  • while (!Q.empty() && !AllComputed())
  • {
  • Tree * X = Q.front();
  • Q.pop();
  • Tree * Iterator = X;
  • int Value = X->Key;
  • //process node X
  • while(Iterator != NULL)
  • {
  • int TmpValue = Iterator->Key + Value;
  • if((!operations[TmpValue]|| operations[TmpValue]
  • == X->Level + 1)&& TmpValue <= n)
  • {
  • operations[TmpValue] = X->Level + 1;
  • (X->children).push_back(new Tree(TmpValue,X));
  • }
  • Iterator = Iterator->Parent;
  • }
  • int L = (int)(X->children).size();
  • for (int i = 0;i < L;++i)
  • {
  • Q.push((X->children)[i]);
  • }
  • }
  • }
  • void search(int k,Tree * T)
  • {
  • if(T->Key == k)
  • {
  • Tree * Iter = T;
  • set<int> S;
  • while (T != NULL)
  • {
  • S.insert(T->Key);
  • T = T->Parent;
  • }
  • for(set<int>::iterator iter = S.begin();;)
  • {
  • cout << *iter;
  • ++iter;
  • if(iter != S.end())
  • cout << "->";
  • else
  • {
  • cout << endl;
  • break;
  • }
  • }
  • }
  • else
  • {
  • vector<Tree *> v = T->children;
  • int L = (int)v.size();
  • for(int i = 0;i < L;++i)
  • search(k,v[i]);
  • }
  • }
  • int main()
  • {
  • Tree * T = new Tree(1,NULL);
  • stacking(MAX,T);
  • int key;
  • cout << "if you want to know how to obtain minimum number of operations :" << endl;
  • cout << "enter a positive number or (0) to quit" << endl;
  • cin >> key;
  • while(key)
  • {
  • cout << operations[key] << endl;
  • search(key,T);
  • cin >> key;
  • }
  • return 0;
  • }
#include<iostream>
#include<set>
#include<queue>
#include<vector>
#define MAX 200
using namespace std;

int operations[MAX + 1] = {0};

// A tree struct
struct Tree
{
	int Key, Level;
	Tree * Parent;
	vector<Tree* > children;
	Tree(int Key, Tree* Parent)
	{
		this->Key = Key;
		this->Parent = Parent;
		if(Parent != NULL)
			this->Level = Parent->Level + 1;
		else
			this->Level = 0;	

	}
};
// testing if all nodes are all computed
bool AllComputed()
{
	for(int k = 1;k <= MAX;k++)
		if(!operations[k])
			return false;
	return true;
}
// building tree with a given node and a range limit
void stacking(int n,Tree * T)
{
	queue<Tree*> Q;
	// using algorithm to parse a tree by levels
	Q.push(T);
	while (!Q.empty() && !AllComputed())
	{
		Tree * X = Q.front();
		Q.pop();
		Tree * Iterator = X;
		int Value = X->Key;
		//process node X
		while(Iterator != NULL)
		{
			int TmpValue = Iterator->Key + Value;
			if((!operations[TmpValue]|| operations[TmpValue] 
			== X->Level + 1)&& TmpValue <= n)
			{
				operations[TmpValue] = X->Level + 1;
				(X->children).push_back(new Tree(TmpValue,X));

			}
			Iterator = Iterator->Parent;
		}
		int L = (int)(X->children).size();
		for (int i = 0;i < L;++i)
		{
			Q.push((X->children)[i]);
		}

	}
}

void search(int k,Tree * T)
{
	if(T->Key == k)
	{
		Tree * Iter = T;
		set<int> S;
		while (T != NULL)
		{
			S.insert(T->Key);
			T = T->Parent;
		}
		for(set<int>::iterator iter = S.begin();;)
		{
			cout << *iter;
			++iter;
			if(iter != S.end())
				cout << "->";
			else
			{
				cout << endl;
				break;
			}

		}
	}
	else
	{
		vector<Tree *> v = T->children;
		int L = (int)v.size();
		for(int i = 0;i < L;++i)
			search(k,v[i]);

	}
}

int main()
{
	Tree * T = new Tree(1,NULL);
	stacking(MAX,T);

	int key;
	cout << "if you want to know how to obtain minimum number of operations :" << endl;
	cout << "enter a positive number or (0) to quit" << endl;

	cin >> key;
	while(key)
	{
		cout << operations[key] << endl;
		search(key,T);
		cin >> key;
	}

	return 0;
}

Historique

19 novembre 2007 18:44:46 :
prochainement mise à jour

Commentaires et avis

signaler à un administrateur
Commentaire de Cyberboy2054 le 19/11/2007 20:39:03

Rigolo, mais au final tu ne fais pas beaucoup plus d'opérations que ce qu'il y avait au départ ? :p
(oui je sais c'etait pas le but du programme)
Juste une question, c'est une recherche en largeur ou en profondeur que tu fais ? j'ai jamais trop saisi la différence en fait.
La ce que je vois, c'est que tu prends toutes les feuilles de ton arbre, et que tu en génère les successeurs (en virant les cas incompatibles/ceux qui ne resoudront jamais le probleme). Donc je dirais en profondeur. La largeur ce serait générer tous les successeurs d'un 'etage' en quelque sorte, puis pour tous les successeurs ainsi que ceux apparus générer les successeurs ...
Concrètement, quelle est la différence entre les 2 algorithmes ? (en termes de temps et de mémoire)

signaler à un administrateur
Commentaire de acx01b le 20/11/2007 12:32:56

salut je n'ai pas vraiment regardé ton code mais qu'est-ce qui te dérange dans un code de ce type ???

#define SUPERPRINTF(X) printf(#X "= %d\n", X)

int puis(int a, unsigned int b) {
int l,i,x,r;
l = sizeof(unsigned int)*8-1;
while(!(b & (1<<l)) && l >= 0) l--;
x = a;
r = 1;
for (i = 0; i <= l; i++) {
if (b & (1<<i)) r *= x;
x *= x;
}
return r;
}

int main() {
SUPERPRINTF(puis(2,13));
}

signaler à un administrateur
Commentaire de elkasimi2007 le 20/11/2007 12:48:32

salut,
d'abord on fait une recherche en profondeur pour trouver
toutes les operations minimum
ensuite on cherche à trouver la suite des multiplication
possible on fait une recherche en largeur car le nombre de
multiplication augmente de niveau en niveau.

Pour ACX01B je n'ai pas bien saisi ce que tu veut dire : tu veux dire que je dois utiliser des fonctions au lieu de blocs d'instructions ou que j'utilise des instructions complexe pour rien faire??

signaler à un administrateur
Commentaire de acx01b le 20/11/2007 13:32:21

salut

ce que j'ai mis comme code c'est le code utilisé habituellement pour calculer une puissance entière

pour x^15 il fait

x2 = x*x
r = x*x2
x4 = x2*x2
r = r * x4
x8 = x4*x4
r = r * x8
--> 6 opérations, mais il n'utilise que 2 temporaires et là il y a une différence je pense, donc pourquoi ta façon est-elle meilleure (c'est ça que je n'ai pas étudié comme problème mais je suppose que toi oui) ?

signaler à un administrateur
Commentaire de elkasimi2007 le 20/11/2007 14:46:43

salut
généralement ma méthode est utilisé pour un operateur
* qlq par exemple:
object X;
étant donné operateur * assez compliqué, on s'interressera
plutot à minimiser le nombre d'appel à l'operateur que minimiser le nombre de cases mémoire alouées.
c'est vrai pour le cas d'un operateur simple * pour les entiers ça parait inutile.

excuse moi,car j'ai pas eu le temps de déchiffrer les
<< ,le sizeof et les ! pour comprendre le but de ton code :)

signaler à un administrateur
Commentaire de vecchio56 le 20/11/2007 23:14:37 administrateur CS

Ce qui est intéressant c'est de savoir laquelle de ces solutions est la plus rapide
- Méthode naive
- Méthode un peu meilleure
- Recherche de la meilleure méthode et application de cette méthode

Tu as une idée?

signaler à un administrateur
Commentaire de Gwaihir le 15/02/2008 19:08:48

Sa doit être possible de chronométrer nan ?
on peut chronométrer les threads ?

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Envoi rapide port série [ par spiritualys ] Hello,J'ai besoin d'aide : je dois envoyer des messages sur un port série avec un temps bien précis (inférieur à 6 ms). Les commandes existantes en C Turoriel Visual C++ pour extra débutant ;-) [ par 187bundy ] Salut à tous !J'ai pas mal programmé en C et C++ sous DOS avec un compilateur borland cpp, mais j'ai arrêté depuis longtemps, et me voila maintenant a tri rapide(quicksort)+tri par tas(heapsort)+simulation graphique [ par mersniyassine ] mon stage d'ete comporte une simulation graphique du tri par tas et du tri rapide, je trouve une difficulté a gerer le code source,merci bien de me fo Evenement trop rapide [ par larion ] Bonjour,Imaginons que nous avons 2 événements, pour exemple :evenement1: WM_LBUTTONDOWN --&gt; Action1evenement2: WM_LBUTTONUP --&gt; Action2S tri rapide (quicksort) et/ou tri par tas(heapsort) urgent [ par mersniyassine ] je trouve une difficulté a simuler graphiquement en C ces 2 trisya t-il quelqu'un qui peut me fournir un code.c compilable sur Turbo C qui effectue u topo rapide du C++ [ par ::seth ] Bonjour je suis actuellement developpeur en php, flash et j'aimerai me mettre au C cependant j'ai une vision assez flou de ce qu'on peut faire avec a affichage trop rapide [ par malik7934 ] Hello,J'ai un prog qui affiche dans une editbox les calculs qu'il fait (verbose). J'emploie la méthode suivante: strcat((char*)verboseText,"TEXTE A A gestion clavier SDL trop rapide !!! [ par _Jonathan ] bonjour a tousj'ai créé un programme avec sdl/opengl mais la gestion du clavier(sdl) est beaucoup tro rapide.j'ai pourtant essayé avec SDL_KEYUP, mais Liste plus rapide que vertex array [ par goutbouyo ] Salut,Dans mon jeu opengl, au début j'utilisait une liste d'affichage.J'ai voulut améliorer les performances du jeu et j'ai donc remplacer la liste pa a l'aide (rapide) [ par alphaone ] j'ai une function qui remplace dans une chaine de caractere un mot par un autre.je voudrai, que quelqu'un qui me donne un script, qui ouvre un fichier


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,452 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.