【问题标题】:c++: Making a histogram with arrays, pointers, for loops. I'm right there, I'm probably thinking too hardc++:用数组、指针、for循环制作直方图。我就在那儿,我可能想太多了
【发布时间】:2017-12-03 22:36:55
【问题描述】:

这是我目前所拥有的:

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int* histogram (int arr[], int size);
double deviation (int arr[], int size);
double mean (int arr[], int size);

int main ()  {
   int scores[100];
   int count = 0;
   int temp;
   double sd;

cout << "***===***===Lab 5 - Stats===***===***\n";
cout << "Welcome to the Historgam Generator and Stardard Deviation Caluclator!" << endl;
cout << "Enter some scores, 0 to 109, limit 100, enter -1 to quit." << endl;

while (count < 109) {//puts limit on array
    cout << "Enter value " << count + 1 << ":   ";
    cin >> temp; //initialize data
    if (temp == -1) {
        break;//end program
    }
    else if (temp < 0) {
        cout << "An invalid score has been entered." << endl;
        break;//end program
    }
    else {
        scores[count] = temp;
        count++;//valid number, continue counting when entered corretly
    }
}

//help from here
//histogram (scores, count);
int* bin = histogram (scores, count);

for (int i = 0; i < count; i++) {
    int displayNo = 0;
    //bin[scores[count]]++;
    //count is the number of numbers entered.
    //scores[] is the array of scores entered by user
    //bin[9] is the address of the element in the array

    cout << displayNo << "| ";
    for (int k = 0; k < scores[i]; k++) {
        cout << '*';
    }
        cout << endl;
}

//to here

sd = deviation (scores, count);
cout << "SD: " << sd << endl;

//hold window open
system ("pause");
return 0;
}

int* histogram (int scores[], int size) {
    int* bin = new int[10];
    for (int i = 0; i < size; i++) {
        if (scores[i] >= 90) {
            bin[9]++;
    }
    else if (scores[i] >= 80 && scores[i] < 90) {
            bin[8]++;
    }
    else if (scores[i] >= 70 && scores[i] < 80) {
        bin[7]++;
    }
    else if (scores[i] >= 60 && scores[i] < 70) {
        bin[6]++;
    }
    else if (scores[i] >= 50 && scores[i] < 60) {
        bin[5]++;
    }
    else if (scores[i] >= 40 && scores[i] < 50) {
        bin[4]++;
    }
    else if (scores[i] >= 30 && scores[i] < 40) {
        bin[3]++;
    }
    else if (scores[i] >= 20 && scores[i] < 30) {
        bin[2]++;
    }
    else if (scores[i] >= 10 && scores[i] < 20) {
        bin[1]++;
    }
    else if (scores[i] >= 0 && scores[i] < 10) {
        bin[0]++;
    }
}
return bin;
}

//calculates standard deviation
double deviation (int scores[], int size) {
double avg = 0;
double sd = 0;
avg = mean (scores, size);
for (int i = 0; i < size; i++) {
    sd += pow ((scores[i] - avg), 2);
}

sd = sqrt (sd / size);
return sd;
}

//calculates the mean/average
double mean (int scores[], int size) {
    double sum = 0;
    double mean = 0;
for (int i = 0; i < size; i++){
    sum += scores[i];
}
mean = sum / size;
return mean;
}

我所要做的就是让我的程序中的直方图显示如下:

9| ***

8| **

7| *

6| ***

5| ************************

4| *******************

3| ****

2|

1|

0|

标清:15.2579


如果我输入了这个测试用例中的数字:

情况 2:30、40、45、102、35、42、65、89、55、48、56、46、42、54、56、51、47、50、51、50、50、47、 52, 53, 47, 44, 69, 35, 40, 45, 35, 42, 65, 55, 48, 100, 56, 46, 42, 54, 56, 51, 47, 50, 51, 50, 50, 47、52、53、47、78、80、95

我已经关闭了 SD 部分,但我只是不知道使用 for 循环使用什么逻辑来使它看起来像这样。我可以就上面制作的部分寻求帮助吗?

****更新**** 以下是我的导师给我的指示:

项目要求

将您的程序文件命名为 stats.cpp 不要使用任何全局变量 仅对 I/O 和格式化使用 iostream 和 iomanip 函数(无 stdio) 一次从控制台读取一个整数列表 将每个整数放入数组中 允许最多(不是总数)100 分(请参阅数组和循环(链接到外部站点。)链接到外部站点。-页面底部的示例) 输入的分数都不会

Bin 9: score ≥ 90
Bin 8: score ≥ 80 but < 90
Bin 7: score ≥ 70 but < 80
    .
    .
    .
Bin 1: score ≥ 10 but < 20
Bin 0: score < 10

请注意,分数包括一些获得额外学分的分数;你的程序必须为最高 109 的分数工作。我使用了一个名为 bin 的整数数组,并在直方图函数中填充了该数组:int bins[10]; bins 数组中的每个元素都是一个计数器,用于计算特定范围内的分数。打印直方图类似于打印 Xs 金字塔或绘制松树:使用两个 for 循环,一个嵌套在另一个内部。外循环遍历 bins 数组,内循环在给定行上打印每个 '*'。

每当您将变量用作累加器或计数器时(即,您使用它的方式如下:sum += ... 或 count++),它必须初始化为 0。自动变量和动态变量都不会自动初始化,因此程序员必须记住将其作为程序的一部分。数组只是使用同一个名称访问的变量列表,这意味着当数组用作一组累加器或计数器时,数组的每个元素都必须初始化为 0。请参见图 2(链接到外部站点.)链接到外部网站..

您的程序将有四个函数(统计函数必须遵循 main):

