函数调用运算符重载和析构函数帮助

发布于 2024-11-26 02:16:07 字数 5541 浏览 0 评论 0原文

我认为我的析构函数现在很好......但仍然不确定如何从operator() 重载中调用print_set。

它按应有的方式输出,但我觉得有一种简单的方法可以从函数调用重载中调用 print_set...似乎无法按照我想要的方式得到东西。

头文件:

/**
 * disjoint_sets class declaration
 *
 */

#include<ostream>
#include<string>
#include<list>

class disjoint_sets 
{
public:

  disjoint_sets(int n); //n is the maximum int that can be in a set, so arrays need to be of size n+1
  ~disjoint_sets();

  bool make_set(int n);
  int find_set(int u);
  bool union_set(int u, int v);
  void print_set(std::ostream& out, int u); //e.g. { 1, 2, 4, 8, 10, }

  operator std::string(); //e.g. "{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }"

private:
  typedef std::list<int>* listptr;

  int* p;       //parent array
  int* rank;    //rank array
  listptr* set; //array of pointers. Each set[i] is a pointer is to a list<int> containing the integers in the i'th set
  int size;     //the size i.e. maximum int that can be in a set

};

实现:

/**
 * disjoint_sets class implementation
 *
 */

#include <iostream>
#include <istream>
#include <sstream>
#include <string>
#include <list>

#include "disjoint.hpp"



/*********************
 * CONSTRUCTOR
 *********************/
disjoint_sets::disjoint_sets(int n)
{
  size = n;

  // initialize all arrays to same size (n+1)  
  p      =    new int[n+1];
  rank   =    new int[n+1];
  set    =    new listptr[n+1];

  // loop through set (array of pointers) and initialize
  //   each element to an empty list
  for (int i(1); i <= n; i++)
    {
      set[i] = new std::list<int>;
    }
}



/*********************
 * DESTRUCTOR
 *********************/
disjoint_sets::~disjoint_sets()
{
  delete[] p;
  delete[] rank;

  // delete each element in the set first, then delete the set.
  for(int i(1); i<size+1; i++)
    {
      set[i]->clear();  
    }
  delete[] set;
}



/*********************
 * MAKE_SET
 *********************/
bool disjoint_sets::make_set(int n)
{
  // if parent already exists
  if (p[n] != 0)
    {
      return false;
    }

  // else we need to make a set  
  else
    {
      // make itself the parent
      p[n] = n;

      // use push_front to add the int to front of set
      set[n]->push_front(n);

      return true;
    }
}



/*********************
 * FIND_SET
 ***********************/
int disjoint_sets::find_set(int u)
{
  while (u != p[u])
    {
      u = p[u];
    }

  // returns parent  
  return u;
}



/*********************
 * UNION_SET
 *********************/
bool disjoint_sets::union_set(int u, int v)
{
  // assign parents to u, v
  u = find_set(u);
  v = find_set(v);


  // return false if parent is 0, list is empty
  if (u == 0 or v == 0)
    {
      return false;
    }


  // if u's height is less than v's (not in same set)
  if (rank[u] < rank[v])
    {
      // point u's parent to v (merge them)
      p[u] = v;

      // splice u out
      (*set[v]).splice((*set[v]).end(), (*set[u]));

      return true;
    }

  // u's height is greater than or equal to v's height  
  else
    {
      // set v's parent to u
      p[v] = u;

      // splice v out
      (*set[u]).splice((*set[u]).end(), (*set[v]));

      return true;
    }


  // if ranks are equal
  if (rank[u] == rank[v])
    {
      // increment rank of u
      rank[u]++;

      return true;
    }
}



/*********************
 * PRINT_SET
 *********************/
void disjoint_sets::print_set(std::ostream& out, int u)
{
  // begin brace for set
  out << "{ ";

  // loop through with iter, seperate with comma
  for (std::list<int>::iterator iter((*set[u]).begin()); iter != (*set[u]).end(); iter++)
    {
      out << *iter << ", ";
    }

  // end brace for set
  out << "}";
}



/*********************
 * STRING CONVERSION
 *********************/
disjoint_sets::operator std::string()
{
  // sstream variable
  std::stringstream text; 


  // pointer to int array
  int *test;
  test = new int[size+1];


  // opening paren
  text << "{ ";


  // start main loop through the array
  for (int i(1); i <= (size + 1); i++)
    {

      // if the root is empty
      if (test[find_set(i)] == 0)
        {

          // set to anything != 0?
          test[find_set(i)] = 10;


          // check if list is empty
          if (set[i]->empty())
            {
              text << "";
            }


          else
            {
              // individual set opening parenthesis
              text << "{ ";

              // use iterator to loop through and load up the stringstream, separate w/ comma
              for (std::list<int>::iterator iter((*set[i]).begin()); iter != (*set[i]).end(); iter++)
                {
                  text << *iter << ", ";
                }

              // individual set closing parenthesis w/ proper punctuation
              text << "}, ";    
            }
        }  
    }

  // closing parenthesis
  text << "}";    

  delete[] test;  

  return text.str(); 
}

驱动程序:

#include<iostream>

#include "disjoint.hpp"


int main() 
{
  using namespace std;

  disjoint_sets ds(12);

  for( int i=1; i <= 10; ++i)
    ds.make_set(i);

  ds.union_set(1,2);
  ds.union_set(2,4);
  ds.union_set(1,8);
  ds.union_set(3,6);
  ds.union_set(2,10);

  //{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }
  cout << string(ds) << endl;
}

I think my destructor is good now... but still not sure how to call print_set from within the operator() overload.

It outputs as it should, but I feel like there is an easy way to just call print_set from within the function call overload... can't seem to get things how I want them..

