【问题标题】:The result wasn't what I expected what i expect结果不是我所期望的
【发布时间】:2019-03-15 06:28:20
【问题描述】:

问题是删除所有最大的数字 例如: 辛:1 2 3 4 5 cout: 1 2 3 4

辛:5 1 2 3 5 cout: 1 2 3

辛:5 5 1 2 5 cout: 1 2

辛:5 5 5 1 5 cout: 1

这里出了问题: 每当我的最大数字与其他位置一起位于第一个和最后一个位置时,代码都会打印出错误的结果 请查看这些示例以更好地理解: 辛: 5 5 1 2 5 预期cout:1 2 但它 cout: 5 1

辛:5 5 1 5 5 预期 cout:1
但它 cout: 5

我认为问题出在删除功能中,但无论我重新检查多少次,我都无法弄清楚出了什么问题,如果有人能帮我解决这个问题,我将非常高兴。 对不起我草率的写作和糟糕的英语 这是我的代码:

#include <iostream>

using namespace std;
void Insert(int a[] ,int n)
{
    for (int i=0; i<n; i++)
    {
        cout << "a[" << i << "]= ";
        cin >> a[i];
    }
}
void Delete(int a[], int n, int Biggestt)
{
    int BiggestLocation;
    for (int i=0; i<n-1; i++)
    {
        if (a[i]==Biggestt)
        {
            BiggestLocation=i;
        }
    }
    for (int i=BiggestLocation; i<n-1; i++)
    {
        a[i]=a[i+1];
    }
}
int Biggest(int a[],int n)
{
    int Biggesttt=a[0];
    for (int i=0; i<n; i++)
    {
        if (Biggesttt<a[i])
        {
            Biggesttt=a[i];
        }
    }
    return Biggesttt;
}
void PrintOut(int a[],int n)
{
    for (int i=0; i<n; i++)
    {
        cout << a[i] << " ";
    }
}
int main()
{
    int n,OriginalCount;
    int Count=0;
    cout << "Insert n: ";
    cin >>n;
    int a[100];
    Insert(a,n);
    int Biggestttt=Biggest(a,n);
    for (int i=0; i<n-1; i++)
    {
        if(a[i]==Biggestttt)
        {
            Count++;
        }
    }
    OriginalCount=Count;
    while(Count!=0)
    {
        {
            Delete(a,n,Biggestttt);
        }
        Count--;
    }
    if (a[n-1]==Biggestttt && OriginalCount==0)
    {
        PrintOut(a,n-1);
    }
    else if (a[n-1]!=Biggestttt && OriginalCount!=0)
    {
        PrintOut(a,n-OriginalCount);
    }
    else if (a[n-1]==Biggestttt && OriginalCount!=0)
    {
        PrintOut(a,n-OriginalCount-1);
    }

return 0;
}

【问题讨论】:

  • 您需要 C 数组(例如 int a[100];)还是可以使用 C++ 向量(例如 vect &lt;int&gt; a;)? (它使事情变得更容易)
  • 标题告诉我什么?请你纠正它;)我不知道它应该告诉我什么。

标签: c++


【解决方案1】:

离你不远了。您最大的问题与对所有功能使用 void function () 有关。通过使用void 作为类型,您将失去return 有效(和需要)信息的能力。

例如,在void Delete(int a[], int n, int Biggestt) 中,保留在a[] 中的元素数量将随着从数组中删除与Biggestt 匹配的每个元素而改变——但您无法返回最终的元素数量删除发生后的数组。您可以将返回类型从void 更改为int 并返回更新后的n,或者您可以将n 作为指针参数传递,这样当它在函数中更新时,其更新后的值可以返回到Delete() 返回时的调用函数。

此外,您在main() 中的逻辑非常混乱。您已经创建了函数来满足您的需求,因此main() 应该相对干净并且只需要处理几个变量。你可以这样做:

