使用动态内存的集合并集
Union of Sets using Dynamic Memory
下面是一段代码。我正在尝试为集合创建联合方法,它应该调用 element(int) 方法来检查我正在创建的新集合中的所有元素,我在这里将其称为 C。我们不应该使用标准库中 set 的联合。当我在 main 函数中调用 A.Union(B) 然后显示它时,程序只显示我输入到 Set A 中的任何内容,但它应该 return 新的所有内容设置我在联合函数中创建的。我怎样才能让这个函数 return 我创建的新集合的所有内容,同时还检查元素以确保没有重复的元素?
*旁注:我完全知道我的变量名,一旦我了解如何更正此方法,我将更改它们。我也是一个初学者,他真的很想学习,所以我很感激建设性的批评,这样我就可以知道如何改进。
//默认构造函数
Set::Set ( int s ){
if ( s > 0 )
psize = s;
else
psize = DEFAULTSIZE;
//allocate an array of specified size
set = new int[ psize ];
if(!set) {
//send an error is system cannot allocate memory
cout << "Cannot Allocate Memory, exiting program... " << endl;
exit (1);
}
for ( int i = 0; i < psize; i++){
set[i] = 0;
numOfElements = 0;
}
}
bool Set::element ( int n ){
for ( int i = 0; i < psize; i++){
if ( set[i] == n )
return true;
}
return false;
}
Set Set::Union( Set &B ){
int newsize = B.numOfElements + numOfElements;
Set C(newsize);
for (int i = 0; i < numOfElements; i++){
C.set[i] = set[i];
}
int indx = 0;
for(int i = 0; i < B.numOfElements; i ++){
if(C.element(B.set[i])){
newsize--;
continue;
}
else
{
C.set[indx + numOfElements] = B.set[i];
indx++;
}
}
C.numOfElements = newsize;
C.display();
return (C);
}
Set Set::Intersection( Set &B ) {
int newsize = numOfElements;
Set C(newsize);
for ( int i = 0; i < numOfElements; i++ ){
if( element(B.set[i]))
C.set[i] = B.set[i];
else{
newsize--;
continue;
}
}
return (C);
}
Set Set::operator-( int n ){
for ( int i = 0; i < numOfElements; i++){
if(element(n)){
delete set[i];
numOfElements--;
}
}
psize = numOfElements;
return (*this);
}
main (){
Set A, B, C;
A.input();
A.display();
B.input();
B.display();
C = A.Union(B);
C.display();
}
Set::element
returns false
如果 n
等于集合的最后一个元素。否则它 returns true
。这可能不是您想要的。
另外 newsize
应该是 B.psize + psize
只有当你从两个集合中添加所有元素。但是,如果某些元素同时存在于 A
和 B
中,那么您就不会将它们全部添加。
此外,main
函数缺少 return 类型。
When I call A.Union(B) in the main function, and then I display it, the program is only displaying whatever I inputted into Set A
但你永远不会显示 A.Union(B)
。合并后,你调用A.display()
。毫不奇怪,它会显示您 在集合 A 中输入的内容。您甚至从未将 Set::Union
编辑的集合 return 存储在变量中。
首先,仅此一项就应该解决眼前的问题,您的 Union
方法似乎应该提供正确的结果,但它 returns[=38= 】 一套新的。所以如果你想正确使用它,你想做这样的事情:
C = A.Union(B);
C.display();
...或更简洁:
A.Union(B).display();
当你写:
A.Union(B);
...你在计算并集,函数 returns 的值,但你没有捕获它,所以它就被扔掉了,代码基本上什么都不做(就术语而言)副作用)。
另外一个小东西,不会影响正确性:
bool Set::element ( int n ) {
bool validate = true;
for ( int i = 0; i < psize; i++){
if ( set[i] == n )
validate = false;
}
return (validate);
}
...这部分可以简单地是:
bool Set::element ( int n ) {
for ( int i = 0; i < psize; i++){
if ( set[i] == n )
return false;
}
return true;
}
它的效率要高得多,因为它会在找到匹配项的那一刻退出函数,并且不会在已经找到匹配项时继续不必要地搜索集合的其余部分。
但更重要的是,处理状态很困难。函数中的变量越多,通常越容易出错。因此,如果您知道如何避免它,请尽量不要引入超出需要的变量,这会让您的生活更轻松。
如果这个 element
函数在查找元素时返回 true 而不是 false,那么它可能更容易理解,但这取决于您。
最后但并非最不重要的一点是,我强烈建议您学习适用于您目前拥有的任何编译器的调试器。如果你想要一些类似于合法 "cheat" 的东西,它会让你比其他学生更有优势,让你了解你的代码在每一个小步骤中做了什么以及它有什么问题,学习调试器并学习如何跟踪您的代码并在任何给定时间查看变量的值。通过对调试器的理解,很多这些问题对你来说会立即变得显而易见,并且不会挠头盯着代码直到你变成斗鸡眼(尽管这有时也是一个有用的练习)。
下面是一段代码。我正在尝试为集合创建联合方法,它应该调用 element(int) 方法来检查我正在创建的新集合中的所有元素,我在这里将其称为 C。我们不应该使用标准库中 set 的联合。当我在 main 函数中调用 A.Union(B) 然后显示它时,程序只显示我输入到 Set A 中的任何内容,但它应该 return 新的所有内容设置我在联合函数中创建的。我怎样才能让这个函数 return 我创建的新集合的所有内容,同时还检查元素以确保没有重复的元素?
*旁注:我完全知道我的变量名,一旦我了解如何更正此方法,我将更改它们。我也是一个初学者,他真的很想学习,所以我很感激建设性的批评,这样我就可以知道如何改进。 //默认构造函数
Set::Set ( int s ){
if ( s > 0 )
psize = s;
else
psize = DEFAULTSIZE;
//allocate an array of specified size
set = new int[ psize ];
if(!set) {
//send an error is system cannot allocate memory
cout << "Cannot Allocate Memory, exiting program... " << endl;
exit (1);
}
for ( int i = 0; i < psize; i++){
set[i] = 0;
numOfElements = 0;
}
}
bool Set::element ( int n ){
for ( int i = 0; i < psize; i++){
if ( set[i] == n )
return true;
}
return false;
}
Set Set::Union( Set &B ){
int newsize = B.numOfElements + numOfElements;
Set C(newsize);
for (int i = 0; i < numOfElements; i++){
C.set[i] = set[i];
}
int indx = 0;
for(int i = 0; i < B.numOfElements; i ++){
if(C.element(B.set[i])){
newsize--;
continue;
}
else
{
C.set[indx + numOfElements] = B.set[i];
indx++;
}
}
C.numOfElements = newsize;
C.display();
return (C);
}
Set Set::Intersection( Set &B ) {
int newsize = numOfElements;
Set C(newsize);
for ( int i = 0; i < numOfElements; i++ ){
if( element(B.set[i]))
C.set[i] = B.set[i];
else{
newsize--;
continue;
}
}
return (C);
}
Set Set::operator-( int n ){
for ( int i = 0; i < numOfElements; i++){
if(element(n)){
delete set[i];
numOfElements--;
}
}
psize = numOfElements;
return (*this);
}
main (){
Set A, B, C;
A.input();
A.display();
B.input();
B.display();
C = A.Union(B);
C.display();
}
Set::element
returns false
如果 n
等于集合的最后一个元素。否则它 returns true
。这可能不是您想要的。
另外 newsize
应该是 B.psize + psize
只有当你从两个集合中添加所有元素。但是,如果某些元素同时存在于 A
和 B
中,那么您就不会将它们全部添加。
此外,main
函数缺少 return 类型。
When I call A.Union(B) in the main function, and then I display it, the program is only displaying whatever I inputted into Set A
但你永远不会显示 A.Union(B)
。合并后,你调用A.display()
。毫不奇怪,它会显示您 在集合 A 中输入的内容。您甚至从未将 Set::Union
编辑的集合 return 存储在变量中。
首先,仅此一项就应该解决眼前的问题,您的 Union
方法似乎应该提供正确的结果,但它 returns[=38= 】 一套新的。所以如果你想正确使用它,你想做这样的事情:
C = A.Union(B);
C.display();
...或更简洁:
A.Union(B).display();
当你写:
A.Union(B);
...你在计算并集,函数 returns 的值,但你没有捕获它,所以它就被扔掉了,代码基本上什么都不做(就术语而言)副作用)。
另外一个小东西,不会影响正确性:
bool Set::element ( int n ) {
bool validate = true;
for ( int i = 0; i < psize; i++){
if ( set[i] == n )
validate = false;
}
return (validate);
}
...这部分可以简单地是:
bool Set::element ( int n ) {
for ( int i = 0; i < psize; i++){
if ( set[i] == n )
return false;
}
return true;
}
它的效率要高得多,因为它会在找到匹配项的那一刻退出函数,并且不会在已经找到匹配项时继续不必要地搜索集合的其余部分。
但更重要的是,处理状态很困难。函数中的变量越多,通常越容易出错。因此,如果您知道如何避免它,请尽量不要引入超出需要的变量,这会让您的生活更轻松。
如果这个 element
函数在查找元素时返回 true 而不是 false,那么它可能更容易理解,但这取决于您。
最后但并非最不重要的一点是,我强烈建议您学习适用于您目前拥有的任何编译器的调试器。如果你想要一些类似于合法 "cheat" 的东西,它会让你比其他学生更有优势,让你了解你的代码在每一个小步骤中做了什么以及它有什么问题,学习调试器并学习如何跟踪您的代码并在任何给定时间查看变量的值。通过对调试器的理解,很多这些问题对你来说会立即变得显而易见,并且不会挠头盯着代码直到你变成斗鸡眼(尽管这有时也是一个有用的练习)。