![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Code Magister |
|
|||
![]() Magister of Code ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 9.7.2004 Где: Kiev Репутация: 1 Всего: 1 |
Вот она эта функция, написаная мной. С небольшими файлами работает безотказно, НО если в файле (насколько я заметил) больше, чем 32786 строки, то прога сначала дуплится, а потом начинает выводить эту самую 32786 строку ХЗ сколько раз. В чем тут дело? Добавлено @ 02:12 И еще, если файл меньше, то она хоть и правильно, но как-то очень медленно работает. Я пытался откомпилировать это в билдере, так там вобще ошибку на стадии выполнения выдает. Это сообщение отредактировал(а) _Slipknot - 5.6.2005, 02:19 --------------------
|
|||
|
||||
| Mayk |
|
||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Можно сделать так: перемотать файл в конец, потом считывать с конца в буфер n-ное кол-во байт, строки из буфера в обратном порядке пихать в выходной файл. Только тут надо учитывать то, что на начало буфера выпадает середина строки. Поэтому приходится отматывать вперед, чтобы при следующем заходе прочитать всю строку.
И еще один момент - в DOS'е строка оканчивается не так как в Linux. Это может повлиять на результат. 800 килобайтный Фауст(20427 строк) перевернулся за ~0.1 секунду 3 метровый Эмбер(60895 строк) перевернулся за ~0.66 секунды.
Ну так, посмотри как ты много читаешь: допустим в файле 5 строк. Ты прочитаешь 5 строк, чтобы узнать их кол-во, затем прочитаешь 4 строки, чтобы прочитать и вывести пятую, потом три строки, чтобы вывести четвертую. В общем кол-во чтений строк - сумма арифмитической прогрессии от 1 до n, где n - кол-во строк. И это будет что-то типа S=n*((1+n)/2)=(n^2+n)/2; если я не попутал. В примере S = (25+5) / 2 = 15; да еще +5 = 20 чтений строк. А теперь пусть n=1000=10^3. S=(10^6+10^3) / 2 = 10 * (10^5 + 10^2) / 2 = 5 * 10^ 5 + 5 * 10^2 = 50500 чтений. Это много. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||
|
|||||
| Code Magister |
|
|||
![]() Magister of Code ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 9.7.2004 Где: Kiev Репутация: 1 Всего: 1 |
спасибо конечно за прогу, но я хочу разобратъся со своей.
можно попроще обьяснить? и как это исправить? --------------------
|
|||
|
||||
| Mayk |
|
||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Я привел пример как это делать быстрее.
[в прошлом посте недоквотил "в чем тут дело?"] По-проще это будет "функция fscanf вызывается СЛИШКОМ много раз, этого можно избежать". Или "алгоритм не годится для решения задачи". Те вычисления показывают что значит слово "СЛИШКОМ" и объясняют почему алгоритм не годится: Большую часть времени программа из первого листинга бегает по файлу туда-сюда, хотя этого можно избежать. Медленная работа вызвана выбором далеко не лучшего алгоритма. Кол-во fscanfов(кстати fgets() подошел бы больше) есть квадратичная функция (это показано в вычислениях). Программа из второго листинга бегает гораздо реже(и там кол-во вызовов fseek() есть линейная функция, которая кстати от кол-ва строк зависит лишь косвенно). Графики функций ax^2 и kx представляешь? -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||
|
|||||
| __Sergey__ |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 67 Регистрация: 21.1.2005 Репутация: нет Всего: 4 |
||||
|
||||
| Code Magister |
|
|||
![]() Magister of Code ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 9.7.2004 Где: Kiev Репутация: 1 Всего: 1 |
Mayk а что от того, что она много бегает по файлу,она зависает чтоли?
--------------------
|
|||
|
||||
| Mayk |
|
||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Она от этого медленно работает. А зависает от... (копаюсь)... Хм, по-моему она не зависает. Просто медленно работает, можно делать printf("%d",c); чтоб не скучно было. Теперь к дупам: Вот в 30 строчке есть
Ну если особо не вдаваться в подробности - вот здесь int заменить на unsigned long int. Кстати, только сейчас заметил, прога переворачивает слова, а не строки, а в комментариях указаны строки... И еще - cin >> way; куда указывает way? Это сообщение отредактировал(а) Mayk - 6.6.2005, 20:45 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||
|
|||||
| Code Magister |
|
||||||||
![]() Magister of Code ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 9.7.2004 Где: Kiev Репутация: 1 Всего: 1 |
Зависает, зацикливается на 32768 строчке. Если б проблема была только в быстродействии - для меня это не была б проблема.
Точно, с long, а i int - ща исправим.
Прога переворачивает строки. 1-я строчка станет последней, а последняя первой. Сами строчки при этом не изменятся
way - это путь файла, который мы будем переворачивать. Добавлено @ 23:38 Mayk да, проблема была именно в типе i. Кажется теперь работает, хоть и медленно. Спасибо за помощь! --------------------
|
||||||||
|
|||||||||
| Code Magister |
|
|||
![]() Magister of Code ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 9.7.2004 Где: Kiev Репутация: 1 Всего: 1 |
А насчет твоей проги. Так она переворачивает только первые 128 строк.
Как я понял она считывает файл в оперативу. Я увеличил размер
--------------------
|
|||
|
||||
| ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Помножте число на двое и вычтете единицу. Получите 0xFFFF. Это значит, что в какой-то функции происходит переполнение двухбайтовой знаковой переменной. |
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Судя по всему не понял. Приницип я уже пояснял.
Теперь проиллюстрирую работу: входной файл: --- a.txt --- AAAAAA`\n` BBBBBB`\n` CCCCCC`\n` -- eof --- Размер буфера = 10. Теперь посмотрим что прочтется из файла. --- a.txt -- AAAAAA`\n` BBBB[BB`\n` CCCCCC`\n`] --- eof --- в квадратных скобках выделено жирным то, что содержится в буфере. Теперь прочтенные строки пихаем в обратном порядку: 1) \n в конце. Все что справа пихаем в выходной файл и \n. Так как правее нет ничего, то в выходной файл идет только \n (багофича). Заменяем '\n' на 0 2) '\n' после BB. Все что правее пихаем в выходной файл + '\n'. Туда добавляется "CCCCCC\n" '\n' меняем на 0. EOL'ов больше нет. Считываем следующий блок. Так как в буфере есть два байта то теперь мы считываем не 10 байт, а только 8(таким образом мы прочитаем эту строчку полностью) --- a.txt -- AAA[AAA`\n` BBBBBB]`\n` CCCCCC`\n` --- eof --- В выходной файл идет все что правее '\n'. то есть BBBBBB. Плюс перевод строки. (кстати, теперь в выходном файле три строки: пустая, CCCCCC, BBBBBB) В буфере остается 3 байта. Мы не можем полностью заполнить весь буфер, поэтому считываем так: --- a.txt -- [AAAAAA]`\n` BBBBBB`\n` CCCCCC`\n` --- eof --- Выкидываем эту строку в выходной файл. Теперь файл перевернут -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| Code Magister |
|
|||
![]() Magister of Code ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 9.7.2004 Где: Kiev Репутация: 1 Всего: 1 |
Mayk тогда хз че она у меня не работает.
А моя уже 2-й час переворачивает 6-ти метровый файлик. Тише едешь - дальше будешь --------------------
|
|||
|
||||
| ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Вот это место. Похоже в вашем компиляторе int - двухбайтовый. Тогда, разумеется, цикл будет вечным. Замените на unsigned long int или, лучше, просто unsigned long (насколько знаю, разницы никакой). |
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
_Slipknot
Какой компилятор используешь? -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| Code Magister |
|
|||
![]() Magister of Code ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 9.7.2004 Где: Kiev Репутация: 1 Всего: 1 |
ManiaK почитай посты выше. Я уже нашел ошибку и исправил ее.
А говорим мы сейчас о программе, которую написал Mayk Добавлено @ 16:04 Mayk BC++ 3.1 --------------------
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |