Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Что делать если массив уже заполнен 
:(
    Опции темы
startpoint
Дата 26.6.2011, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 4.7.2007

Репутация: нет
Всего: нет



Нужно написать программу, которая бы подсчитывала количество символов в тексте побуквенно. Каждый символ будет представлен структурой:
Код

typedef struct {
    char value;
    int amount;
} symbol;
, где value это непосредственно сам символ, amount - количество вхождений. Хранить всё это буду в массиве. Так вот, проблема в том, что заранее естественно не известно сколько разных символов будет в тексте... Предположим что я объявляю массив на 50 символов, а их в тексте окажется 51. Что делать в этом случае ? А что если букв всего 3 - зачем мне тогда ещё 47 пустых ячеек в массиве ? Как со всем этим быть ?

Добавлено через 5 минут и 21 секунду
P.S. Пишу на C
PM MAIL   Вверх
fish9370
Дата 26.6.2011, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



есть три подхода: 
1) взять с запасом
2) сначала посчитать количество, потом выделить пространство под массив
3) использовать динамический список

недавно обсуждали подобную тему..
http://forum.vingrad.ru/forum/topic-332571/0.html


Цитата(startpoint @  26.6.2011,  22:00 Найти цитируемый пост)
P.S. Пишу на C

 smile 


--------------------
undefined
PM MAIL WWW ICQ   Вверх
bsa
Дата 26.6.2011, 22:45 (ссылка) |    (голосов:5) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



startpoint, рекомендую сделать проще - сделать массив из 256 интов. После этого каждый символ интерпретировать как индекс массива. При нахождении символа просто инкрементировать соответствующий элемента массива.
А так, как ты делать хочешь - очень медленно будет работать.

Это сообщение отредактировал(а) bsa - 27.6.2011, 11:14
PM   Вверх
newbieone
Дата 27.6.2011, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 14.3.2010

Репутация: 1
Всего: 1



Когда еще учился на первом курсе в ВУЗе, обходил подобную проблему со строками (длина которых заранее неизвестна) так: считывал посимвольно элементы строки и при каждом следующем считывании, если оно проходило успешно, создавал массив размером на 1 чар больше, переносил всё содержимое старого массива в новый, и старый удалял. в конце концов всегда имел [] char нужной длины smile но так, конечно, делать не надо ни в коем случае.
Если вариант bsa не подходит по условию задачи (обязательно использовать приведенную структуру), можно посмотреть в сторону контейнеров STL в C++ (если, опять же, условие использования чистого С не строгое).
PM MAIL   Вверх
bsa
Дата 27.6.2011, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(newbieone @  27.6.2011,  11:09 Найти цитируемый пост)
Когда еще учился на первом курсе в ВУЗе, обходил подобную проблему со строками (длина которых заранее неизвестна) так: считывал посимвольно элементы строки и при каждом следующем считывании, если оно проходило успешно, создавал массив размером на 1 чар больше, переносил всё содержимое старого массива в новый, и старый удалял. в конце концов всегда имел [] char нужной длины  но так, конечно, делать не надо ни в коем случае.

Очень неоптимально. В том же std::vector это делается через увеличение объема массива в 2 раза, а не на 1 символ. Более того, можно использовать realloc для изменений объема массива.
PM   Вверх
newbieone
Дата 27.6.2011, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 14.3.2010

Репутация: 1
Всего: 1



Цитата(bsa @ 27.6.2011,  11:16)
увеличение объема массива в 2 раза, а не на 1 символ

согласен. в своем посте я указал, что так делать не надо было. впрочем, ничто не мешает применить этот способ к данной задаче с учетом замечания о количестве выделяемой памяти при превышении. получится этакий велосипед наподобие std::vector средствами С.

Это сообщение отредактировал(а) newbieone - 27.6.2011, 13:05
PM MAIL   Вверх
Сыроежка
Дата 28.6.2011, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 127
Регистрация: 24.6.2011

Репутация: 1
Всего: 1



Цитата(startpoint @  26.6.2011,  22:00 Найти цитируемый пост)
Нужно написать программу, которая бы подсчитывала количество символов в тексте побуквенно. Каждый символ будет представлен структурой:

код C++

typedef struct {
    char value;
    int amount;
} symbol;

, где value это непосредственно сам символ, amount - количество вхождений. Хранить всё это буду в массиве. Так вот, проблема в том, что заранее естественно не известно сколько разных символов будет в тексте... Предположим что я объявляю массив на 50 символов, а их в тексте окажется 51. Что делать в этом случае ? А что если букв всего 3 - зачем мне тогда ещё 47 пустых ячеек в массиве ? Как со всем этим быть ?


Для таких целей служит контейнер std::map. . 
PM MAIL   Вверх
fish9370
Дата 28.6.2011, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(Сыроежка @  28.6.2011,  18:41 Найти цитируемый пост)
Для таких целей служит контейнер std::map


вобщето он пишет на Си..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
Сыроежка
Дата 28.6.2011, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 127
Регистрация: 24.6.2011

Репутация: 1
Всего: 1