在程序顶部添加三个统计函数的函数原型 主要的 在这里定义你的数组 在这里阅读数据 调用直方图 打印直方图(有关所需输出的示例,请参见下面的“测试用例”) 呼叫偏差 打印标准偏差(如果需要,可以组合步骤 v 和 vi) 直方图(传入你需要的任何参数) 计算直方图 返回直方图数组,作为函数返回值(使用“return”关键字)或通过参数列表。选择数组和函数(链接到外部站点)中说明的三种技术之一。链接到外部站点.. 偏差(传入你需要的任何参数,返回一个双精度) 呼叫平均值(即所有分数的平均值) 计算标准差 返回标准差 mean(传入你需要的任何参数,返回一个双精度值) - 参见 average.cpp(链接到外部站点。)链接到外部站点。 额外学分 如果您提前完成了作业,您可以尝试以下一项或两项额外学分作业来挑战自己:

(5 分)仅使用一个循环打印直方图。请参阅我为实验 3 发布的解决方案之一以获取提示。 (5 分)仅使用计算完成要求 5(制作直方图) 您只能使用一 (1) 个循环 您的单个循环可能只包含一个语句(不使用逗号操作符作弊) 您不得使用 if、switch 或条件语句 你不能使用函数调用 您不能将任何逻辑移动到打印功能中 您可以使用多个循环来打印直方图(除非您正在做额外的信用 1),但不能填充数组 或者,要获得 5 分的额外学分,请完成上述要求 5,但您可以使用条件语句。

【问题讨论】:

  • 示例:for 循环:for ( int i = count; i &gt;= 0; --i ) { ... }int displayNo = 9; ... cout &lt;&lt; displayNo-- &lt;&lt; "| ";,我相信您可以轻松搞定其余部分。
  • 这个displayNo 只是一个显示count 的计数器,对吧?如果是这样,您可以直接使用count 而不是这个额外的变量。
  • 不允许输入超过 100 个值,写入 scores[100] 将是对大小为 100 的数组的越界访问。即代码中的109 有问题。
  • 你得到的输出是什么,有什么不满意的地方? IE。你的具体问题在哪里?
  • int displayNo = 0; 然后cout &lt;&lt; displayNo &lt;&lt; "| "; 并且在任何地方都没有更改displayNo 可能会给你很多“0|”。你可能想要cout &lt;&lt; i &lt;&lt; "| ";

标签: c++ arrays pointers for-loop histogram


【解决方案1】:

不知道你想做什么,但就是这样吗?

void histogram(int scores[], int size, int *bin)
{
   for (int i = 0; i < size; i++)
   {
       int binId = scores[i] / 10;
       if (binId > 9) binId = 9;
       bin[binId]++; 
   }
}

// called from main:
int bin[10]; // declared here as global var, so it is well destroyed
histogram(scores, size, bin); // pass bin pointer, avoid returning pointer with assigned memory from within a fonction, this will trap you.

如果 bin 始终具有相同的“排序标准”,x / 10 实际上会降低值,因此您不需要进行所有这些比较。


为了显示这样的东西?

for (int i = 0; i < 10; i++) 
{
    cout << i << "| ";
    for (int k = 0; k < bin[i]; k++) 
    {
        cout << '*';
    }
    cout << endl;
}

如果你迷失在循环中,实际上将循环变成循环会变得很棘手。有些代码有 3-4 级循环,成为一场噩梦。重构子函数将使您的代码更具可读性和更易于调试。

for (int i = 0; i < count; i++) 
{
    cout << i << "| ";
    print_stars(bin[i])
    cout << endl;
}

void print_stars(int amount)
{
    for (int k = 0; k < amount; k++) 
    {
        cout << '*';
    }
}

【讨论】:

  • 这太棒了!在代码的第一部分中,您的函数调用存在问题。我不确定如何解决它。
  • 你能指出哪里吗? bin 变量在函数外部定义,然后作为指针传递,这是为了避免按要求指定全局变量。
  • 直方图(分数、大小、&bin);
  • size 表示“没有重载函数“size”的实例与所需的类型匹配。
  • 你帮了大忙!我只是想让它工作
【解决方案2】:

在自己完成这项任务后,我想出了一个办法。目前这可能对您没有帮助,但对于任何新人来说都可以。我没有尝试返回动态数组,而是通过参数/参数返回它。

直方图原型

int* histogram(int arr[], int size, int* bin);

直方图函数

int* histogram (int arr[], int size, int* bin) {

    for (int i = 0; i < size; i++) {
        if (scores[i] >= 90) {
            bin[9]++;
        }
        else if (scores[i] >= 80 && scores[i] < 90) {
            bin[8]++;
        }
        else if (scores[i] >= 70 && scores[i] < 80) {
            bin[7]++;
        }
        else if (scores[i] >= 60 && scores[i] < 70) {
            bin[6]++;
        }
        else if (scores[i] >= 50 && scores[i] < 60) {
            bin[5]++;
        }
        else if (scores[i] >= 40 && scores[i] < 50) {
            bin[4]++;
        }
        else if (scores[i] >= 30 && scores[i] < 40) {
            bin[3]++;
        }
        else if (scores[i] >= 20 && scores[i] < 30) {
            bin[2]++;
        }
        else if (scores[i] >= 10 && scores[i] < 20) {
            bin[1]++;
        }
        else if (scores[i] >= 0 && scores[i] < 10) {
            bin[0]++;
        }
    }

    return bin;
}

在主函数中调用函数并打印直方图

int bin[10];
histogram(scores, count, bin); 

for (int i = 9; i >= 0; i--) {
    cout << i << "| ";
    for (int j = 0; j < bin[i]; j++)
    {
        cout << '*';
    }
    cout << endl;
}

【讨论】:

    猜你喜欢
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多