下面我有一段代码。我正在尝试为集合创建一个union方法,它应该调用element(int)方法来检查我正在创建的新集合中的所有元素,我在这里调用了C.我们不应该使用标准库中的联合。当我在main函数中调用A.Union(B),然后我显示它时,程序只显示我在Set A中输入的内容,但它应该返回我在我创建的新集合的所有内容联合功能。如何让这个函数返回我创建的新集合的所有内容,同时还检查元素以确保没有元素重复?
*旁注:我完全了解我的变量名,一旦我理解了如何纠正这种方法,我会更改它们。我也是一个初学者,他真的很想学习,所以我会感激建设性的批评,所以我知道如何改进。 //默认构造函数
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();
}
答案 0 :(得分:1)
Set::element
等于该集合的最后一个元素,则 false
会返回n
。否则返回true
。这可能不是你想要的。
仅当您添加两个集合中的所有元素时,newsize
也应为B.psize + psize
。但如果某些元素同时包含A
和B
,那么您就不会添加所有元素。
此外,main
函数缺少返回类型。
当我在主函数中调用A.Union(B),然后我显示它时,程序只显示我在Set A中输入的内容
但你永远不会显示A.Union(B)
。结合后,你打电话给A.display()
。毫不奇怪它显示你输入到Set A 中的内容。您甚至从未将Set::Union
返回的集合存储在变量中。
答案 1 :(得分:0)
首先,仅此一项就可以解决当前问题,您的Union
方法似乎应该提供正确的结果,但会返回一个新的集合。因此,如果您想正确使用它,您需要执行以下操作:
C = A.Union(B);
C.display();
......或更简洁:
A.Union(B).display();
当你写:
A.Union(B);
...你正在计算联合,函数返回值,但你没有捕获它,所以它只是被抛弃而且代码基本上什么都不做(就副作用而言)。 / p>
也是另一件小事,它不会影响正确性:
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;
}
它的效率相当高,因为它会在找到匹配项时退出函数,并且在找到匹配项时不会继续不必要地搜索其余的函数。
更重要的是,处理国家很难。函数中的变量越多,通常就越容易出错。因此,如果你能看到如何避免它,尽量不要引入比所需更多的变量,它会让你的生活更轻松。
如果它在查找元素时返回true而不是false,那么理解这个element
函数可能会容易一些,但这取决于你。
最后但同样重要的是,我强烈建议您学习当前编译器的调试器。如果你想要一个类似法律“欺骗”的东西,它会让你比其他学生更有优势,让你在每一个小步骤和你的代码所做的事情上接触,学习调试器并学习如何追踪您的代码并在任何给定时间查看变量的值。通过对调试器的理解,很多这些问题对您来说都会变得非常明显,并且在您变得睁大眼睛之前不会挠头并盯着代码(尽管这有时也是一种有用的练习)。