Вопрос № 179077: Здравствуй те Эксперты. у меня возникла проблема при написанние программы на С++ Билдере 6. сама задача такая "В существующем на диске файле поменять местами первый из наиболее часто встречающихся символов с первым из наиболее редко встреч...
Вопрос № 179077:
Здравствуй те Эксперты. у меня возникла проблема при написанние программы на С++ Билдере 6. сама задача такая "В существующем на диске файле поменять местами первый из наиболее часто встречающихся символов с первым из наиболее редко встречающихся символов. (Файл создать с помощью текстового редактора) Вспомогательный файл не использовать." Как я поняла, необходимо чтобы он проверил файл на все 26 символов, и нашел самый большой. Для того чтобы как это проверть нужно их занести в переменную
какую нибудь и сравнить и + доп.открыть счетчик проверки этих символов. и в конце уже менять местами,самый большой с самым маленьким. Если я не ошибаюсь всего 26 символов, плюс еще придется потратить 52 буквы(переменных) чтобы все это произвести. возможно ли это как нибудь сократить? Если да, то как образом.?
Если я не ошибаюсь всего 26 символов, плюс еще придется потратить 52 буквы(переменных) чтобы все это произвести.
Нет, можно проще. Узнайте
размер файла, выделите массив нужного размера. Далее в примере показано, как найти в массиве первый наиболее часто и наименее часто повторяющиеся элементы.
int main() { char massiv[15]="hheeeerrrrrddq"; int size_of_massiv=strlen(massiv); int current_max,i,j,max,min,current_min; int symbol_position,symbol_position2; max=0; min=size_of_massiv+1; current_min=0; current_max=0; //поиск первого наиболее часто встречающегося элемента for (i=0; i<size_of_massiv; i++) { for (j=0; j<size_of_massiv;j++) if (massiv[i]==massiv[j])
current_max++; if (current_max>max) { max=current_max; symbol_position=i; } current_max=0; } //поиск первого наименее часто встречающегося элемента for (i=0; i<size_of_massiv; i++) { for (j=0; j<size_of_massiv;j++) if (massiv[i]==massiv[j]) current_min++; if (current_min<min) { min=current_min; symbol_position2=i; } current_min=0; }<
br>printf("%c = %d times \n",massiv[symbol_position],max); printf("%c = %d times \n",massiv[symbol_position2],min); getch(); }
Ответ отправил: AtomIad, 5-й класс
Ответ отправлен: 13.06.2010, 21:21
Номер ответа: 262091
Оценка ответа: 5 Комментарий к оценке: без коментарев
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 262091
на номер 1151 (Россия) |
Еще номера »
Предлагаю свой вариант решения — именно для файлов, причем любого размера в пределах 2Гб. В задаче не уточняется, текстовый файл или бинарный, поэтому программа работает с бинарными файлами. Всего возможно 256 символов (столько можно закодировать в одном байте, многобайтовые кодировки не рассматриваем). Программа подсчитывает частоты символов, для каждого символа сохраняется смещение первого вхождения. Просканировав весь файл, программа определяет самый частый и самый
редкий символы, а затем записывает самый редкий символ на место первого самого частого и наоборот.
Код:
/* В существующем на диске файле поменять местами первый из наиболее
часто встречающихся символов с первым из наиболее редко встречающихся символов. (Файл создать с помощью текстового редактора) Вспомогательный файл не использовать. */
// всю обработку файла выполняем в этой функции int work( const char* pszFileName ) { // открываем файл для чтения/записи
с разделением доступа по чтению int h = _open( pszFileName, _O_BINARY | _O_RDWR, _S_IREAD ); if( h == -1 ) return -1;
unsigned freq[256]; // кол-во соответствующих символов unsigned long offs[256]; // где первый раз встретился символ memset( freq, 0, sizeof freq ); // обнуляем массив частот символов memset( offs, -1, sizeof offs ); // заполняем offs значением (-1)
unsigned char buf[4096]; // буфер для чтения файла unsigned l
ong offs_buf = 0; // файловое смещение начала буфера int iRetValue = 0; // возвращаемое значение
while(1) { int n = _read( h, buf, sizeof buf ); if( n < 0 ) { iRetValue = -2; break; } // ошибка чтения if( n == 0 ) break; // конец файла
for( int i = 0; i < n; ++i ) { // сканируем буфер int ch = buf[i]; // символ ++freq[ch]; // счетчик вхождений этого символа if( offs[ch] == -1 ) // если символ встретился первый раз, offs[ch] = offs_buf
+ i; // то запоминаем его смещение в файле
} offs_buf += n; // файловое смещение следующего блока; в конце - размер файла }
if( iRetValue == 0 ) { // определяем самый частый и самый редкий символ среди имеющихся в файле int chMin, chMax; unsigned long nMin = ULONG_MAX, nMax = 0; for( int i = 0; i < 256; ++i ) { int f = freq[i]; if( f ) { if( f > nMax ) { nMax = f; // максимальная частота
chMax = i; // соответствующий символ } else if( f < nMin ) { nMin = f; // минимальная частота chMin = i; // соответствующий символ } } }
if( nMin == ULONG_MAX ) iRetValue = -4; // весь файл заполнен одним символом (chMax) else if( offs_buf >= 3 ) { printf( "Наиболее часто встречается символ '%c' (\\x%02x), первое вхождение в позиции %lu\n" "Наиболее редко встречается символ '%c'
(\\x%02x), первое вхождение в позиции %lu\n", chMax, chMax, offs[chMax], chMin, chMin, offs[chMin] );
_lseek( h, offs[chMin], 0 ); // позиция самого редкого символа _write( h, &chMax, 1 ); // записываем самый частый символ
_lseek( h, offs[chMax], 0 ); // позиция самого частого символа _write( h, &chMin, 1 ); // записываем самый редкий символ } else iRetValue = -3; } _close(h); return iRe
tValue; }
int main( int argc, char* argv[] ) { char szInput[_MAX_PATH]; char *pInName; if( argc >= 2 )
// если в командной строке переданы параметры, pInName = argv[1]; // то первый из них - имя обрабатываемого файла else { // иначе - запрашиваем имя файла у пользователя printf( "Введите имя исходного файла: " ); pInName = gets( szInput ); }
int iResult = work( pInName ); switch( iResult ) { case -1: printf( "Ошибка при открытии файла \"%s\"\n", pInName ); break; case -2: printf( "Ошибка при чтении файла
\"%s\"\n", pInName ); break; case -3: printf( "Слишком маленький файл \"%s\"\n", pInName ); break; case -4: printf( "Весь файл заполнен одним символом.\n" ); break; } return iResult; }
За неимением C++ Builder программа протестирована в MSVC++ 6.0 и Code::Blocks 10.05.
Успехов!
Ответ отправил: amnick, Профессионал
Ответ отправлен: 14.06.2010, 14:54
Номер ответа: 262101
Оценка ответа: 5
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 262101
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.