Header file:

/**
 * disjoint_sets class declaration
 *
 */

#include<ostream>
#include<string>
#include<list>

class disjoint_sets 
{
public:

  disjoint_sets(int n); //n is the maximum int that can be in a set, so arrays need to be of size n+1
  ~disjoint_sets();

  bool make_set(int n);
  int find_set(int u);
  bool union_set(int u, int v);
  void print_set(std::ostream& out, int u); //e.g. { 1, 2, 4, 8, 10, }

  operator std::string(); //e.g. "{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }"

private:
  typedef std::list<int>* listptr;

  int* p;       //parent array
  int* rank;    //rank array
  listptr* set; //array of pointers. Each set[i] is a pointer is to a list<int> containing the integers in the i'th set
  int size;     //the size i.e. maximum int that can be in a set

};

Implementation:

/**
 * disjoint_sets class implementation
 *
 */

#include <iostream>
#include <istream>
#include <sstream>
#include <string>
#include <list>

#include "disjoint.hpp"



/*********************
 * CONSTRUCTOR
 *********************/
disjoint_sets::disjoint_sets(int n)
{
  size = n;

  // initialize all arrays to same size (n+1)  
  p      =    new int[n+1];
  rank   =    new int[n+1];
  set    =    new listptr[n+1];

  // loop through set (array of pointers) and initialize
  //   each element to an empty list
  for (int i(1); i <= n; i++)
    {
      set[i] = new std::list<int>;
    }
}



/*********************
 * DESTRUCTOR
 *********************/
disjoint_sets::~disjoint_sets()
{
  delete[] p;
  delete[] rank;

  // delete each element in the set first, then delete the set.
  for(int i(1); i<size+1; i++)
    {
      set[i]->clear();  
    }
  delete[] set;
}



/*********************
 * MAKE_SET
 *********************/
bool disjoint_sets::make_set(int n)
{
  // if parent already exists
  if (p[n] != 0)
    {
      return false;
    }

  // else we need to make a set  
  else
    {
      // make itself the parent
      p[n] = n;

      // use push_front to add the int to front of set
      set[n]->push_front(n);

      return true;
    }
}



/*********************
 * FIND_SET
 ***********************/
int disjoint_sets::find_set(int u)
{
  while (u != p[u])
    {
      u = p[u];
    }

  // returns parent  
  return u;
}



/*********************
 * UNION_SET
 *********************/
bool disjoint_sets::union_set(int u, int v)
{
  // assign parents to u, v
  u = find_set(u);
  v = find_set(v);


  // return false if parent is 0, list is empty
  if (u == 0 or v == 0)
    {
      return false;
    }


  // if u's height is less than v's (not in same set)
  if (rank[u] < rank[v])
    {
      // point u's parent to v (merge them)
      p[u] = v;

      // splice u out
      (*set[v]).splice((*set[v]).end(), (*set[u]));

      return true;
    }

  // u's height is greater than or equal to v's height  
  else
    {
      // set v's parent to u
      p[v] = u;

      // splice v out
      (*set[u]).splice((*set[u]).end(), (*set[v]));

      return true;
    }


  // if ranks are equal
  if (rank[u] == rank[v])
    {
      // increment rank of u
      rank[u]++;

      return true;
    }
}



/*********************
 * PRINT_SET
 *********************/
void disjoint_sets::print_set(std::ostream& out, int u)
{
  // begin brace for set
  out << "{ ";

  // loop through with iter, seperate with comma
  for (std::list<int>::iterator iter((*set[u]).begin()); iter != (*set[u]).end(); iter++)
    {
      out << *iter << ", ";
    }

  // end brace for set
  out << "}";
}



/*********************
 * STRING CONVERSION
 *********************/
disjoint_sets::operator std::string()
{
  // sstream variable
  std::stringstream text; 


  // pointer to int array
  int *test;
  test = new int[size+1];


  // opening paren
  text << "{ ";


  // start main loop through the array
  for (int i(1); i <= (size + 1); i++)
    {

      // if the root is empty
      if (test[find_set(i)] == 0)
        {

          // set to anything != 0?
          test[find_set(i)] = 10;


          // check if list is empty
          if (set[i]->empty())
            {
              text << "";
            }


          else
            {
              // individual set opening parenthesis
              text << "{ ";

              // use iterator to loop through and load up the stringstream, separate w/ comma
              for (std::list<int>::iterator iter((*set[i]).begin()); iter != (*set[i]).end(); iter++)
                {
                  text << *iter << ", ";
                }

              // individual set closing parenthesis w/ proper punctuation
              text << "}, ";    
            }
        }  
    }

  // closing parenthesis
  text << "}";    

  delete[] test;  

  return text.str(); 
}

Driver:

#include<iostream>

#include "disjoint.hpp"


int main() 
{
  using namespace std;

  disjoint_sets ds(12);

  for( int i=1; i <= 10; ++i)
    ds.make_set(i);

  ds.union_set(1,2);
  ds.union_set(2,4);
  ds.union_set(1,8);
  ds.union_set(3,6);
  ds.union_set(2,10);

  //{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }
  cout << string(ds) << endl;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

各自安好 2024-12-03 02:16:07

只关注析构函数:

// delete[] set; // need special conditions for this?

是的,您需要先删除集合中的每个元素,然后再删除集合。如果您对内存管理不感兴趣,请使用 std::shared_ptr 。

提示:如果您提出具体问题,您可能会得到更好的答案。

Just focusing on the destructor:

// delete[] set; // need special conditions for this?

Yes, you need to delete each element in the set first and then delete the set. Use std::shared_ptr if you are not interested to do the memory management.

As a hint: You might get better answers if you ask concrete questions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文