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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Срочно нужна помощь в поиске ошибки, Работа со строками - а в частности с... 
:(
    Опции темы
Voldemar2004
Дата 10.5.2006, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

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



Работа со строками - а в частности с AnsiString.

Требуется вывести предложения с наибольшим количеством слов.

Вопрос к профи: функция word_counter(char *a) правильно работает, но при работе с AnsiString - неверно выдает количество слов в предложении.
Код
//---------------------------------------------------------------------------
#include <iostream.h>  // cin, cout
#include <conio.h>     // getch()
#include <string.h>    // strlen()

#include <vcl.h>
#pragma hdrstop

//---------------------------------------------------------------------------
#pragma argsused

int clause_count(char *); /* Прототип функции подсчета количества предложений. */
int word_counter(char *); /* Прототип функции подсчета количества слов в предложении. */

int main(int argc, char* argv[])
{
char *a = "Moskva, kefir. Pobeda? Ura, ura, ura!";

        int i=0, count=0; /* count - Переменная для подсчета количества слов в каждом предложении */

        /*
        Создание динамического массива - для хранения в каждом его элементе
        выделенного предложения
        */
        AnsiString *b = new AnsiString[clause_count(a)];

        int buffer=0;

        for(int j=0; j<clause_count(a); j++)
        {
                do
                {
                //cout<<a[i];
                i++;
                count++;
                }
                while( a[i-1] != '.' && a[i-1] != '?' && a[i-1] != '!');


                        /* Каждое предложение запишем в отдельный массив. */
                        for(int k=buffer; k<count; k++) {b[j] += a[k];};
                        buffer=count;
         }

               /* Вот здесь заступорило! */

               /* Неверно выводится количество слов в предложении! */
               for(int i=0; i<clause_count(a); i++)
               {
               cout<<word_counter(b[i].c_str())<<"\n";
               }

getch();

delete[] b;
return 0;
}
//---------------------------------------------------------------------------

int clause_count(char *a)
{
/* Массив разделителей. */
char *split = ".!?";

int i=0, clause=0;

        do
        {
                for(int j=0; j<3; j++)
                {
                        if( a[i]==split[j] ) clause++;
                }
        i++;
        }
        while( i!= strlen(a) );
return clause;
}
//---------------------------------------------------------------------------

int word_counter(char *a)
{
int i=0, counter=0;

        do
        {
        if( a[i]==' ' && a[i+1] !=' ' ) counter++;
        i++;
        }
        while( i!= strlen(a) );
return counter+1;
}
//---------------------------------------------------------------------------
 


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
bsa
Дата 10.5.2006, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Кто так пишет?!? Убил бы.
strlen(a) - долгая функция. Она перебирает каждый символ строки.  Это тебе не iterator!
А с обычными строками работает (не AnsiString)? 
PM   Вверх
Fazil6
Дата 10.5.2006, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



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

return counter+1;

согласен с предыдущим оратором - крайне коряво написано. Чего только do-while стоит... 
PM MAIL   Вверх
bsa
Дата 10.5.2006, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Человек, наверное, не знает, как пользоваться for(;;).  smile 
Код
int word_counter(const char *a) {    
    int i, n;
    int counter;
    n = strlen(a);
    for(; ( n > 0 ) && ( *a == ' ' ); --n, ++a );  //пропускаем лидирующие пробелы
    for( counter = 0; n > 0; --n, ++a )
        if ( ( *a == ' ' ) && ( a[1] != ' ' ) )
            ++counter;
    return counter;
}

Так, имхо, лучше (я не отлаживал, правда). 
PM   Вверх
Hose
Дата 11.5.2006, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



я конечно не профи и по проблемме ничего сказать не могу. Но крайне не люблю необоснованные обвинения. Поэтому сам проверил производительность двух предложеных вариантов.
код:
Код

int _tmain(int argc, _TCHAR* argv[])
{
    int count = 0;
    for (int i = 0; i < 100000000; i++)
    {
        count += word_counter("Moskva, kefir. Pobeda? Ura, ura, ura!");
    }
    printf("%d", count);
    return 0;
}

Измерения проводились по часам, поэтому достаточно грубы.
MSVS 2005

вариант от Voldemar2004 выполнялся 13 секунд,
вариант от bsa 21 секунду. 
PM MAIL   Вверх
bsa
Дата 11.5.2006, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Мой вариант:
real    0m32.741s
user    0m32.274s
sys     0m0.072s

Вариант Voldemar2004:
real    1m24.101s
user    1m23.853s
sys     0m0.188s

Компиляция производилась с помощью gcc-3.4.5.
Использовалась библиотека glibc-2.3.6-r3.
Тистировалось на "Linux b-s-a 2.6.15-gentoo-r7 #1 PREEMPT Mon Mar 6 11:45:01 MSK 2006 x86_64 AMD Athlon™ 64 Processor 3000+ GNU/Linux" с помощью стандартной утилиты time.

Добавлено @ 10:52 
Хотя, его процедура считает правильней. Но только в данном конкретном случае. 
PM   Вверх
Voldemar2004
Дата 11.5.2006, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

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



Hose, 
Цитата(Hose @  11.5.2006,  10:24 Найти цитируемый пост)
вариант от Voldemar2004 выполнялся 13 секунд,
вариант от bsa 21 секунду. 
Я спрашивал про скорость? smile 

Цитата(bsa @  11.5.2006,  10:47 Найти цитируемый пост)
MSK 2006 x86_64 AMD Athlon™ 64 Processor 3000+ GNU/Linux" с помощью стандартной утилиты time.
bsa, ответ, конечно, в тему.

Цитата(Fazil6 @  10.5.2006,  22:57 Найти цитируемый пост)
вообще такой корявый алгоритм. 
Цитата(Fazil6 @  10.5.2006,  22:57 Найти цитируемый пост)
неправильно выдает в первую очередь из-за этого
Код
return counter+1;
Ну конечно, щазз.

Вот так выдаст правильное количество слов:
Код
char *a = "Moskva, kefir.Pobeda?Ura, ura, ura!";
А вот так - уже нет - 
Код
char *a = "Moskva,slovo.Pivo?Ura,ura,ura!";
Я понял в чем ошибка - цеплялись лишние пробелы при выделении.
Код
for(int i=0; i<clause_count(a); i++) cout<<b[i].c_str()<<"\n";

Цитата(bsa @  11.5.2006,  10:47 Найти цитируемый пост)
Но только в данном конкретном случае. 
Ее еще надо отлаживать для всех случаев. smile  


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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