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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C] Поиск слова в строке и его номер 
:(
    Опции темы
InviZible
Дата 28.10.2007, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здравствуйте.
Есть строка s1 в ней нужно найти слова s2 и указать его номер.
Например, s1="Я изучаю чистый Си" s2="Чистый". На выходе: 3.
Заранее спасибо.
PM MAIL   Вверх
Mayk
Дата 28.10.2007, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

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



Цитата(InviZible @  28.10.2007,  19:59 Найти цитируемый пост)

Например, s1="Я изучаю чистый Си" s2="Чистый". На выходе: 3.

мм, это опечатка, или необходимо искать с игнорированием регистра букв? допустим, что это опечатка. и регистр имеет значение.
и допустим что в случае не обнаружения слова должно возвращаться 0.
не совсем понятно что подразумевается под словами --- вернее, как они разделены? допустим они разделены только пробельными символами.

Тогда это можно сделать примерно так.
Код

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>

/** Возвращает 1 если символ ch может содержаться в слове */
int isWord( int c ){
    return  c &&  !isspace(c);
}

/** Найдем слово */
const char* findWord( const char* string, const char* word ){
    const char* ptr = string-1;
    int wordLength = strlen(word);

    if( wordLength == 0 )
        return NULL;

    for(;;){
        /*найдем подстроку*/
        ptr = strstr( ptr+1, word );
        if( ! ptr ){
            return NULL;
        }

        /* проверяем что подстрока является словом
         * проверяем начало слова --- символ перед подстрокой не должен быть символом слова
         */
        if( ptr != string && isWord( ptr[-1] ) ){
            continue;
        }

        /* проверяем конец слова
         * проверяем конец слова --- символ после подстроки не должен быть символом слова
         */
        if( isWord( ptr[ wordLength ] ) ){
            continue;
        }

        /* возвращаемся */
        return ptr;
    }

}

int wordNumber( const char* string, const char* word ){
    const char* ptr;
    int result = 1;
    
    ptr = findWord(string, word);
    if(!ptr){
        return 0;
    }

    --ptr;

    while( ptr > string ){
        /*пропускаем пробельные символы*/
        while( ptr > string && !isWord(*ptr) ){
            --ptr;
        }

        /* обновляем счетчик слов*/
        if( ptr > string )
            ++result;

        /* пропускаем слово*/
        while( ptr > string && isWord(*ptr) ){
            --ptr;
        }
   }
    
    return result;
}


void testFindWord(){
    const char* ptr;
    ptr = "0";
    assert( findWord(ptr,"0") == ptr );
    ptr = " 0";
    assert( findWord(ptr,"0") == ptr+1 );
    ptr = " 0 ";
    assert( findWord(ptr,"0") == ptr+1 );
    
    ptr = "00";
    assert( findWord(ptr,"0") == NULL );
    ptr = " 00 ";
    assert( findWord(ptr,"0") == NULL );
    ptr = " zzz z";
    /*     012345 */
    assert( findWord(ptr,"z") == ptr+5 );
    ptr = "01";
    assert( findWord(ptr,"01") == ptr );
    ptr = " 01";
    assert( findWord(ptr,"01") == ptr+1 );
    ptr = " 01 ";
    assert( findWord(ptr,"01") == ptr+1 );
    ptr = "0101";
    assert( findWord(ptr,"10101") == NULL );
    ptr = " zxz   zx";
    /*     01234567*/
    assert( findWord(ptr,"zx") == ptr+7 );
}

void testWordNumber(){
    assert( wordNumber("Я изучаю чистый Си", "чистый") == 3 );
    assert( wordNumber("   Я изучаю чистый Си", "чистый") == 3 );
    assert( wordNumber("   Я изучаю нечистый чистый Си", "чистый") == 4 );
    assert( wordNumber("   Я изучаю чистыйне чистый Си", "чистый") == 4 );
    assert( wordNumber("Я изучаю нечистый чистый Си", "чистый") == 4 );
    assert( wordNumber("Я изучаю нечистый чистый Си", "Я") == 1 );
    assert( wordNumber("Я", "Я") == 1 );
    assert( wordNumber("Я изучаю нечистый Си", "чистый") == 0 );
    assert( wordNumber("Я изучаю нечистый Си ", "чистый") == 0 );
    assert( wordNumber("Я изучаю нечистый Си", "") == 0 );
    assert( wordNumber("", "") == 0 );
    assert( wordNumber("", "негдеискать") == 0 );
    assert( wordNumber("   ", "негдеискать") == 0 );
    assert( wordNumber("   ", "") == 0 );
}

int main(){
    testFindWord();
    testWordNumber();
    return 0;
}



--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Optimus
Дата 28.10.2007, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Предложу свой вариант, где регистр не имеет значение:
Код

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>

char ToUpper(char ch);
int Equal(char *s, char *str);

void main()
{

  char s1[] = "Я изучаю чистый Си";
  char str[] = "Чистый";
  char tmp[30];
  char *t;
  int isContain = 0;
  int number = 1;

  strcpy(tmp, s1);

  t = strtok ( tmp, ", " ) ; //здесь ставим разделители слов

  while ( t != NULL )
  {
    if (Equal(t, str))
    {
      isContain = 1;
      break;
    }
    ++number;
    t = strtok ( NULL, ", " ) ; //здесь ставим разделители слов
   }

  if (isContain == 1)
  {
    printf("%d слово", number);
  }
  else
  {
    printf("не содержится");
  }

  getch();
}

//-------------------------------------------------------------------

char ToUpper(char ch)
{
  if (ch >= 'а' && ch <= 'п' )
    ch -= 32 ;
  else if (ch >= 'р' && ch <= 'я' )
    ch -= 80 ;
       else if (ch >= 'a' && ch <= 'z')
     ch -= 32;

  return ch;
}

//-------------------------------------------------------------------

int Equal(char *s, char *str) // возвращает 1 если стоки ровны, без учета регистра
{
  int lenOfStr;
  int i;
  int j;
  int equal = 0;

  for (lenOfStr = 0; str[lenOfStr] != '\0'; ++lenOfStr);

  for (i = 0; s[i] != '\0' && equal == 0; ++i)
  {
    if (ToUpper(s[i]) == ToUpper(str[0]))
    {
      for (j = 1; s[i+j] != '\0' && str[j] != '\0'; ++j)
      {
    if (ToUpper(s[i+j]) != ToUpper(str[j]))
      break;
      }

      equal = (lenOfStr == j) ? 1 : 0;
    }
  }

  return equal;
}

после использования функции strtok() строка изменяется, по этому в начале мы делаем ее копию
Код

strcpy(tmp, s1);


Это сообщение отредактировал(а) Optimus - 28.10.2007, 23:14
--------------------
"постановка задачи наполовину решает саму задачу"
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

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

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


 




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


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

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