Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

Гаряка Асмик
Статус: Профессионал
Рейтинг: 4354
∙ повысить рейтинг »
lamed
Статус: Профессионал
Рейтинг: 2752
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2478
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И ПО / Программирование / C/C++

Номер выпуска:1555
Дата выхода:19.06.2010, 05:00
Администратор рассылки:Verena, Профессионал
Подписчиков / экспертов:366 / 165
Вопросов / ответов:1 / 2
IRC-канал по теме:#C

Вопрос № 179077: Здравствуй те Эксперты. у меня возникла проблема при написанние программы на С++ Билдере 6. сама задача такая "В существующем на диске файле поменять местами первый из наиболее часто встречающихся символов с первым из наиболее редко встреч...



Вопрос № 179077:

Здравствуй те Эксперты.
у меня возникла проблема при написанние программы на С++ Билдере 6.
сама задача такая "В существующем на диске файле поменять местами первый из наиболее часто встречающихся символов с первым из наиболее редко встречающихся символов. (Файл создать с помощью текстового редактора)
Вспомогательный файл не использовать."
Как я поняла, необходимо чтобы он проверил файл на все 26 символов, и нашел самый большой.
Для того чтобы как это проверть нужно их занести в переменную какую нибудь и сравнить и + доп.открыть счетчик проверки этих символов.
и в конце уже менять местами,самый большой с самым маленьким.
Если я не ошибаюсь всего 26 символов, плюс еще придется потратить 52 буквы(переменных) чтобы все это произвести.
возможно ли это как нибудь сократить?
Если да, то как образом.?

Отправлен: 13.06.2010, 15:46
Вопрос задал: Илона Меньшикова, Посетитель
Всего ответов: 2
Страница вопроса »


Отвечает AtomIad, 5-й класс :
Здравствуйте, Илона Меньшикова.
© Цитата: Илона Меньшикова
Если я не ошибаюсь всего 26 символов, плюс еще придется потратить 52 буквы(переменных) чтобы все это произвести.

Нет, можно проще. Узнайте размер файла, выделите массив нужного размера.
Далее в примере показано, как найти в массиве первый наиболее часто и наименее часто повторяющиеся элементы.
Код:
#include <s
 tdio.h>
#include <conio.h>
#include <string.h>

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 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Отвечает amnick, Профессионал :
    Здравствуйте, Илона Меньшикова.

    Предлагаю свой вариант решения — именно для файлов, причем любого размера в пределах 2Гб. В задаче не уточняется, текстовый файл или бинарный, поэтому программа работает с бинарными файлами. Всего возможно 256 символов (столько можно закодировать в одном байте, многобайтовые кодировки не рассматриваем). Программа подсчитывает частоты символов, для каждого символа сохраняется смещение первого вхождения. Просканировав весь файл, программа определяет самый частый и самый редкий символы, а затем записывает самый редкий символ на место первого самого частого и наоборот.

    Код:
    /*
    В существующем на диске файле поменять местами первый из наиболее
    часто встречающихся символов с первым из наиболее редко встречающихся
    символов. (Файл создать с помощью текстового редактора)
    Вспомогательный файл не использовать.
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <io.h>
    #include <fcntl.h>
    #include <sys\stat.h>
    #include <string.h>

    // всю обработку файла выполняем в этой функции
    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 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.16 от 26.05.2010

    В избранное