J'ai terminé la création (plutôt la reproduction ^^) de l'automate cellulaire "le jeu de la vie" de conway en C++. Il marche parfaitement, seulement, je tourne sur un monde de 153*274 carrés de 5px, et j'aimerais m'amuser a faire 1366*768 carrés de 1 px pour voir toutes les évolutions de plusieurs milliers de cellules en même temps. Mon monde est en fait un tableau bidimensionnel, qui contient des 0 et des 1 (1 pour cellule vivante.). Mais problème de mémoire, dès que mon tableau devient plus gros, dès qu'on débute le checking de chaque cellule du tableau, Paf, ça crash... Du coup, je me dis que les tableaux pour les mondes ne doivent pas être une bonne habitude pour ce genre de choses. Mais je ne sais vraiment pas comment faire autrement.
Et bien après vérification, non! La compilation a cette fois bien lieu, mais l'erreur est plus loin maintenant, lors du premier tour de boucle sur le tableau, tout plante. Merci.
- Edité par AnselmeClergeot 18 juillet 2014 à 11:41:01
Peux-tu m'expliquer comment les déclarer dynamiquement SANS boost qui est une galère à installer? Et aussi comment parcourir ce tableau si il faut utiliser une manière différente?
Crois-tu que je n'ai pas terminé le tuto C++? Crois-tu qu'avant de m'embeter à écrire ce sujet je n'ai pas googlé des heures dans toutes les langues possibles? Crois-tu que ta réponse m'est vraiment utile? D'autant plus que le site sur lequel tu m'as vulgairement envoyé ne contient AUCUNE information sur ce que je cherche. La prochaine fois, abstient toi de ce genre de réponses inutiles à souhait.
- Edité par AnselmeClergeot 18 juillet 2014 à 12:05:07
Si tu ne sais pas instancier dynamiquement un tableau en deux dimensions après avoir "googlé des heures", poses toi quelques questions. Soit dit en passant, la page que je viens de t'envoyer contient un exemple complet et extrêmement bien documenté d'allocation dynamique.
Salut. Comment par lire ca: une deque est ce qui te permet de gérer dynamiquement un tableau à une dimension http://www.cplusplus.com/reference/deque/deque/
Ensuite, comme tu veux un tableau à deux dimension (L lignes et C colones), tu crée une deque de L*C éléments
Tu accèdes à l'élément ligne l, colonne c, en prenant lélément à l'index l*C + c de ta deque.
Oprax, je ne comprends pas comment elle fonctionne... Ksass précise qu'il faut l'implémenter, mais rien qu'a voir la tête du .h, ça à l'air supeer dur.
- Edité par AnselmeClergeot 18 juillet 2014 à 12:16:32
@IAmJohn tu lien est obsolète on est en C++ les tableaux style-C c'est moche, regarde std::array.
J'aimerais bien quelques arguments pour appuyer cette réponse un peu trop définitive.
Les arguments sont ressassés partout où l'on parle de vrai C++ depuis au moins 10 ans.
Très facile, l'exemple de wikipedia contient des fuites de mémoire potentielle. C++ est un langage à exceptions, dans lequel la gestion manuelle des ressources est une hérésie. Le concept central pour la gestion des ressources en C++, c'est le RAII et rien d'autre. En l'occurrence, l'allocation et désallocation de ressources à la main, c'est à bannir.
std::vector (et de manière générale, tous les conteneurs de la STL)
std::unique_ptr
std::shared_ptr/std::weak_ptr
(Dans le cas - rare - où C++11 n'est pas accessible, voir boost::scoped_ptr, boost::scoped_vector, boost::shared_ptr).
A noter : ce n'est pas valable que pour la mémoire. std::lock, std::ofstream et cie, sont d'autres bon exemples de capsule RAII.
AnselmeWindowsDev a écrit:
Ksass précise qu'il faut l'implémenter, mais rien qu'a voir la tête du .h, ça à l'air supeer dur.
Je suis sûr qu'en prenant ton mal en patience, tu t'en sortirais, ce n'est pas si compliqué que cela et j'ai bien commenté les fonctionnalités.
Mais bon, un exemple de code minimal pour une matrice comme conteneur simple (pas adapté pour les classes à sémantique d'entité non-polymorphes) :
template<class T>
class Matrix{
public:
Matrix(std::size_t w, std::size_t h) : _w{w}, _h(h), _data{ new T[_w*_h] }{}
Matrix(Matrix const& m) : _w{m._w}, _h{m._h}, _data{ new T[_w*_h] }{
for(unsigned int i{}; i < _w*_h; ++i) _data[i] = m._data[i];
}
Matrix& operator=(Matrix const& m){
Matrix copy{ m };
swap(m);
return *this;
}
Matrix(Matrix&& m) = default;
Matrix& operator=(Matrix&& m) = default;
void swap(Matrix& m){
std::swap(_h, m._h);
std::swap(_w, m._w);
_data.swap(m._data);
}
T const& operator()(std::size_t x, std::size_t y) const {
assert(x < _w && "Out of bound x");
assert(y < _h && "Out of bound y");
return _data[y*_w + x];
}
T & operator()(std::size_t x, std::size_t y) {
assert(x < _w && "Out of bound x");
assert(y < _h && "Out of bound y");
return _data[y*_w + x];
}
std::size_t width() const{ return _w; }
std::size_t height() const{ return _h; }
private:
std::size_t _w;
std::size_t _h;
std::unique_ptr<T[]> _data;
};
Utilisation :
int main(){
Matrix<int> m{ 12, 12 };
for(unsigned y{}; y < m.height(); ++y)
for(unsigned x{}; x < m.width(); ++x)
m(x,y) = y*x;
for(unsigned y{}; y < m.height(); ++y){
for(unsigned x{}; x < m.width(); ++x)
std::cout<<m(x,y)<<' ';
std::cout<<std::endl;
}
return 0;
}
std::array est un conteneur implémentant un tableau de taille fixe, les arguments en sa faveur peuvent se résumer à: Parce que c'est ce qui justifie l'existence même du C++ (généricité, invariants,spécifications,encapsulation,SRP,RAII, Object as service provider...).
Considérons un langage imaginaire qui accepte n'accepte que des uns et des zéros. De plus, pour accepter la phrase, elle doit se terminer par + si elle était dans l'état zéro ou % si elle était dans l'état un. Pou langage sont décrits dans l'image suivante
DFA.h
#ifndef DETERMINISTIC_FINITE_AUTOMATA_H
#define DETERMINISTIC_FINITE_AUTOMATA_H
#include <stdbool.h>
/* Structs to represent State, Transition and the automata itself */
typedef struct DETERMINISTIC_FINITE_AUTOMATA DFA;
typedef struct DETERMINISTIC_FINITE_AUTOMATA_STATE DFA_State;
typedef struct DETERMINISTIC_FINITE_AUTOMATA_TRANSITION
DFA_Transition;
/* Define an automata transition */
struct DETERMINISTIC_FINITE_AUTOMATA_TRANSITION
{
DFA_State *origin_state;
DFA_State *destination_state;
char trigger_value; // The value that triggers the transition
};
/* Define an automata state */
struct DETERMINISTIC_FINITE_AUTOMATA_STATE
{
int state_identifier; // Integer number to help end user identify the state
bool accept_state; // If this state is an accept state or not
int transitions_count;
DFA_Transition **transitions;
};
/* Define the automata */
struct DETERMINISTIC_FINITE_AUTOMATA
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
{
int states_count;
DFA_State **states;
DFA_State *current_state;
DFA_State *initial_state;
};
/* ====== Functions ====== */
/* Automata state manipulation */
bool init_automata (DFA *automata);
bool update_automata (char ch, DFA *automata);
/* Automata abstraction of state updates */
bool belongs_to_language (char *string, DFA *automata);
/* Alloc abstaction */
DFA_State* create_state (int state_identifier, bool accept_state, DFA *automata);
DFA_Transition* create_transition (char trigger_value, DFA_State *origin_state,
DFA_State *destination_state);
DFA* create_automata ();
/* Allow creation of several transitions simply */
bool generate_transitions(char *string, DFA_State *origin_state, DFA_State
*destination_state);
/* Dealloc abstraction */
bool free_automata (DFA *automata);
/* ====== DEBUG FUNCTIONS ====== */
void describe_automata (DFA *automata);
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
#endif // DETERMINISTIC_FINITE_AUTOMATA_H
DFA.c
#include "dfa.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
bool init_automata (DFA *automata)
{
if (!automata->initial_state) {
printf("[-] Error: Initial state of automata not set.\n");
exit(1);
}
return (automata->current_state = automata->initial_state);
}
bool update_automata (char ch, DFA *automata)
{
DFA_State *state = automata->current_state;
bool made_transition = false;
for (int j = 0; j < state->transitions_count; j++) {
if (state->transitions[j]->trigger_value == ch) {
automata->current_state = state->transitions[j]->destination_state;
made_transition = true;
break; // Finite automata does not have 'choices'. If trigger_value matches, then the
automata must not have another transition with the same value.
}
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
}
if (!made_transition) { // Automata will always execute a transition if value is accepted.
Even if the transition result in the same stage.
return false;
}
return true;
}
bool belongs_to_language (char *string, DFA *automata)
{
if (strlen(string) == 0) {
printf("[-] Error: Empty string sent to analyse in belongs_to_language.\n");
exit(1);
}
init_automata(automata);
for (int i = 0; i < strlen(string); i++) {
if (!update_automata(string[i], automata)) {
return false;
}
}
return automata->current_state->accept_state;
}
bool set_transition_to_state (DFA_Transition **transition, DFA_State *origin_state)
{
DFA_Transition **tmp = realloc(origin_state->transitions, (origin_state-
>transitions_count + 1) * sizeof(DFA_Transition));
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
if (tmp == NULL) {
printf("[-] Error during reallocation of state transitions. Trying again.\n");
tmp = realloc(origin_state->transitions, (origin_state->transitions_count + 1) *
sizeof(DFA_Transition));
if (tmp == NULL) {
printf("[-] Error during reallocation of state transitions.\n");
exit(1);
}
}
origin_state->transitions = tmp;
origin_state->transitions[origin_state->transitions_count] = *transition; // Add new
transitions to array of transitions
origin_state->transitions_count += 1;
return true;
}
bool set_state_to_automata (DFA_State **state, DFA *automata)
{
automata->states = realloc(automata->states, (automata->states_count + 1) *
sizeof(DFA_State));
if (!automata->states) {
printf("[-] Error during reallocation of automata states.\n");
exit(1);
}
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
automata->states[automata->states_count] = *state; // Add new state to the final of the
array
automata->states_count += 1;
return true;
}
DFA_State* create_state (int state_identifier, bool accept_state, DFA *automata)
{
DFA_State *state = malloc(sizeof(DFA_State));
if (!state) {
printf("[-] Error during allocation of state.\n");
exit(1);
}
state->accept_state = accept_state;
state->transitions_count = 0;
state->state_identifier = state_identifier;
state->transitions = NULL;
set_state_to_automata(&state, automata);
return state;
}
DFA_Transition* create_transition (char trigger_value, DFA_State *origin_state,
DFA_State *destination_state)
{
DFA_Transition *transition = malloc(sizeof(DFA_Transition));
if (!transition) {
printf("[-] Error during allocation of transition.\n");
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
exit(1);
}
transition->trigger_value = trigger_value;
transition->origin_state = origin_state;
transition->destination_state = destination_state;
set_transition_to_state(&transition, origin_state);
return transition;
}
bool generate_transitions (char *string, DFA_State *origin_state, DFA_State
*destination_state)
{
for (int i = 0; i < strlen(string); i++) {
if (!create_transition(string[i], origin_state, destination_state)) {
return false;
}
}
return true;
}
DFA* create_automata ()
{
DFA *automata = malloc(sizeof(DFA));
if (!automata) {
printf("[-] Error during allocation of automata.\n");
exit(1);
}
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
automata->states_count = 0;
automata->initial_state = NULL;
automata->states = NULL;
return automata;
}
bool free_automata (DFA *automata)
{
for (int i = 0; i < automata->states_count; i++) {
for (int j = 0; j < automata->states[i]->transitions_count; j++) {
free(automata->states[i]->transitions[j]);
}
free(automata->states[i]);
}
free(automata);
return true;
}
/* ========== DEBUG FUNCTIONS ========== */
void describe_transition (DFA_Transition *transition)
{
printf("------ Origin state: %p\n", transition->origin_state);
printf("------ Destination state: %p\n", transition->destination_state);
printf("------ Trigger value: %c\n", transition->trigger_value);
}
void describe_state (DFA_State *state)
Université Sidi Mohamed Ben Abdellah
Faculté des Sciences dhar el mahraz Fes Compilation
{
printf("--- Accept state: %d\n", state->accept_state);
if (state->transitions_count > 0) {
printf("--:: Transitions dump (%d):\n", state->transitions_count);
for (int i = 0; i < state->transitions_count; i++) {
printf("------ Transition %d\n", i);
describe_transition(state->transitions[i]);
}
} else {
printf("--:: State has no transitions to dump.\n");
}
}
void describe_automata (DFA *automata)
{
printf("Automata dump:\n");
if (automata->states_count > 0) {
printf(":: States dump (%d):\n", automata->states_count);
for (int i = 0; i < automata->states_count; i++) {
printf(":: State %d\n", i);
describe_state(automata->states[i]);
}
} else {
printf("--- Automata has no states to dump.\n");
}
}
Écrire le programme principale main.c pour vérifie ces 2 expression régulière a-aaaa--0101% 100101011
Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.
Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre. En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.
Au lieu de déterrer un sujet il est préférable :
soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
soit de créer un nouveau sujet décrivant votre propre contexte
ne pas répondre à un déterrage et le signaler à la modération
Je ferme ce sujet. En cas de désaccord, me contacter par MP.
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
* Un wrapper C++ pour sqlite * Une alternative a boost units
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Écrire le programme principale main.c pour vérifie ces 2 expression régulière a-aaaa--0101% 100101011