C++ : inversion texte par blocs

Discutez d'informatique ici !
rattlesnake
Membre Naturel
Messages: 29
Enregistré le: 15 Aoû 2014, 14:01

C++ : inversion texte par blocs

par rattlesnake » 12 Sep 2014, 15:54

Bonjour,
J'aimerais connaître une méthode pour inverser des blocs d'un fichier txt
par exemple :
6
1
1
2
2
3
5
4
4
deviendrait :
5
4
4
2
2
3
6
1
1

Merci d'avance !



Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 12 Sep 2014, 16:03

il ne s'agit pas de C++, mais d'algorithmie.
un algorithme assez évident est le suivant:
soit L la liste de nombres (de taille l) en entree
soit O la liste en sorties
- prendre les trois derniers nombre de L (L[l-3] ,L[l-2], L[l-1])
- les ajouter dans la liste de sortie: O.push_back(L[l-3] ,L[l-2], L[l-1])
- enlever ces nombres de L: L=L(0, l-4)
- recommencer jusqu'à ce que taille de L <3
la vie est une fête :)

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 12 Sep 2014, 17:30

voici un exemple en C++ (qqpart tu l'as un peu cherché..)
Code: Tout sélectionner
#include
#include
#include
#include
#include
#include
template
class Block{
  public:
  Block(size_t n):_size(n){}
  void push(const Value &v){
    _v.push_back(v);
  }
  template
  void flood(Container &l){
    std::copy(_v.rbegin(), _v.rend(), std::back_inserter(l));
    _v.clear();
  }
  bool full()const{
    return _v.size()==_size;
  }
  protected:
  std::vector _v;
  size_t _size;
};
template
Container reverse(const Container& v, size_t blockSize){
  Container out;
  Block b(blockSize);
 
  for(auto it = v.rbegin(); it!=v.rend(); ++it){
    b.push(*it);
    if(b.full()){
      b.flood(out);
    }
  }
  return out;
}
template
std::string toss(const Container& v){
  std::stringstream oss;
  std::copy(v.begin(), v.end(),
    std::ostream_iterator(oss, " "));
  return oss.str();
}
int main(){
  std::vector v={6,1,1,2,2,3,5,4,4};
  //std::list v={'a','b','c','d','e','f','g','h','i'};
  typedef decltype(v)::value_type valueType;
  const auto& out=reverse(v, 3);
  std::cout<<toss(v)<<std::endl<<toss(out)<<std::endl;
  return 0;
}


plus intérssant:
trier en inplace!
la vie est une fête :)

rattlesnake
Membre Naturel
Messages: 29
Enregistré le: 15 Aoû 2014, 14:01

par rattlesnake » 16 Sep 2014, 09:48

Merci pour ta réponse.
J'ai essayé de coder l'ensemble de façon bête et méchante. J'arrive à isoler le dernier bloc, mais quand il s'agit de reparcourir le texte pour récupérer l'avant dernier ça ne marche pas, du coup je me retrouve avec des fichiers textes avec uniquement le dernier bloc...
ci dessous le code commenté :

Code: Tout sélectionner
#include
#include
#include
#include
#include
#include

using namespace std;

int main()
{






   ifstream liste("/home/modis/Desktop/Traitement/liste_fichiers_txt.txt", ios::in);//ouverture de la liste de fichiers
   
   if(liste)
   {
      string lisligne;
      string filename0, filename1;
      string ligne,of_ligne;
      int n_ligne=40701, i=0,j;
      double double1, double2, double3, double4, double5, double6;
      string s1,s2,s3,s4,s5,s6;
      
for(j=0;j> filename0; //lecture du nom du fichier à ouvrir dans un fichier texte avec l'ensemble des noms
            filename1 = "/home/modis/Desktop/Traitement/fichiers_invers/" + filename0;
            filename0 = "/home/modis/Desktop/Traitement/données_modèles/données_modèles/2011/" + filename0;
            
            
            ifstream fichier0(filename0.c_str(), ios::in);   
            ofstream fichier1(filename1.c_str(), ios::out | ios::binary);


            if(fichier0 && fichier1)
               {
                  

                        
                  while(getline(fichier0, ligne))
                  {   
                              ostringstream oss1,oss2,oss3,oss4,oss5,oss6;
                                                               
                        
                           if(i==n_ligne-2-220*j) //220 lignes par bloc
                           {      
                              fichier0 >> double1 >> double2 >> double3 >> double4 >> double5 >> double6;
                              oss1 << double1;
                              oss2 << double2;
                              oss3 << double3;
                              oss4 << double4;
                              oss5 << double5;   oss6<<double6;                                                   
                              s1 = oss1.str();
                              s2 = oss2.str();
                              s3 = oss3.str();
                              s4 = oss4.str();
                              s5 = oss5.str();
                              s6 = oss6.str();
                              of_ligne= s1 + " " + s2 + " " + s3 + " " + s4 + " " + s5 + " " + s6 + "\n";
                              fichier1 << of_ligne;//ecriture de la ligne dans le fichier output
                              //vide les ostringstream                   
                              oss1.str("");
                              oss2.str("");
                              oss3.str("");
                              oss4.str("");
                              oss5.str("");
                              oss6.str("");
                              
                           }
                           else i++;//si je ne suis toujours pas à la ligne voulue
                                             
                  
                                          
                           
                        

                  }
               }
               else
                  cerr<<"Impossible d'ouvrir le fichier!1"<<endl;
               i=0;//remise à zero pour reparcourir le fichier
         
      }
   }
}
   else
      cerr<<"Impossible d'ouvrir le fichier!2"<<endl;

   return 0;
}


Je tourne en rond dessus depuis un bon petit moment, j'aimerais juste savoir ce qui empêche de reparcourir le fichier pour prendre un nouveau bloc...
Le but étant d'ouvrir un fichier, de parcourir ses lignes jusqu'à la premiere du bloc voulu, d'écrire ces lignes dans un nouveau fichier. Une fois arrivé à la dernière ligne, on reparcourt le fichier jusqu'à la premiere ligne du bloc au dessus puis on écris la suite etc.
Merci d'avance

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 16 Sep 2014, 09:51

Bonjour,

Il ne faut pas oublier que lorsque tu lis un fichier, un curseur est présent pour savoir quand tu arrives au bout du fichier.

Si tu veux remonter au début de ton fichier, il faut que tu utilises seekg : http://www.cplusplus.com/reference/istream/istream/seekg/ pour remettre le curseur au début du fichier.

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 16 Sep 2014, 11:12

hello,

plusieurs choses:
jvais pas te lancer des fleurs, ton code fait tout pour que tu galères.
Déjà il faut savoir que le mot clé fonction existe!
une fonction pour convertir un fichier en un autre, et une fonction qui prend une liste de fichiers et qui applique à chacun la première

Ensuite, on fait du C++ et pas du C des années poussiéreuses, donc tu instancies tes variables au plus près! idem tu les déclares au plus près.
T'as cinquante mille ostream et double, il serait bon de faire une boucle...

Enfin, juste pour info, lorsque les ressources le permettent, vaut mieux gérer les fichiers en buffer (string), parce que la mémoire c'est plus rapide que le filesystem.
Typiquement, fichier -> string
puis apres string->vector de ligne
puis vector de double
tu tries ton vector de double
puis tu l'écris dans le fichier de sortie

tu t'en sors bien sûr avec tes fichiers, mais à la perte de quelques cheveux
la vie est une fête :)

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite