Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: помогите мне нужно открыть файл и посчитать в нём сиволы и к  (Прочитано 9762 раз)
0 Пользователей и 1 Гость смотрят эту тему.
noa
Гость
« : 19-11-2003 17:28 » 

помогите мне нужно открыть файл и посчитать в нём сиволы и каждый поотдельности. шлите пожалуйста на noa@ua.fm Заранее благодарен!!!
Записан
Sommer
Молодой специалист

us
Offline Offline

« Ответ #1 : 19-11-2003 17:31 » 

noa,
а что значит "и каждый по отдельности?"
Записан

когда-нибудь, я верю, ты будешь ехать по этому городу и поймёшь, что хочешь увидеть меня за рулём мчащейся по соседней полосе машины.
но тогда меня уже не будет
в этом городе
forever yours.
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #2 : 19-11-2003 18:32 » 

noa, мда - задчка однако,

FILE *f;
f = fopen(filename, "r"); // Fikle to read only

while (fread(f,char))
{
// Делать что либо с символами
}
fclose(f);

все - это читает все символы с файла

Причем все и каждый в отдельности. Отлично

Могут быть проблемы - я его не компилировал, а формат функции чтения не помню, мож она там что не так возвращает...
Записан

А птичку нашу прошу не обижать!!!
Thinker
Гость
« Ответ #3 : 19-11-2003 22:04 » 

Цитата

открыть файл и посчитать в нём сиволы и каждый поотдельности

Если это означает подсчет сколько раз каждый символ присутствовал в файле и речь не идет о Unicode, то можно создать массив целых чисел размером в искомый алфавит (в худшем случае - 256), и использовать его как счетчик.
С Unicode задачка становится гораздо интереснее Улыбаюсь
К делу не относится:
Для любителей структур данных - можно еще и построить частотный индех всех слов в документе, причем документ (в моем случае) был около 1 терабайта - snapshot куска интернета  Жжешь Причем кодировки там были смешанные и зачастую неправильно помеченные. Было интересно .... 8)
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #4 : 19-11-2003 22:38 » 

Thinker, все очень просто - завтра протрезвею и вывешу алгоритм на 10 строк больше того, который написан у меня, и сделаю вам подсчет - с условием уникода, или без него - без всяких проблем...
Записан

А птичку нашу прошу не обижать!!!
Alf
Гость
« Ответ #5 : 20-11-2003 00:33 » 

Цитата: Thinker

Если это означает подсчет сколько раз каждый символ присутствовал в файле и речь не идет о Unicode, то можно создать массив целых чисел размером в искомый алфавит (в худшем случае - 256), и использовать его как счетчик.
С Unicode задачка становится гораздо интереснее Улыбаюсь

А вот ежели взять да и завести для хранения счетчиков ассоциативный массив, даже Unicode не внесет желаемого разнообразия. Задачка останется по-прежнему скучной...  Жаль
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #6 : 20-11-2003 00:56 » 

Alf, а она и так скучна, и не в юникоде дело.
Процесс:
1. берется файл - читается весь.
2. Определяется формат.
3. Создается связный список, в котором в зависимости от формата фалйа данное - 1 байт или 2.
Можно и не связный спиок а массив в случае 1 байта символа из 256 позиций - но ломает так делать. Улыбаюсь
4. Затем банальный перебор позиций для каждого символа.
Принцип подсчета - первый символ фала считается сколько раз втречается и в памяти забивается на соответствующую байду. В нашем случае когда 256 символов - обычно сначала сичтали 0 символы - потом все остальные заменяли на 0.
Для юникода тоже можно взять первый символ - посчитать его содержимое, а потом заменять другие на него - не суть.

И все.
Остается прикол когда файл размером больше оперативки в разы, например 2 Гига.

Тогда пробежку делаем в кусках фала, которые считываем, скажем по 20 мег, или по 100 мег - в зависимости от системы.
Задача ВСЯ - включая работу по связному списку и оформлению в нормальный объект - порядка 100 строк кода максимум.... и то с запасом на всякие там заморочки по улучшению...

Скучно. noa, ты можешь брать на вооружение эту схему - все будет работать как часики.
-----------------------
(кстати если не нужна точность, а порядок, то можно использовать оценочные алгоритмы Улыбаюсь Улыбаюсь вот там интереснее...)
Записан

А птичку нашу прошу не обижать!!!
Alf
Гость
« Ответ #7 : 20-11-2003 08:02 » 

Цитата: Гром
Alf, а она и так скучна, и не в юникоде дело.
Процесс:
1. берется файл - читается весь.
2. Определяется формат.
3. Создается связный список, в котором в зависимости от формата фалйа данное - 1 байт или 2.
Можно и не связный спиок а массив в случае 1 байта символа из 256 позиций - но ломает так делать. Улыбаюсь
4. Затем банальный перебор позиций для каждого символа.
Принцип подсчета - первый символ фала считается сколько раз втречается и в памяти забивается на соответствующую байду. В нашем случае когда 256 символов - обычно сначала сичтали 0 символы - потом все остальные заменяли на 0.
Для юникода тоже можно взять первый символ - посчитать его содержимое, а потом заменять другие на него - не суть.
И все.

Если я правильно понял идею, делается как минимум несколько проходов файла, а именно - столько, сколько различных символов в нем встречается?
Цитата: Гром

Остается прикол когда файл размером больше оперативки в разы, например 2 Гига.

Тогда пробежку делаем в кусках фала, которые считываем, скажем по 20 мег, или по 100 мег - в зависимости от системы.

Сложно... Не в смысле - безумно сложно само по себе, а для решаемой задачи сложновато.
А почему бы не так: берем ассоциативный массив счетчиков, изначально обнуленных. Читаем входной файл поэлементно и инкрементируем счетчик, ассоциированный с этим элементом. Работать должно с любыми кодировками, читать данные однократно и не зависеть от размера входного файла. И по памяти выгадаем: массив счетчиков в любом случае компактнее исходных данных. Если, конечно, не выдумают какую-нибудь всегалактическую кодировку подлиннее Unicode, скажем, 32-битную  Улыбаюсь Тогда таблица счетчиков тоже распухнет изрядно...
Правда, и перспектива сканировать файл до 4.000.000.000 раз тоже не очень...
Записан
Diletant
Помогающий

de
Offline Offline

« Ответ #8 : 20-11-2003 10:27 » 

Не понял проблемы

FILE *f;
TCHAR MyChar;
int iCounts[sizeof(MyChar)*8];
int i;

for (i= 0; i < sizeof(MyChar)*8; i++)
{
   iCounts = 0;
}

f = fopen(filename, "rb"); // Fikle to read only

while (fread(f,MyChar))
{
    (iCounts[(int)MyChar])++
}
fclose(f);


Вместо TCHAR может быть какой угодно char.
Записан
Alf
Гость
« Ответ #9 : 20-11-2003 11:54 » 

Цитата: Diletant
Не понял проблемы

...
int iCounts[sizeof(MyChar)*8];
...

Не понял эту конструкцию. Судя по всему, это массив счетчиков экземпляров символа?
sizeof(MyChar) вернет размер, занимаемый переменной типа MyChar, в байтах. В случае символов ASCII это будет 1, для Unicode - 2. Соответственно и размерность таблицы будет 8 либо 16. Вроде маловато.
Вот кабы 2 возвести в эту степень, было бы уже ближе к истине, по-моему.
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #10 : 20-11-2003 12:14 » 

Alf, нет - прозод один Улыбаюсь - при возможности можно сделать, просто вчера был пъян и фокус не удался Улыбаюсь

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

примерно:

#define size_of_file - тут не пишу просто - сичтаем определили размер в байтах filesize().

typedef struct
{
char a[size_of_file];
int   count[size_of_file];
int active_num;

} mystr;

mystr str;
str.active_num = 0;
FILE *f;
f = fopen(filename, "r"); // Fikle to read only
bool flag=false;
while (fread(f,char))
{
for (int i=0; i<active_num; i++)
{
    if (char == str.a)
    {
        str.count++;
        flag = true;
        break;
    }
}
if (flag == false)
{
     active_num++;
     str.a[active_num] = char;
     str.count[active_num] = 1;
} else
{
     flag = false;
}

}
fclose(f);



УСЕ  Отлично
Записан

А птичку нашу прошу не обижать!!!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #11 : 20-11-2003 12:30 » 

Ну... не понимаю как можно осбуждать на основе таких скудных данных, да и noa пропал. Ну да ладно - спонтанно продолжаем разговор, предположив что мы знаем, что ему нужно.

