【问题标题】:Error : Display duplicated results via pointer错误:通过指针显示重复的结果
【发布时间】:2017-05-05 08:02:30
【问题描述】:

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

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

更新:在 stackoverflow 对等方进行各种更新后,我无法让它运行。

约束:我必须使用指针与指针进行动态比较。 “重要的提示 用于数组的所有存储都应动态创建;并在何时删除它们 他们不再需要。 访问数组的元素时,您应该通过指针访问它,即通过 取消引用这个指针。使用符号,例如 set [k] 或 *(set + 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;
}

【问题讨论】:

  • checkElement 应该在找到重复项后立即返回 true,否则它将始终返回 false,除非它是被重复的最后一个元素
  • imho typedefing 内置类型然后不始终使用 typedefs 是非常令人困惑的。例如。 ptrWalk==S[j]Elementchar* 进行比较,它们实际上是相同的
  • @tobi303 明白了!
  • @FedericoklezCulloca 明白你的意思!
  • @FedericoklezCulloca 一旦我将其更改为返回 bool found=true。编译器在显示结果时卡住了

标签: c++ arrays pointers char


【解决方案1】:

您的代码中有两个不同的主要问题。 Federico 已经给出了第一个:checkElement 应该在找到一个元素后立即返回 true。代码应该变得简单(但请注意j&lt;size中的&lt;):

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++;          
    }
}

【讨论】:

  • while(found) 是什么意思?
  • 你介意重新审视我的代码,因为我有新的限制!干杯兄弟
【解决方案2】:

主要问题是 checkElement() 找到元素后会丢失“break”。如果您不中断循环,它将与其他索引进行比较并覆盖“找到”标志。

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++;          
    }
}

}

您需要通过删除不必要的变量并降低其复杂性来优化您的代码。

【讨论】:

  • 你介意重新审视我的代码吗,因为我对它做了一些小修改
【解决方案3】:

在我的 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-30
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    相关资源
    最近更新 更多