Я новичок в программировании и работе над c++ (даже концепция проблемы такая же, как и в c, я думаю).
Я читаю файл как единственные аргументы, которые содержат алфавиты (символы в моем коде), такие как "aabbacceaad" для вычисления частоты. Мой код правильно вычисляет частоту. Я уверен в этом. Проблема в том, что в моей переменной указателя дерева Node * указана (которая относится к узлу типа). Я использую его для создания дерева. Но когда я пытаюсь создать дерево из частоты, вычисленной из повторяющихся символов, эта переменная указателя дерева запоминает только последнюю выполненную частоту вне цикла for-loop
. Пожалуйста, позаботьтесь, я просто должен использовать указатели, а не массивы.
Я имею в виду, что у меня есть символы во входном файле, такие как "aabcddeeebbaa". И ожидаемый результат для него таков:
0 symbol:a Freq:4 Left 0 Right 0 Index1
1 symbol:b Freq:3 Left 0 Right 0 Index2
2 symbol:c Freq:1 Left 0 Right 0 Index3
3 symbol:d Freq:2 Left 0 Right 0 Index4
4 symbol:e Freq:3 Left 0 Right 0 Index-1
Но вывод моего кода выглядит так:
0 symbol:e Freq:3 Left:0 Right:0 Next:5 //Last "e" is executed,tree variable forgot a,b,c and d.
1 symbol:e Freq:3 Left:0 Right:0 Next:5
2 symbol:e Freq:3 Left:0 Right:0 Next:5
3 symbol:e Freq:3 Left:0 Right:0 Next:5
4 symbol:e Freq:3 Left:0 Right:0 Next:-1
Мой полный код c++ для этого:
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <cassert>
#include <vector>
using namespace std;
class Huffman {
public: int data_size,
length;
Huffman(char * argv);
~Huffman() {};
vector < char > storesym;
vector < int > storefreq;
struct Node
{
int value;
int freq, next;
short flag;
unsigned char symbol;
struct Node * left, * right;
};
Node * tree;
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTOR definition ////////////////////////////////////////////////////////////////////////////////
Huffman::Huffman(char * argv)
{
char c;
int count = 0;
int flag[256]; //this flag is to know if the alphabet is already counted or not.If counted that i set it to "1" other wise it is "0".Please see below in my code
int j = 0;
FILE * input_file;
int *symbolarray;
symbolarray=new int[30];
char i, n;
input_file = fopen(argv, "rb");
c = fgetc(input_file);
////////////////////////////////////////////////////////////////////////////// From here to down i read the alphabbets from file taken as sole argument ///////////////////////////////////////
while (c != EOF && c != '\n' && c != '\r')
{
symbolarray[count] = c;
count++;
c = fgetc(input_file);
}
fclose(input_file);
for (i = 0; i < count; i++)
flag[i] = {0 };
int fcount1 = 0;
for (i = 0; i < count; i++)
{
if (flag[i] == 0)
{
for (j = i; j < count; j++)
{
if (symbolarray[i] == symbolarray[j]&& flag[j] == 0)
{
fcount1++;
flag[j] = 1; //**I am setting flag to 1 those alphabets to 1 so that they will not be counted again on next iteration**
}
}
storesym.push_back(symbolarray[i]);
storefreq.push_back(fcount1);
}
fcount1 = 0;
}
cout << endl;
////////////////////////////////////////////////////////////////////////// ERROR PRONE PART STARTS NOW /////////////////////////////////////////////////////
for (i = 0; i < storesym.size(); i++)
{
tree = new Node; // the problem is here this tree pointer don't store the values for all alphabets, it just remembers the last executed alphabet after this for loop.
tree -> left = NULL;
tree ->right = NULL;
tree -> symbol = storesym[i];
tree -> freq = storefreq[i];
tree -> flag = 0;
tree -> next = i + 1;
cout<<"check1 : "<<tree -> symbol<<endl;
}
//////////////////////////////////////////////////////////////////// eror PRONE PART ENDS HERE ///////////////////////////////////////////////////////////////////////////////////
cout << "Here is the data read from file" << endl;
n = storesym.size() - 1;
for (int i = 0; i < storesym.size(); i++)
{
if (n == i)
{
tree -> next = -1;
cout << i << " symbol:" << tree -> symbol << " Freq:" << tree ->freq << " Left:" << tree -> left << " Right:" << tree -> right << " Next:" << tree -> next << endl;
break;
} else
{
cout << i << " symbol:" << tree -> symbol << " Freq:" << tree -> freq << " Left:" << tree -> left << " Right:" << tree ->right << " Next:" << tree -> next << endl;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char * * argv)
{
int freq[256] = {0};
if (argc < 2) {
cout << "Ohh.. Sorry , you forgot to provide the Input File please" << endl;
return (0);
}
Huffman Object1(argv[1]);
return (0);
}
** Пожалуйста, помогите мне сохранить в памяти все "a, b, c, d и e" (не только последнее "e")? Я знаю, что есть что-то делать с указателями.
Этот бит
while (c != EOF && c != '\n' && c != '\r')
{
tree[count].symbol = c;
count++;
c = fgetc(input_file);
}
разделяет неинициализированное tree
указателей.
Это большой нет-нет, и означает, что ваша программа формально не определена.
Тебе просто не повезло, что он не разбился.
Вы делаете это снова немного дальше.
Затем вы выделяете в этом цикле:
for (i = 0; i < storesym.size(); i++)
{
tree = new Node; // the problem is here this tree pointer don't store the values for all alphabets, it just remembers the last executed alphabet after this for loop.
tree -> left = NULL;
tree ->right = NULL;
tree -> symbol = storesym[i];
tree -> freq = storefreq[i];
tree -> flag = 0;
tree -> next = i + 1;
cout<<"check1 : "<<tree -> symbol<<endl;
}
который неоднократно выделяет на нем один Node
и tree
точек.
Другими словами, он не строит дерево, и вам нужно переписать его так, как он есть на самом деле.
Независимо от того, какой материал курса вы следите, в последнее время должны были покрыть деревья.
Лучший совет, который я могу дать, - это начать, читать больше и не писать столько кода перед тестированием.