错误:通过指针显示重复的结果



目标状态:我应该显示一个结果,其中随机化,例如集合 S = {狗、牛、鸡...},其中随机大小可以是 1-12,动物不能复制,所以一旦有牛,集合 S 中就不能再有另一头牛了。

错误:我一直显示正确的随机大小 1-12。但是,即使我尝试在将动物插入 S 集之前检查动物是否存在于集合 S 中,我也有复制动物。

更新我无法让它在堆栈溢出对等方进行各种更新后运行。

约束:我必须使用指针与指针进行比较 - 动态。 "重要说明 应动态创建用于阵列的所有存储;并在以下情况下删除它们 不再需要它们。 当访问数组的元素时,你应该通过指针访问它,即 取消引用此指针。使用符号,例如集合 [k] 或 *(集合 + k) 不允许访问集合的第 k 个元素。

希望听到你的建议,朋友们!

此致敬意 毫米

/* 
MarcusMoo_A2.cpp by Marcus Moo
Full Time Student
I did not pass my assignment to anyone in the class or copy anyone’s work; 
and I'm willing to accept whatever penalty given to you and 
also to all the related parties involved 
*/
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
/* Global Declaration */
const int MAX = 12; // 12 animals
const int MAXSTR = 10; 
typedef char * Element;
static Element UniversalSet [MAX] = {"Rat", "Ox", "Tiger", "Rabbit", "Dragon",
"Snake", "Horse", "Sheep", "Monkey", "Rooster", "Dog", "Pig"};
/* Functions */
// Construct a set
void option0(int); // Menu Option 0
void constructSet (Element *, int); // Construct a set
bool checkElement (Element *, Element *, int); // Check element for replicates
int main()
{   
// Declarations
int mainSelect;
int size=rand()%12+1; // Random construct

srand (time(NULL)); // Even better randomization
cout << "Welcome to MARCUS MOO Learning Center" << endl;
do 
{
cout << "0. An example of set" << endl;
cout << "1. Union" << endl;
cout << "2. Intersection" << endl;
cout << "3. Complement" << endl;
cout << "4. Subset of" << endl;
cout << "5. Equality" << endl;
cout << "6. Difference " << endl;
cout << "7. Distributive Law" << endl;
cout << "9. Quit" << endl;
cout << endl;
if (mainSelect==0)
{
option0(size);
}
cout << "Your option: ";
cin >> mainSelect;
cout << endl;
} while(mainSelect!=9);
return 0;
}
/* Functions */
// Option 0 - An example of set
void option0 (int size)
{
// Mini Declaration
int again;
Element *S;
do 
{
cout << "Here is an example on set of animals" << endl;
cout << endl;
// Build set S
constructSet (S,size);

// Display set S
Element *S = &S[0];
cout << "Set S = {";
for (int i = 0; i < size; i++)
{
if (i!=size)
{
cout << *S
<< ", ";
}
else 
{
cout << *S
<< "}"
<< endl;
}     
S++;      
} 

cout << endl;
cout << "Note that elements in S are distinct are not in order" << endl;
cout << endl;
// Option 0 2nd Part
cout << "Wish to try the following operations?" << endl;
cout << "1. Add an element to the set" << endl;
cout << "2. Check the element in the set" << endl;
cout << "3. Check the cardinality" << endl;
cout << "9. Quit" << endl;
cout << endl; 
cout << "Your choice: ";
cin >> again;
} while (again!=9);   
}
// Construct a set 
void constructSet (Element *set, int size)
{
// Declarations
Element *ptrWalk;
ptrWalk = &set[0];
int randomA=0;
for (int i = 0;i<size;i++)
{
bool found = true;
while (found) 
{
randomA = rand()%MAX;  // avoid magic numbers in code...
*ptrWalk = UniversalSet [randomA];
// Ensure no replicated animals in set S
found = checkElement (ptrWalk, set, i);
}
set=ptrWalk;
set++;         
}
}
bool checkElement (Element *ptrWalk, Element *set, int size)
{
for (int j=0; j<size;j++)
{
if (ptrWalk==&set[j])
{
return true;
}
}
return false;
}

你的代码中有 2 个不同的主要问题。Federico已经给出了第一个:一旦找到一个元素checkElement就应该返回true。代码应该变得简单(但请注意j<size中的<):

bool checkElement (char *ptrWalk, int size)
{
for (int j=0; j<size;j++)
{
if (ptrWalk==S[j])
{
return true;
}
}
return false;
}

第二个问题是,您不应该搜索整个数组,而应该只搜索已经填充的部分。这意味着在constructSet中,您应该调用checkElement(ptrWalk, i),因为当前元素的索引是已填充项的数量。所以你必须更换两倍的生产线

found = checkElement (*ptrWalk, size);

有了这个

found = checkElement (*ptrWalk, i);

这应该足以让您的程序提供预期的结果。但是,如果您希望它很好,仍然有一些改进:

  • 您正确声明了int main()但在main末尾忘记了return 0;
  • 在定义函数之前调用函数时,您未能转发声明它们(至少应该引起警告......
  • 您大量使用全局变量,这不是一个好的做法,因为它不允许轻松测试
  • 您的算法应该简化为遵循不要重复自己原则。代码重复对将来的维护不利,因为如果强制在不同的地方应用代码更改并且遗漏这样做会导致令人讨厌的错误(看起来这很糟糕,但我已经修复了它 - 是的,但只在一个地方......

constructSet可以简单地说:

// Construct a set 
void constructSet (Element *set, int size)
{
// Declarations
//Element *ptrBase;
voidPtr *ptrWalk;
ptrWalk = &set[0];
int randomA=0;
for (int i = 0;i<size;i++)
{
bool found = true;
while (found) {
randomA = rand()%MAX;  // avoid magic numbers in code...
*ptrWalk = UniversalSet [randomA];
// Ensure no replicated animals in set S
found = checkElement (*ptrWalk, i);
}
ptrWalk++;          
}
}

主要问题是一旦找到元素,checkElement() 中就会缺少 'break'。如果你不打破循环,它将与其他索引进行比较并覆盖"found"标志。

if (ptrWalk==S[j])
{
found = true;
break;
}

此外,使用 ptrWalk 作为临时变量来保存字符串。只有在确保字符串不存在后,才将字符串添加到 S。

void constructSet (Element *set, int size)
{
// Declarations
//Element *ptrBase;
Element ptrWalk;
//ptrWalk = &set[0];
int randomA=0;
int randomB=0;
bool found = false;
for (int i = 0;i<size;i++)
{
randomA = rand()%12; 
ptrWalk = UniversalSet [randomA];
// Ensure no replicated animals in set S
found = checkElement (ptrWalk, i);
if (found==true)
{
do 
{
// Define value for S
randomB = rand()%12;
ptrWalk = UniversalSet [randomB];
found = checkElement (ptrWalk, i);  
} while(found==true);
S[i] = UniversalSet [randomB];
//ptrWalk++;
}
else 
{        
// Define value for S
S[i] = UniversalSet [randomA];
//ptrWalk++;          
}
}

}

您需要通过删除不必要的变量并使其不那么复杂来优化代码。

我已经在我的C++讲师的指导下解决了这个问题!你们下次可以参考一下,解决你们的指针困境!干杯!

/* 
MarcusMoo_A2.cpp by Marcus Moo
Full Time Student
I did not pass my assignment to anyone in the class or copy anyone’s work; 
and I'm willing to accept whatever penalty given to you and 
also to all the related parties involved 
*/
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
/* Global Declaration */
const int MAX = 12; // 12 animals
const int MAXSTR = 10; 
typedef char * Element;
static Element UniversalSet [MAX] = {"Rat", "Ox", "Tiger", "Rabbit", "Dragon",
"Snake", "Horse", "Sheep", "Monkey", "Rooster", "Dog", "Pig"};
/* Functions */
// Construct a set
void option0(int); // Menu Option 0
void constructSet (Element *, int); // Construct a set
bool checkElement (Element, Element *, int); // Check element for replicates
// This function is to get a random element
// with storage allocated
Element getAnElement ()
{
Element *p = &UniversalSet [0];
int k = rand () % MAX;
for (int i = 0; i < k; i++)
++p;
Element e = new char [MAXSTR];
strcpy (e, *p);
return e;
}
int main()
{   
// Declarations
int mainSelect;
int size=rand()%12; // Random construct

srand (time(NULL)); // Even better randomization
cout << "Welcome to MARCUS MOO Learning Center" << endl;
do 
{
cout << "0. An example of set" << endl;
cout << "1. Union" << endl;
cout << "2. Intersection" << endl;
cout << "3. Complement" << endl;
cout << "4. Subset of" << endl;
cout << "5. Equality" << endl;
cout << "6. Difference " << endl;
cout << "7. Distributive Law" << endl;
cout << "9. Quit" << endl;
cout << endl;
if (mainSelect==0)
{
option0(size);
}
cout << "Your option: ";
cin >> mainSelect;
cout << endl;
} while(mainSelect!=9);
return 0;
}
/* Functions */
// Option 0 - An example of set
void option0 (int size)
{
// Mini Declaration
int again;
Element *S;
// You need to assign storage
S = new Element [MAX];
for (int i = 0; i < MAX; i++)
S [i] = new char [MAXSTR];

do 
{
cout << "Here is an example on set of animals" << endl;
cout << endl;
// Build set S
constructSet (S,size);

// Display set S
Element *p = &S[0];  // Change to p
cout << "Set S = {";
for (int i = 0; i < size; i++)
{
if (i!=size-1)
{
cout << *p
<< ", ";
}
else 
{
cout << *p
<< "}"
<< endl;
}     
p++;      
} 

cout << endl;
cout << "Note that elements in S are distinct are not in order" << endl;
cout << endl;
// Option 0 2nd Part
cout << "Wish to try the following operations?" << endl;
cout << "1. Add an element to the set" << endl;
cout << "2. Check the element in the set" << endl;
cout << "3. Check the cardinality" << endl;
cout << "9. Quit" << endl;
cout << endl; 
cout << "Your choice: ";
cin >> again;
} while (again!=9);   
}
// Construct a set 
void constructSet (Element *set, int size)
{
// Declarations
Element *ptrWalk;
ptrWalk = &set[0];
int randomA=0;
Element temp = new char [MAXSTR];
for (int i = 0;i<size;i++)
{
bool found = true;
while (found) 
{
// randomA = rand()%MAX;  ..
temp = getAnElement ();
// Ensure no replicated animals in set S
found = checkElement (temp, set, i);
}
// set=ptrWalk;
// set++;

strcpy (*ptrWalk, temp);
++ptrWalk;         
}
}
bool checkElement (Element ptrWalk, Element *set, int size)
{
Element *p = &set[0];
for (int j=0; j<size;j++)
{
if (strcmp (ptrWalk, *p) == 0)
{
return true;
}
p++;
}
return false;
}

最新更新