Отладка гистограммы в C - PullRequest
       5

Отладка гистограммы в C

0 голосов
/ 18 декабря 2010

Первый вопрос здесь о переполнении стека, так что простите, если это оффтоп или нет для каждого этикета, но кажется, что все должно быть в порядке. Я делаю упражнение 1-13 в K & R, специально печатая вертикальную гистограмму длины слов на входе. Вот мой код:

#include <stdio.h>

#define UPPER 10
#define ABOVE (UPPER+1)

main()
{
    int i, c, wcounter, j;
    int wlengths[ABOVE];
    int maxHistHeight;

    for (i = 0; i <= ABOVE; ++i)        /* Initialize everything to zero */
        wlengths[i] = 0;

    wcounter = maxHistHeight = 0;

    while((c = getchar()) != EOF){      /* Count word lengths */
        if (c != ' ' && c != '\t' && c != '\n'){
            ++wcounter;
        } 
        else if (wcounter >= ABOVE){
            ++wlengths[ABOVE];
            wcounter = 0;
        }else if (wcounter != 0){   
            ++wlengths[wcounter];
            wcounter = 0;
        }
    }

    for (i = 1; i <= ABOVE; ++i)       /*For testing purposes. See if the array is holding correct values*/
        printf(" %d ",wlengths[i]);

    printf("\n");

    for (i = 1; i <= ABOVE; ++i)        /*Get the Maximum height for histogram */
        if (wlengths[i]>maxHistHeight)
            maxHistHeight = wlengths[i];

    printf("Histogram of length of words\n");   /* Print histogram */
    printf("----------------------------\n");

    for (i = maxHistHeight; i >= 0; --i){  /* Start at top of histogram, and go downwards */
        printf("\n");   
        for (j = 1; j <= ABOVE; ++j){      /*For each level of histogram, go through all the */
            if (i == 0 && j != ABOVE){     /*Arrays, and see if they contain an X in that level */
                printf(" %d ", j);
            }else if (i == 0 && j == ABOVE){
                printf(">%d",UPPER);
            }
            else if (wlengths[j]>=i){
                printf(" X ");
            }
            else{ 
                printf("   ");
            }    
        }           
    }
    printf("\n");    
}

Я хочу напечатать гистограмму длины слов длиной 1-10 букв, а также длиной более 10 букв. Я хочу, чтобы это выглядело так:

Гистограмма длины слов

                               X 
       X  X                    X 
 1  2  3  4  5  6  7  8  9  10 >10

Я использую массив размером 12 (не уверен, так ли это, как вы бы это сказали), с 11-м индексом, содержащим все вхождения слов длиной более 10 букв. Однако, когда я распечатываю гистограмму, она печатает «X» в месте> 10, даже если слово имеет длину всего 10 букв. Поэтому, если я введу это:

1234567890
123457890
1234567890

Я получаю:

Histogram of length of words
----------------------------

                            X  X 
                         X  X  X 
 1  2  3  4  5  6  7  8  9  10 >10

Я подумал, что, должно быть, что-то не так с тем, как я увеличивал свой массив, поэтому я напечатал значения массива и получил это:

 0  0  0  0  0  0  0  0  1  2  0 

, что не соответствует тому, что печатает моя гистограмма. Я ценю любую помощь!

ОБНОВЛЕНИЕ ОРИГИНАЛЬНОГО ВОПРОСА

Итак, я установил размер моего массива, чтобы он содержал 12 элементов: 10 для хранения слов длиной 1-10, 1 для всех слов длиной> 10 и 1 для индекса 0, чтобы мои индексы совпадали с длинами моих слов , Раньше у меня был массив только с 11 элементами, когда мне нужно было его 12, но когда я распечатывал значения моего массива, он отображал правильные значения, но во время печати гистограммы он был неправильным. поэтому с учетом ввода этого:

1234567890
1234567890
12345678901234567890
12345

Я получил это в массиве (я печатаю из индекса 1 в индекс 11), и это правильно:

 0  0  0  0  1  0  0  0  0  2  1 

Но распечатка гистограммы другая:

Histogram of length of words
----------------------------

                            X  X 
          X                 X  X 
 1  2  3  4  5  6  7  8  9  10 >10

Разве они не должны быть одинаковыми?

Ответы [ 3 ]

1 голос
/ 18 декабря 2010

Ваш массив имеет размерность ABOVE (= 11), но вы перебираете от 0 до ABOVE (включительно), что составляет ABOVE + 1 (= 12) элементов. Допустимый диапазон индексов - от 0 до ABOVE - 1, поэтому вы пишете (и затем читаете) за пределами выделенного массива.

например. Ваш цикл инициализации должен быть:

for (i = 0; i < ABOVE; ++i)        /* Initialize everything to zero */
    wlengths[i] = 0;

Я думаю, что вы, вероятно, запутались, потому что индексы массива C начинаются с 0, в то время как ваша гистограмма должна представлять длины слов от 1 до 10, а затем 11 для длин слов> 10. Вы можете подойти к этому одним из двух способов, либо:

(a) с учетом разницы 1, чтобы слова длины 1 помещались в ячейку 1, слова длины 2 помещались в ячейку 1 и т. Д., Или

(b) выделить дополнительный элемент (т.е. сделать массив на один элемент больше, чем нужно) и просто не использовать элемент 0. Таким образом, вам не нужно беспокоиться о смещении 1.

0 голосов
/ 18 декабря 2010

Хорошо, я думаю, что понимаю, что вы, ребята, имели в виду. Мой массив должен иметь возможность хранить 12 элементов, при условии, что я использую индексы 1-10 для длин слов 1-10, индекс 11 для всех этих длин слов> 10 и, наконец, индекс 0 отбрасывается, потому что я хочу, чтобы номера индексов выровняйте с моими длинами слова. Я установил размер массива на 12, или на 2 больше, чем моя верхняя константа, и это, похоже, помогло. Вот мой вывод:

Histogram of length of words
----------------------------

                            X    
             X              X  X 
 1  2  3  4  5  6  7  8  9  10 >10

с учетом этого ввода:

1234567890 
1234567890
12345
12345678901234567890
0 голосов
/ 18 декабря 2010

Длины: если вы объявите массив как вещи [LEN], то массив может содержать вещи LEN.

Индексы: Но элементы массива индексируются от 0 до LEN-1 и доступны как вещи [0], вещи [1], ..., вещи [LEN - 1]

Таким образом, вы обычно будете видеть циклы, выглядящие так: for (i = 0; i

Проблема в том, что вам нужны длины слов от 1 до 10, поэтому вам необходимо соответствующим образом настроить индексы массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...