int main (void)
{
    int n, b,
        a[MAXINT];

    cout << "Insert n: ";
    if (!(cin >> n)) {      /* validate ALL user input */
        cerr << "(invalid conversion or user canceled)\n";
        return 1;
    }

    Insert (a, n);          /* insert all array values */
    cout << "original: ";   /* output the original */
    PrintOut (a, n);

    b = Biggest (a, n);     /* find the biggest number in the arry */
    Delete (a, &n, b);      /* delete all occurrences in array */

    cout << "big deleted: ";    /* output array with biggest removed */
    PrintOut (a, n);

    return 0;
}

(注意:因为您的Delete() 函数已被留下void,指向n 的指针已作为参数传递,因此删除元素后n 的最终值将可用回到调用函数(main() 这里))

把它放在一起并对Delete()中的逻辑进行调整,您可以执行以下操作:

#include <iostream>

using namespace std;

#define MAXINT 100

void Insert (int a[], int n)
{
    for (int i=0; i<n; i++)
    {
        cout << "a[" << i << "]= ";
        cin >> a[i];
    }
}

void Delete(int *a, int *n, int Biggestt)
{
    for (int i = 0; i < *n;)
    {
        if (*n > 1 && a[i] == Biggestt)
        {
            for (int j = i + 1; j < *n; j++)
                a[j-1] = a[j];
            (*n)--;     /* if biggest removed, decrement n */
        }
        else
            i++;        /* only advance if biggest not removed at index */
    }
}

int Biggest(int a[],int n)
{
    int Biggesttt=a[0];
    for (int i=1; i<n; i++)
    {
        if (Biggesttt<a[i])
        {
            Biggesttt=a[i];
        }
    }
    return Biggesttt;
}

void PrintOut(int a[],int n)
{
    for (int i=0; i<n; i++)
    {
        cout << " " << a[i];
    }
    cout << '\n';
}

int main (void)
{
    int n, b,
        a[MAXINT];

    cout << "Insert n: ";
    if (!(cin >> n)) {      /* validate ALL user input */
        cerr << "(invalid conversion or user canceled)\n";
        return 1;
    }

    Insert (a, n);          /* insert all array values */
    cout << "original: ";   /* output the original */
    PrintOut (a, n);

    b = Biggest (a, n);     /* find the biggest number in the arry */
    Delete (a, &n, b);      /* delete all occurrences in array */

    cout << "big deleted: ";    /* output array with biggest removed */
    PrintOut (a, n);

    return 0;
}

示例使用/输出

$ ./bin/remove_biggest
Insert n: 5
a[0]= 5
a[1]= 1
a[2]= 2
a[3]= 3
a[4]= 5
original:  5 1 2 3 5
*n: 3
*n: 3
*n: 3
big deleted:  1 2 3

$ ./bin/remove_biggest
Insert n: 4
a[0]= 5
a[1]= 5
a[2]= 1
a[3]= 5
original:  5 5 1 5
*n: 1
big deleted:  1

如果a[...] 中的所有数字都相同怎么办?你必须能够处理这种情况。 Delete() 中的逻辑现在保留 1 个数字,如果它们都是相同的数字。您也可以选择将它们全部保留,因为没有 Biggestt。它们同时是最大的和最小的。如何处理取决于您。

$ ./bin/remove_biggest
Insert n: 4
a[0]= 5
a[1]= 5
a[2]= 5
a[3]= 5
original:  5 5 5 5
*n: 1
big deleted:  5

如果它们都是相同的大数字,我们将删除所有它们,留下 1,因为它也是最小值。

使用引用 int&amp; n 而不是指针

响应您的评论和飞翔的建议,C++ 允许您在Delete() 中传递对n 的引用而不是指针,以确保对n 的更改在调用函数中可见(@ 987654351@ 这里)。问题的症结在于,当您简单地将参数传递给函数时,函数会收到一份副本,并且对函数内的变量所做的任何更改都会在返回时丢失。 C++ 提供了一个引用(例如int&amp; n),它本质上将别名传递给原始文件,对引用所做的任何更改都是对原始文件所做的更改。这是对传递变量的地址的改进,因为它确实避免了取消引用指针。