в принципе согласен с Alf и Diletant думаю имеется ввиду одно и то же.

Вопросы к коду Diletant:

Я это место тоже не понял? Думаю так:
int iCounts[sizeof(char)*256];  - число символов для таблицы ANSI.

Обнулить счётчики:
memset(iCounts,0,sizeof(int)*sizeof(char)*256);

и главное:
"(iCounts[(int)MyChar])++" Не понял?

Наверно всё-таки так:

(iCounts[(unsigned char)MyChar])++

тк в С++ char вообщето со знаком, поэтому для символа с кодом > 127 всё вылетает в отрицательную область, да плюс ещё кастинг в 4х байтовый целый!!! Индекс получится сумасшедший.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 20-11-2003 12:41 » 

Гром, а так разве проще? По-моему сложнее.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Diletant
Помогающий

de
Offline Offline

« Ответ #13 : 20-11-2003 14:33 » 

Цитата: Джон


Вопросы к коду Diletant:

Я это место тоже не понял? Думаю так:
int iCounts[sizeof(char)*256];  - число символов для таблицы ANSI.


Поторопился я  :oops: . Умножать надо, естественно, на 256. Хотя IMHO sizeof(MyChar)  предпочтительнее во избежание путаницы со встроенным типом С.

Цитата: Джон

Обнулить счётчики:
memset(iCounts,0,sizeof(int)*sizeof(char)*256);


Это уже на любителя,  но я не люблю без особой необходимости использовать memset.


Цитата: Джон

и главное:
"(iCounts[(int)MyChar])++" Не понял?

Наверно всё-таки так:

(iCounts[(unsigned char)MyChar])++

тк в С++ char вообщето со знаком, поэтому для символа с кодом > 127 всё вылетает в отрицательную область, да плюс ещё кастинг в 4х байтовый целый!!! Индекс получится сумасшедший.


Все-таки так:

(iCounts[(unsigned int)MyChar])++

если мы хотим UNICODE поддерживать. В противном случае придется юникодный компилятор использовать.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #14 : 20-11-2003 15:03 » 

Цитата: Diletant

Это уже на любителя, но я не люблю без особой необходимости использовать memset.


Согласен, я не люблю циклы закручивать.

Цитата: Diletant

(iCounts[(unsigned int)MyChar])++


Сделай
char ch = -65;
(unsigned int)ch  и посмотри, что получится.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Diletant
Помогающий

de
Offline Offline

« Ответ #15 : 20-11-2003 15:38 » 

Жаль  Так больше нельзя...  .  Тогда надо MyChar как unsigned TCHAR декларировать. Пошел читать про приведение типов   Жаль  Жаль  Жаль
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #16 : 20-11-2003 15:49 » 

Я не совсем уверен, что с UNICODE так же всё гладко получится. Например с началом файла мы уже пролетаем. Мне ща надо уже сваливать, а завтра меня не будет. Если что, на след неделе продолжим. Честно говоря про UNICODE я ещё хорошо не думал, да и нужно ли оно?  noa- то вон, пропал.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #17 : 20-11-2003 15:49 » 

Джон, чем сложнее.
Идея проста до безобразия.
Встречается символ - смотрим его в своем списке, находим, увеличиваем каунтер - не находим - создаем новый элемент.
На обычных чар - заработает 100% и очень быстро.
Процедура поиска в своем списке может быть ускорена Улыбаюсь
Я ж писал это прямо тут даже не заставляя себя думать Улыбаюсь
Может и неправильно так поступать, но....

Посик в массиве для поиска можно ускорять - если он будет не массивом а упорядоченным списком, по данным, тогда мы можем брать алгоритм разделения его.
В любом случае два байта это FFFF максимум элементов и поиск будет бытрее чем в гиговом файле к примеру...

Вот отчюда и вывод так быстрее в случае больших файлов.
Записан

А птичку нашу прошу не обижать!!!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #18 : 20-11-2003 16:01 » 

Я пока с уверенностью говорю только про ANSI посмотри код Diletantа. Один проход без поиска

Код:

char MyChar;
int iCounts[256*sizeof)char:(;
memset)iCounts,0,sizeof)int:*sizeof)char:*256:;
FILE *f = fopen)"d{\\a.txt", "rb":;
while )fread)&MyChar,sizeof)char:,1,f:: )iCounts[)unsigned char:MyChar(:++;
fclose)f:;
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines