我重载了ostream运算符<<能够打印或写下我的ojbects。在其中一个中,我实际上是在file.txt中编写我的整个结构。结构对象实际上是一个二叉树,为了确保我从中获取每个元素,我需要一个递归函数。这是我尝试做的基本代码。
out << parcour(tree); // recursive function
Parcour假设返回anoter结构,其中我有输入文件中的信息。我的递归函数的内部是这样的:
node* parcour(node* node){
if (node) {
parcour(childnode(0));
parcour(childnode(1));
return node;
}
return nullptr;
}
具有我想要的信息的所有节点都由此函数返回。所以我认为问题是多次返回单个std :: cout实际上并没有工作。我想知道是否有一个带有多个返回函数(一个递归函数)的函数可以作为输出,每次只返回一个返回值。
请不要注意语法合成错误,因为我的代码运行完全,除了我无法解决的单一概念。
编辑:有些人一直要求我提供更多代码,所以基本上我只是复制粘贴下面的原始代码(注意:一切都是法语:S):这是Arbres.h
#ifndef ARBRES_H
#define ARBRES_H
#pragma once
#include <iostream>
#include <vector>
using namespace std;
// noeud pour un arbre binaire contenant des informations de type T
template <class T>
class Noeud
{
private:
T* element; // élément du noeud
Noeud<T> *parent; // Pointeur vers le parent
Noeud<T> *gauche; // Pointeur vers le fils gauche
Noeud<T> *droit; // Pointeur vers le fils droit
public:
//constructeur du noeud
Noeud()
{
element = nullptr;
parent = nullptr;
gauche = nullptr;
droit = nullptr;
}
// destructeur du noeud
~Noeud ()
{
}
// retourne l'enfant où "i" represente la position de l'enfant (droit ou gauche)
Noeud<T> * Enfant(int i) const
{
if (i == 0)
if (!gauche)
return nullptr;
else
return gauche;
else if (i == 1)
if (!droit)
return nullptr;
else
return droit;
else
return nullptr;
}
// retourne le parent du noeud
Noeud<T> *Parent () const
{
return parent;
}
// retourne un pointeur vers l'élément du noeud (les infos)
T *Element() const
{
return element;
}
// modifie la valeur de l'élément
void RemplacerElement( T *ele )
{
element = ele;
}
//retourne vrai si le noeud est une feuille
bool EstUneFeuille () const
{
return (!gauche) && (!droit);
}
//retourne vrai si le noeud est une racine
bool EstUneRacine () const
{
return (!parent);
}
// détache l'enfant du noeud et retourne un pointeur vers ce noeud
Noeud<T> *Detacher (Noeud<T>* Enfant)
{
Noeud<T> *temp;
if (Enfant->parent->gauche == Enfant) {
temp = Enfant->parent->gauche;
Enfant->parent->gauche = nullptr;
} else if (Enfant->parent->droit == Enfant) {
temp = Enfant->parent->droit;
Enfant->parent->droit = nullptr;
} else
return nullptr;
return temp;
}
// attache le noeud à l'enfant. Retourne vrai si l'opération est réussie
bool Attacher(Noeud<T>* nouvelEnfant)
{
if (!gauche)
gauche = nouvelEnfant;
else if(!droit)
droit = nouvelEnfant;
else
return 0;
return 1;
}
// attache les enfants au noeud. Retourne vrai si l'opération est réussie
bool Attache(Noeud<T>* noeudCourant)
{
if (!gauche->parent)
gauche->parent = noeudCourant;
else if (!droit->parent)
droit->parent = noeudCourant;
else
return 0;
return 1;
}
// Fonction Récursive qui crée un nouveau noeud et le place correctement dans l'arbre
void CreerNouveauNoeud(istream& in, Noeud<T>* noeudCourant, int val) {
if (val == 1) {
if (!noeudCourant->Enfant(0)) {
noeudCourant->Attacher(new Noeud<T>());
noeudCourant->Attache(noeudCourant);
noeudCourant = noeudCourant->Enfant(0);
noeudCourant->RemplacerElement(new T());
in >> *(noeudCourant->Element());
return;
}
else if (!noeudCourant->Enfant(1)) {
noeudCourant->Attacher(new Noeud<T>());
noeudCourant->Attache(noeudCourant);
noeudCourant = noeudCourant->Enfant(1);
noeudCourant->RemplacerElement(new T());
in >> *(noeudCourant->Element());
return;
}
else {
cout << "\nERROR: Structure dans le fichier texte incorrect (limite de 2 sous-noeuds par noeud)" << endl;
return;
}
}
else {
if (!noeudCourant->Enfant(1)) // S'il existe un noeud à droite s'est qu'on est rendu à ajouter la, sinon on va à gauche
CreerNouveauNoeud(in, noeudCourant->Enfant(0), val - 1);
else
CreerNouveauNoeud(in, noeudCourant->Enfant(1), val - 1);
}
return;
}
// le mot clé "friend" indique que la fonction peut utiliser les membres privés de la classe Noeud
template<class U>
friend istream& operator>> (istream& in, Noeud<U>& n);
template<class U>
friend ostream& operator<< (ostream& out, Noeud<U>& n);
};
// surcharge de l'opérateur >> pour un noeud
template <class T>
istream& operator>> (istream& in, Noeud<T>& n)
{
in >> *n.element;
return in;
}
// surcharge de l'opérateur << pour un noeud
template <class T>
ostream& operator<< (ostream& out, Noeud<T>& n)
{
out << *n.element;
return out;
}
// Patron de classe définissant la classe "Arbres"
// contenant des informations de type T
template <class T>
class Arbres
{
// Patron de classe définissant la classe "Arbres"
private:
vector<Noeud<T>*> racines;
Noeud<T>* noeudCourant;
public:
//constructeur d'une classe Arbres
Arbres()
{
noeudCourant = nullptr;
}
// destructeur d'une classe Arbres
~Arbres ()
{
supprimeArbre();
}
// ajoute un arbre de niveau 0 (un noeud) à la liste des racines
int NouveauNoeud(Noeud<T>* n)
{
n->RemplacerElement(new T());
racines.push_back(n);
return racines.size() - 1;
}
// positionne le noeud courant sur le noeud racine d'indice i
void SetCourant(int i)
{
if(i<racines.size())
noeudCourant = racines[i];
}
// Déplace le noeud courant vers son enfant i
void NaviguerVersEnfant(int i)
{
noeudCourant = noeudCourant->Enfant(i);
}
// Déplace le noeud courant vers son parent
void NaviguerVersParent()
{
noeudCourant = noeudCourant->Parent();
}
// mets le noeud en position i de la liste racine comme enfant du noeud courant
void joindreCourant(int i)
{
if (!noeudCourant->Enfant(0) || !noeudCourant->Enfant(1)) {
noeudCourant->Attacher(racines[i]);
racines[i] = nullptr;
racines.erase(racines.begin()+i);
}
else {
cout << "/nERROR: Aucun Enfant disponible sur le noeud Courant " << endl;
}
}
// Détache le noeud courant de son parent
void DetacherCourant()
{
if (noeudCourant->Parent()->Enfant(0) == noeudCourant) {
noeudCourant->Detacher(noeudCourant->Enfant(0));
}
else
noeudCourant->Detacher(noeudCourant->Parent()->Enfant(1));
}
// supprime le noeud courant
void SupprimerCourant()
{
supprimeArbre(noeudCourant);
}
// retourne la liste des noeuds racines
const vector<Noeud<T>*>* getRacine() const
{
return &racines;
}
// retourne le noeud courant
const Noeud<T>* getCourant() const
{
return noeudCourant;
}
// fonction récursive qui parcours l'arbre et retourne chacun d'entre eux
void parcourir(ostream& out, Noeud<T>* racine) {
if (racine) {
parcourir(out, racine->Enfant(0));
parcourir(out, racine->Enfant(1));
out << *racine;
}
return;
}
void supprimeArbre(Noeud<T>* racine) { // fonction récursive qui parcours l'arbre et supprime chaque noeud que l'on rencontre
if (racine) {
supprimeArbre(racine->Enfant(0));
supprimeArbre(racine->Enfant(1));
delete racine->Element();
delete racine;
}
return;
}
// le mot clé "friend" indique que la fonction peut utiliser les membres privés d'une classe Arbres
template<class U>
friend istream& operator>> (istream& in, Arbres<U>& n);
template<class U>
friend ostream& operator<< (ostream& out, Arbres<U>& n);
};
// surcharge de l'opérateur >> pour un objet de type Arbres<T>
template <class T>
istream& operator>> (istream& in, Arbres<T>& n)
{
string buffer;
while (in >> buffer) {
int a = count(buffer.begin(), buffer.end(), '-'); // Compte le nombre de tiret pour déterminer le niveau du noeud dans l'arbres
if (a == 0) {
n.SetCourant(n.NouveauNoeud(new Noeud<T>()));
n.noeudCourant->RemplacerElement(new T());
in >> *(n.noeudCourant);
}
else {
n.noeudCourant->CreerNouveauNoeud(in, n.noeudCourant, (a / 2));
}
}
return in;
}
// surcharge de l'opérateur << pour un objet de type Arbres<T>
template <class T>
ostream& operator<< (ostream& out, Arbres<T>& n)
{
for (int x = 0; x < n.racines.size(); x++) {
n.parcourir(out, n.racines[x]);
}
return out;
}
#endif
这是TP2.h
#ifndef TP2_H
#define TP2_H
#pragma once
# include <string>
# include <iostream>
using namespace std;
class Personne
{
private:
string nom;
string prenom;
int age;
string metier;
public:
Personne();
Personne(string leNom, string lePrenom, int lAge, string leMetier);
~Personne();
friend istream& operator>> (istream& in, Personne& n);
friend ostream& operator<< (ostream& out, Personne& n);
};
#endif
这是TP2.cpp
#include "TP2.h"
#include "Arbres.h"
#include <fstream>
#include <algorithm>
using namespace std;
Personne::Personne() {
return;
}
Personne::Personne(string leNom, string lePrenom, int lAge, string leMetier)
{
nom = leNom;
prenom = lePrenom;
age = lAge;
metier = leMetier;
return;
}
Personne::~Personne()
{
return;
}
istream& operator>> (istream& in, Personne& n)
{
in >> n.nom >> n.prenom >> n.age >> n.metier;
return in;
}
ostream& operator<< (ostream& out, Personne& n)
{
out << "\tNom: " << n.nom << "\n\tPrenom: " << n.prenom << "\n\tAge: " << n.age << "\n\tMetier: " << n.metier << endl;
return out;
}
int main(){
ifstream Transaction;
ifstream Data_input;
ofstream Data_ouput;
string transaction_fichier;
string arbres_fichier;
char op[1], FILENAME[50]; // Operateur, Nom d'un fichier
int i; // Indice
Arbres<Personne>* structure = nullptr;
cout << "Entrer le nom du fichier transaction: ";
cin >> transaction_fichier; // IMPORTANT : Le nom du fichier ne doit pas compoter d'espace!
cout << endl;
Transaction.open(transaction_fichier);
if (Transaction.fail())
cout << "\nError 404 : File not found\n";
while (!Transaction.eof()) {
Transaction >> op;
switch (op[0]) {
case '*':
Transaction >> *(*(structure->getRacine()))[structure->NouveauNoeud(new Noeud<Personne>())];
break;
case '&':
Transaction >> i;
structure->SetCourant(i);
break;
case '>':
Transaction >> i;
structure->NaviguerVersEnfant(i);
break;
case '<':
Transaction >> i;
structure->NaviguerVersParent();
break;
case '+':
Transaction >> i;
structure->joindreCourant(i);
break;
case '-':
structure->DetacherCourant();
break;
case '!':
structure->SupprimerCourant();
break;
case '%':
cout << "Informations des personnes dans les noeuds racines:" << endl;
for (unsigned int x = 0; x < (*(structure->getRacine())).size(); x++) {
cout << *(*(structure->getRacine()))[x] << endl;
}
break;
case '?':
cout << "Informations de la personne dans le noeud courant:" << endl;
cout << *(structure->getCourant()->Element()) << endl;
break;
case '#':
if (structure) {
for (unsigned int x = 0; x < (*(structure->getRacine())).size(); x++) {
structure->supprimeArbre((*(structure->getRacine()))[x]);
}
}
else {
Transaction >> FILENAME;
Data_input.open(FILENAME);
if (Data_input.fail())
cout << "\nError 404 : File not found\n";
structure = new Arbres<Personne>;
Data_input >> *structure;
}
break;
case '$':
Transaction >> FILENAME;
Data_ouput.open(FILENAME);
Data_ouput << *structure;
break;
default:
cout << "\nError420 Operator not supported: " << op << endl;
break;
}
}
// Fin du programme
return 0;
}
答案 0 :(得分:3)
整个递归调用无法正常运行。
离开的是从您的顶级parcour()
调用返回的 return 值。由于内部递归调用似乎没有对返回值做出贡献,因此调用是否发生或者只是被跳过并不重要。
要实现您所描述的意图,您需要将输出对象传递给parcour()
并在该函数中输出您需要的任何内容。