使用引用,Delete() 可以重写如下:

void Delete (int *a, int& n, int Biggestt)
{
    for (int i = 0; i < n;)
    {
        if (n > 1 && a[i] == Biggestt)
        {
            for (int j = i + 1; j < n; j++)
                a[j-1] = a[j];
            n--;        /* if biggest removed, decrement n */
        }
        else
            i++;        /* only advance if biggest not removed at index */
    }
}

main() 中对Delete() 的调用将是:

Delete (a, n, b);       /* delete all occurrences in array */

你已经摆脱了所谓的'*'标记:)(那个飞)

【讨论】:

  • 嘿大卫,谢谢你的回答,但你能以某种方式在没有 * 标记的情况下做到这一点,再次感谢你的时间
  • 为什么不使用引用?这是 C++。
  • 应该有,会调整的。
  • @ThaiHuynh - 您必须将n 作为指向Delete() 的指针传递,因为您不会从void 函数返回任何值。这允许n 的值在Delete() 中更新,并且更改在调用函数中可见(此处为main)。另一种方法是更改​​Delete 的返回类型,例如int Delete (int *a, int n, int Biggestt) 然后在 main 分配返回值,例如n = Delete (a, n, b); 这也很好,你可以去掉 dereferences(例如,Delete'n' 之前的 '*')。
  • 另一种方法是将n 作为参考传递——这也允许您避免取消参考(这是一种 C 方式)。我会放弃更新。
【解决方案2】:
#include <iostream>

using namespace std;
void Insert(int a[] ,int n)
{
    for (int i=0; i<n; i++)
    {
        cout << "a[" << i << "]= ";
        cin >> a[i];
    }
}
void Delete(int a[], int n, int Biggestt)
{
    int BiggestLocation;
    for (int i=0; i<n-1; i++)
    {
        if (a[i]==Biggestt)
        {
            a[i]=-1;
        }
    }
    for (int i=1; i<n; i++)
    {
        if(a[i-1]==-1)
        a[i-1]=a[i];
    }
}
int Biggest(int a[],int n)
{
    int Biggesttt=a[0];
    for (int i=0; i<n; i++)
    {
        if (Biggesttt<a[i])
        {
            Biggesttt=a[i];
        }
    }
    return Biggesttt;
}
void PrintOut(int a[],int n)
{
    for (int i=0; i<n; i++)
    {
        cout << a[i] << " ";
    }
}
int main()
{
    int n,OriginalCount;
    int Count=0;
    cout << "Insert n: ";
    cin >>n;
    int a[100];
    Insert(a,n);
    int Biggestttt=Biggest(a,n);
    for (int i=0; i<n-1; i++)
    {
        if(a[i]==Biggestttt)
        {
            Count++;
        }
    }
    OriginalCount=Count;
    while(Count!=0)
    {
        {
            Delete(a,n,Biggestttt);
        }
        Count--;
    }
    if (a[n-1]==Biggestttt && OriginalCount==0)
    {
        PrintOut(a,n-1);
    }
    else if (a[n-1]!=Biggestttt && OriginalCount!=0)
    {
        PrintOut(a,n-OriginalCount);
    }
    else if (a[n-1]==Biggestttt && OriginalCount!=0)
    {
        PrintOut(a,n-OriginalCount-1);
    }

return 0;
}

试试这个代码。 只需将所有最大数的实例等同于 -1,然后用不等于 -1 的相邻元素覆盖它们。

【讨论】:

  • 只要将所有最大数的实例等同于-1,然后用不等于-1的相邻元素覆盖它们。
  • 张贴不解释的代码块是没有用的。
  • 虽然此代码可能有效,但最好告诉 OP 进行了哪些更改。
  • 感谢您的建议。我忘了添加解释。这就是为什么我在我的答案下面评论了解释。不要在没有看到整个对话的情况下放弃投票。
  • @ChallaSaiBhanuTeja 您必须编辑您的答案才能发布解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
相关资源
最近更新 更多