Как напечатать массив int по блокам чисел? (Печать гистограммы)

#c #arrays #histogram

#c #массивы #гистограмма

Вопрос:

Для этой программы я должен сгенерировать определенное количество случайных целых чисел с заданным диапазоном. Например, 100 целых чисел между 0-10.

Я создал массив распределения (называемый distTab), который показывает, сколько раз было сгенерировано определенное число. Затем я печатаю числа в виде звездочек в цикле for. проверьте изображение ниже.

введите описание изображения здесь

Это хорошо работает для 0-10, но, допустим, я генерирую 10000 чисел в диапазоне 0-1000, моя функция печати печатает каждый индекс distTab. Я хотел бы сократить его по диапазону и добавить значения индекса друг к другу в этом диапазоне. Например, между 0-100 -> 20 звездочками, 101-200 -> 21 звездочкой и так далее.

Вот мой код для печати гистограммы в данный момент:

 int inc=0;

printf("n%st%sn","Number", "Histogramn");
for(int i=0; i <= max; i  ) {
    if(distTab[i]==0)       
        continue;

    printf("  %dt",i);
    int lim = distTab[i];

    for(int j=1; j<=lim; j  ){          
        printf("*");
        inc  ;
    }
    printf("n");
}
  

Случайные числа и distTab создаются следующим образом (в цикле for):

 int distTab[MAX_RAND];
memset(distTab, 0, sizeof distTab);

//for(0 -> desired number of ints)
    rnd = (rand() % limit) 1;
    if (max < rnd)
        max = rnd;  //max value generated.
    distTab[(int)rnd]  ;
//}
  

Заранее спасибо за ваше время, и я надеюсь, что я объяснил свой вопрос так ясно, как мог.

Комментарии:

1. Что вы пробовали?

2. Вам нужно написать функцию int myfunc(int value) (я позволю вам найти более подходящее название функции), которая возвращает 20, если value находится между 0 и 100, 21, если value находится между 101 и 200, 22 для value между 201 и 300 и т.д. Подсказка : начните с карандаша и листа бумаги.

Ответ №1:

Масштабируйте гистограмму. Или еще лучше напечатать это в процентах. Я бы сделал что-то вроде

 lim = distTab[i] / max_distTab * max_lim;
  

Таким образом, ваше наиболее частое значение всегда будет одинаковым с .

Ответ №2:

Вот как я бы сделал это для чисел от 0 до 9999 и диапазонов от 100:

 int inc=0;
int count[10] = {0};
printf("n%st%sn","Number", "Histogramn");
for(int i = 0; i <= max; i  ) {
    if(distTab[i]==0)       
        continue;

    count[max % 100]  = distTab[i];
 }

 for (int i = 0; i < 10;   i){
    printf("M-Mt",i * 100, (i   1) * 100);
    int lim = count[i];

    for(int j=1; j<=lim; j  ){          
        printf("*");
        inc  ;
    }
    printf("n");
}
  

Я использовал жесткие значения, чтобы избежать массива переменной длины, однако лучшей практикой было бы либо malloc вашего массива, либо использовать define.

Если вам нужен пользовательский диапазон, вы также можете использовать другой массив отсортированных значений int:

 int ranges[] = {100, 300, 450, 600, 1000};
// assuming ranges is sorted
int get_index(int value, int* ranges){
  int count = 0;
  if (value > ranges[ranges.size() - 1])
    return -1;
  while (value < ranges[count])
      count;
  return count;
}
  

и заменить

 for(int i = 0; i <= max; i  ) {
    if(distTab[i]==0)       
        continue;

    count[max % 100]  = distTab[i];
 }
  

Автор: :

 for(int i = 0; i <= max; i  ) {
    if(distTab[i]==0)       
        continue;

    count[get_index(i, ranges)]  = distTab[i];
 }
  

Комментарии:

1. Спасибо! В настоящее время я внедряю ваши предложения в свой код. Буду держать вас в курсе, если это сработает. Это не кажется слишком сложным, но я просто не могу обмозговать это.

2. Какую часть вы хотели бы, чтобы я прояснил?