我正在学习c ++并且我被分配为一个项目来构建一个给出字符串的树(例如" hello world hello one world"),它必须为每个不同的域创建一个节点字符串中的单词,节点的一部分必须包含一个空格来保存单词而另一个节点必须保存出现的频率(例如hello | 2,one | 1,world | 2),但是当我单独放置单词时meter()函数没有问题,但问题是当我试图获取整个字符串的单词时,由于一些奇怪的原因只是将字符串的最后一个字添加到树中,频率为字符串中的单词。我已经尝试了不同的方法来将字符串拆分为单词以将它们添加到树中,但所有这些方法总能得到相同的结果。
#include <iostream>
#include <conio.h>
#include <cstring>
#include <sstream>
using namespace std;
typedef char* tipo;
typedef int tipo1;
class Nodo{
tipo1 f;
tipo dato;
Nodo *izq;
Nodo *der;
friend class Arbol;
};
typedef Nodo* pNodo;
class Arbol{
pNodo raiz;
public:
Arbol();
pNodo getRaiz();
tipo getDato();
void insertarNodo(tipo x, pNodo &p);
void meter(tipo x);
void eliminaNodo(tipo x, pNodo &p);
void eliminar(tipo x);
void inOrden(pNodo p);
tipo1 pertenece(tipo x, pNodo p);
tipo menor(pNodo p);
tipo1 pertenece1(tipo x);
int estaVacia();
void arbolito(tipo x);
};
Arbol::Arbol(){
raiz=NULL;
}
pNodo Arbol:: getRaiz(){
return raiz;
}
int Arbol:: estaVacia(){
return raiz==NULL;
}
void Arbol::insertarNodo(tipo x, pNodo &p){
if (p==NULL){
p=new Nodo();
p->f=1;
p->dato=x;
p->izq=NULL;
p->der=NULL;
}
else if(strcmp(x, p -> dato)<0){
insertarNodo(x, p->izq);
}
else if(strcmp(x, p -> dato)>0){
insertarNodo(x,p->der);
}
else if(strcmp(x, p -> dato)==0){
p -> f ++;
}
}
void Arbol:: meter(tipo x){
insertarNodo(x,raiz);
}
tipo Arbol:: menor(pNodo p){
if (estaVacia()){
return "Error: Arbol vacio";
}else{
if (p->izq==NULL){
return p->dato;
}else{
return menor(p->izq);
}
}
}
void Arbol:: eliminaNodo(tipo x, pNodo &p){
if (p!=NULL){
if (strcmp(x, p -> dato)==0){
(p->f)--;
if (p->izq==NULL && p->f==0){
pNodo q=p;
p=p->der;
delete q;
}else if(p->der==NULL && p->f==0){
pNodo q=p;
p=p->izq;
delete q;
}else if(p->izq!=NULL && p->der!=NULL & p->f==0){
tipo m=menor(p->der);
p->dato=m;
eliminaNodo(m,p->der);
}
}else if (strcmp(x, p -> dato)<0){
eliminaNodo(x,p->izq);
}else{
eliminaNodo(x, p->der);
}
}else{
cout<<"No se encontro el dato";
}
}
void Arbol:: eliminar(tipo x){
eliminaNodo(x, raiz);
}
void Arbol:: inOrden(pNodo p){
if (p!=NULL){
inOrden(p->izq);
cout<<p->dato<<"="<<p->f<<endl;
inOrden(p->der);
}
}
tipo1 Arbol:: pertenece(tipo x, pNodo p){
if (p==NULL){
return 0;
}
if (p->dato==x){
return p->f;
}else if(strcmp(x, p -> dato)<0){
return pertenece(x, p->izq);
}else if(strcmp(x, p -> dato)>0){
return pertenece(x,p->der);
}
}
tipo1 Arbol:: pertenece1(tipo x){
return pertenece(x,raiz);
}
int main()
{
Arbol tree;
tipo a,b;
string x;
string s="hjk This is";
s=s+" ";
int i=0;
a=strchr(s.c_str(),' ');
while (s[i]!=' ' && i<s.size()){
x=x+s[i];
i++;
if (i==a-s.c_str()){
strcpy(b, x.c_str());
cout <<x.c_str()<<endl;
tree.meter(b);
i++;
a=strchr(a+1,' ');
x="";
}
}
tree.inOrden(tree.getRaiz());
getch();
return 0;
}
答案 0 :(得分:0)
我认为您的问题是因为您使用的是char*
而不是字符串。
当您将节点插入数据结构时,只保留指针的副本到字符串,并且不要复制该字符串。
当您的代码解析句子中的下一个单词时,您将新单词指定给指针b
。然后所有您的节点现在指向同一个单词 - 在您处理完句子后,它将始终是最后一个单词。
更改您的代码以使用strcpy
获取该单词的副本并将其存储在节点中,而不仅仅是指针的副本。 (不要忘记为副本分配内存,更改为使用string
而不是char*
的另一个原因,所有内存管理都是为您处理的。)