用“*”表示 C++ 中的相对频率打印直方图

时间:2021-07-25 16:24:30

标签: c++ arrays histogram

我正在尝试将具有绝对值的直方图转换为显示由用户编写的字符串中字母的相对频率的直方图。字母频率应由*表示。因此,如果字母“A”占字符串的 1%,则应该有两个 *。 1% = 2 *。

尝试计算频率时,输出为零。我真的不明白为什么。

我尝试在互联网上搜索,但我真的找不到对我有帮助的东西。我想我的头脑和编码都被卡住了。

这是我的三个函数的代码:

void berakna_histogram_abs(const string inm, int arr[ANTAL_BOKSTAVER]){

    int i, j = 0;

    while (inm[i] != '\0'){
        if (inm[i] >= 'a' && inm[i] <= 'z'){
            j = inm[i] - 'a';
            ++arr[j];
        }
        if (inm[i] >= 'A' && inm[i] <= 'Z'){
            j = inm[i] - 'A';
            ++arr[j];
        }
        i++;
    }
}
void abs_till_rel(int arr[ANTAL_BOKSTAVER], int (&ree)[ANTAL_BOKSTAVER]){

        for(int i = 0; i < ANTAL_BOKSTAVER; i++) {
            ree[i] = arr[i] / 26;
            printf("%c %lf \n", i + 'a', ree[i]);
        }

        for (int x = 0; x < ANTAL_BOKSTAVER; x++){

        }

    }

void plotta_histogram_rel(int (&ree)[ANTAL_BOKSTAVER]){

    cout << "Frekvensen av bokstäver i texten är: " << endl;
    for (int i = 0; i < ANTAL_BOKSTAVER; i++){
        cout << char(i + 'a') << " : " << ree[i] << endl;

         }
    }

我不允许在第三个函数中进行任何计算,这仅用于编写直方图。整个程序相当大,如果你愿意,我会提供所有代码。

非常感谢您的任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:1)

因此,您有一些错误需要更正。您没有将数组作为第一个函数中的引用传递。您按值传递它。因此,对第一个函数 berakna_histogram_abs 中的 arra 所做的所有修改都不会对外界可见。

您需要像在其他函数中一样做-->

void berakna_histogram_abs(const std::string inm, int (&arr)[ANTAL_BOKSTAVER]) {

顺便说一下,字符串也应该作为引用传递。反正。没那么重要。

下一个问题。您忘记在第一个函数中将变量 i 初始化为 0。因此,它将具有一些随机值并且程序将失败,因为您使用 inm[i] 访问了一些随机索引。

在您的计算函数 abs_till_rel 中,您使用了错误的公式。您需要乘以 100 以获得 0 到 100 之间的整数结果百分比。然后除以 26,结果与字母表中的字母数量有关。我的猜测是您希望与字符串中的字母数有关系。

为此,您首先需要计算所有字母计数以获得总计数。例如:

int sum = 0;
    for (int i = 0; i < ANTAL_BOKSTAVER; i++) sum += arr[i];

然后除以这个总和,如下所示:

ree[i] = (arr[i] * 100) / sum;

为了输出直方图,您可以简单地构建一个带星号的字符串,使用 std::string constructor number 2

您更新后的程序将如下所示:

#include <iostream>
#include <string>
#include <stdio.h>

constexpr int ANTAL_BOKSTAVER = 26;

void berakna_histogram_abs(const std::string inm, int (&arr)[ANTAL_BOKSTAVER]) {

    int i = 0, j = 0;

    while (inm[i] != '\0') {
        if (inm[i] >= 'a' && inm[i] <= 'z') {
            j = inm[i] - 'a';
            ++arr[j];
        }
        if (inm[i] >= 'A' && inm[i] <= 'Z') {
            j = inm[i] - 'A';
            ++arr[j];
        }
        i++;
    }
}
void abs_till_rel(int arr[ANTAL_BOKSTAVER], int(&ree)[ANTAL_BOKSTAVER]) {
    
    int sum = 0;
    for (int i = 0; i < ANTAL_BOKSTAVER; i++) sum += arr[i];

    if (sum >0) for (int i = 0; i < ANTAL_BOKSTAVER; i++) {
        ree[i] = (arr[i] * 100) / sum;
        std::cout << (char)(i + 'a') << '\t' << ree[i] << '\n';
    }

    for (int x = 0; x < ANTAL_BOKSTAVER; x++) {

    }

}

void plotta_histogram_rel(int(&ree)[ANTAL_BOKSTAVER]) {

    std::cout << "Frekvensen av bokstäver i texten är: " << std::endl;
    for (int i = 0; i < ANTAL_BOKSTAVER; i++) {
        std::cout << char(i + 'a') << " : " << std::string(ree[i]*2,'*') << std::endl;

    }
}
int main() {

    std::string test{"The quick brown fox jumps over the lazy dog"};

    int frequencyArray[ANTAL_BOKSTAVER] = {};
    int frequencyInPercent[ANTAL_BOKSTAVER] = {};

    berakna_histogram_abs(test, frequencyArray);
    abs_till_rel(frequencyArray, frequencyInPercent);
    plotta_histogram_rel(frequencyInPercent);

}

但在 C++ 中,我们将使用标准方法并编写以下内容:

#include <iostream>
#include <map>
#include <string>
#include <cctype>

// Our test string. This is a standard test string that contains all letters
std::string test{ "The quick brown fox jumps over the lazy dog" };

int main() {
    // Count all letters
    std::map<char, size_t> counter{};
    for (const auto& c : test) if (std::isalpha(c)) counter[std::tolower(c)]++;

    // Show histogram
    for (const auto& [letter, count] : counter)
        std::cout << letter << '\t' << std::string((count * 200) / test.size(), '*') << '\n';
    return 0;
}

答案 1 :(得分:0)

void abs_till_rel(int arr[ANTAL_BOKSTAVER], int langd, double frekArr[ANTAL_BOKSTAVER]){
//Function to calculate the relative frequency of letters in a string.
    for (int i = 0; i < ANTAL_BOKSTAVER; i++){

    frekArr[i] = arr[i]; //Writes over the input from the user to a new array.

    frekArr[i] = frekArr[i] * 200 / langd; //Calculates the relative frequency
    //*200 since 1% should be represented by two (2) *.
    }
}
void plotta_histogram_rel(double frekArr[ANTAL_BOKSTAVER], int langd){

    int j = 0;
    for (int i = 0; i < ANTAL_BOKSTAVER; i++){
    cout << char(i + 'A') << " : ";
//Creates a histograg, horizontal, with A-Z.

        if(frekArr[i] > 0){
        for ( j = 0; j < frekArr[i]; j++){ 
        cout << "*";
        }
        cout << endl;
        }
//If the index in frekArr is NOT empty, loop through the index [i] times and 
//write double the amount of *. 
        else {
            cout << " " << endl;
//Else, leave it empty.
        }
}
}

我已经解决了这个问题。请参阅上面的工作代码。