Цитата(fish9370 @  28.6.2011,  19:41 Найти цитируемый пост)
вобщето он пишет на Си.. 


На С тоже есть реализация map. Но проще конечно в таком случае использовать список и каждый раз проверять, имеется ли в списке уже подсчитанный символ. Если нет, то доавлять в список. Списко конечно желательно иметь отсортированным по коду символа, чтобы использовать двоичный метод поиска.
PM MAIL   Вверх
Dov
Дата 28.6.2011, 20:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 11
Всего: 88



Да вы чего, ребятки? Вам что, делать нефиг?  bsa ещё два дня назад написал, что и как нужно делать. Читайте внимательно, что вам пишут: 
Цитата(bsa @  26.6.2011,  22:45 Найти цитируемый пост)
...рекомендую сделать проще - сделать массив из 256 интов. После этого каждый символ интерпретировать как индекс массива. При нахождении символа просто инкрементировать соответствующий элемента массива.

Если есть трудности в реализации этого простейшего метода, то могу предложить чего-нибудь такое:
Код
#define SIZE 256

int main()
{
    char   text[] = "Izrail'skaya,- govoryu,- voenshchina\
                     Izvestna vsemu svetu!\
                     Kak mat',- govoryu,- i kak zhenshchina\
                     Trebuyu ikh k otvetu!\
                                           Àleksandr Galich";                        
    char * p;
    int    arr[SIZE]  = {0};
    int    i;

    for(p = text; *p; p++)
        arr[*p]++;

    for(i = 0; i < SIZE; i++)
        if(arr[i] && i != ' ')
            printf("'%c' - %d\n", i, arr[i]);

    return 0;
}



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Сыроежка
Дата 28.6.2011, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 127
Регистрация: 24.6.2011

Репутация: 1
Всего: 1



Цитата(Dov @  28.6.2011,  20:21 Найти цитируемый пост)
Если есть трудности в реализации этого простейшего метода, то могу предложить чего-нибудь такое:

код C++

#define SIZE 256

int main()
{
    char   text[] = "Izrail'skaya,- govoryu,- voenshchina\
                     Izvestna vsemu svetu!\
                     Kak mat',- govoryu,- i kak zhenshchina\
                     Trebuyu ikh k otvetu!\
                                           Àleksandr Galich";                        
    char * p;
    int    arr[SIZE]  = {0};
    int    i;

    for(p = text; *p; p++)
        arr[*p]++;

    for(i = 0; i < SIZE; i++)
        if(arr[i] && i != ' ')
            printf("'%c' - %d\n", i, arr[i]);

    return 0;
}



Не обесудьте, но ваш код не корректный! Точнее сказать, зависящий от реализации компилятора. Дело в том, что тип char может вести себя и как signed char, и как  unsigned char. Если он ведет себя как знаковое целое число, то тогда выражение

arr[*p]++;

будет некорректным, так как получится, что вы будете вычитать из arr отрицательное число *p. Чтобы код был правильным надо предварительно делать кастинг то unsigned char.

Это сообщение отредактировал(а) Сыроежка - 28.6.2011, 20:42
PM MAIL   Вверх
Dov
Дата 28.6.2011, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 11
Всего: 88



Цитата(Сыроежка @  28.6.2011,  20:29 Найти цитируемый пост)
Не обесудьте, но ваш код не корректный!

А у нас что, дефицит напильников?  smile 



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
fish9370
Дата 29.6.2011, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(Dov @  28.6.2011,  20:21 Найти цитируемый пост)
Да вы чего, ребятки? Вам что, делать нефиг?  bsa ещё два дня назад написал, что и как нужно делать. Читайте внимательно, что вам пишут


поищите мой пост, там давно уже есть такой пример, задолго до bsa..
http://forum.vingrad.ru/forum/topic-332571/0.html


--------------------
undefined
PM MAIL WWW ICQ   Вверх
Сыроежка
Дата 29.6.2011, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 127
Регистрация: 24.6.2011

Репутация: 1
Всего: 1



Цитата(fish9370 @  29.6.2011,  12:43 Найти цитируемый пост)
поищите мой пост, там давно уже есть такой пример, задолго до bsa..


С той же самой ошибкой, как в данном примере, когда для символов с отрицательными кодами, которые обычно соответствуют символдам русского языка, проивходит выход за границу массива?!smile
PM MAIL   Вверх
universeroot
Дата 29.6.2011, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 29.6.2011

Репутация: нет
Всего: нет



А как вам моя реализация?  smile 

Код

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

#define STRING_SIZE 512

int main(int argc, char* argv[])
{
    char* string = (char*)malloc(STRING_SIZE);
    unsigned char result[256] = { 0 };
    int i;

    printf("Enter string: ");
    scanf("%s", string);

    for(i = 0; i < strlen(string); i++)
        result[string[i]]++;

    for(i = 0; i < 256; i++)
        if(result[i] != 0)
            printf("char: %c result: %d\n", i, result[i]);

    free(string);

    return 0;
}


Это сообщение отредактировал(а) universeroot - 29.6.2011, 18:15
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0853 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.