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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Си] Функция поиска в строке 
:(
    Опции темы
Foxxx
Дата 20.11.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Необходимо написать функцию, которая принимает строку с (нулевым байтом), производит в ней поиск наибольшего количества цифр, стоящих подряд. Ф-я возвращает строку из найденных цифр.

Пример. Есть строка: "qwerty2qwerty 22 2 q 2 1qeqe323eq2". Функция возвратит 323.

 smile 
PM MAIL   Вверх
Walker
Дата 20.11.2007, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Доброго времени суток. Например, так?
Код

/* Функция помимо сформированной строки возвращает её длину */
int function_name(line, longest)
char *line;            /* Анализируемая строка */
char *longest;      /* Сюда положим самую длинную последовательность */
{
   int len = 0;                            /* Длина каждой измеряемой последовательности*/
   int maxlen = 0;                      /* Самая длинная последовательность */
   int length = getlength(line);  /* Каким-нибудь образом нужно знать длину анализируемой строки, чтобы выделить место для хранения числовой последовательности */
   char numberline[length];       /* Перезаписываемый буфер для хранения  каждой считываемой последовательности */
   while(*line != '\0')                           /* Бежим по анализируемой строке*/
   {
     if('0' <= *line && *line <= '9')        /* Читаем встретившуюся последовательность чисел */
     {
        *(numberline + len) = *line;
        len++;
     }
     else if (len > maxlen)                     /* Если она больше хранимой, перезаписываем */
     {
        maxlen = len;
        copy(longest, numberline);
        len = 0;
     }
     else
        len = 0;
     line++;
   }
   return maxlen;
}

Плюсы: алгоритм однопроходный.
Минусы: требует выделение памяти под строку для временного сохранения перед анализом каждой встреченной числовой последовательности
Возможная оптимизация предложенного алгоритма: выделять для временного хранения числовой последовательности память динамически с помошью p = alloc(n) и free(p), где p - указатель на место в памяти для хранения n типов.



--------------------
"От вчерашних побед остаётся усталость, если завтрашний день не сулит ничего..."
PM MAIL   Вверх
Foxxx
Дата 20.11.2007, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А можно без указателей как-нить. Просто в функцию передается массив символов. И не надо дополнительных фичей типа возвращения длины строки. Необходимо получить строку, найти данные, и вернуть строку.

Добавлено через 32 секунды
Может кто-нить еще что-нить подкинет smile 
PM MAIL   Вверх
Walker
Дата 20.11.2007, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

И не надо дополнительных фичей типа возвращения длины строки. Необходимо...

Уважаемый Foxxx, любой преподаватель будет счастлив, если его ученик обретёт системное мышление, применительно к инженеру (не только ПО), будет видеть задачу, стоящую перед ним, с комплексной точки зрения и мыслить категориями принципиальных схем и алгоритмов в первую очередь. Вы же сразу обратили внимание на детали реализации. Функция выполняет должна выполнять поставленные Вами изначально условия. Если она по каким-то причинам этого не делает - необходимо сперва разобраться, почему и устранить недостаток. Если же она со своей задачей справляется - оформляйте, как душе угодно. Ну не нравится Вам, что она возвращает длину, а собираемая строка передаётся через параметр, так возьмите и объявите её внутри функции, а возращаемое значение объявите char[] - дело-то вкуса. Вот мне было жалко просто так терять maxlen, тем более, что в С возращаемый по умолчанию тип - int.
Цитата

А можно без указателей как-нить. Просто в функцию передается массив символов.

 smile  Массив в С - формальность для облегчения восприятия и, иногда, управления многократными прогулками по наборам данных. Старайтесь сразу представлять, как Вы оперируете памятью. Опять же - не нравится моё представление, ну введите индексацию - замените конструкцию типа
Код

*(numberline + len) = *line;

на
Код

numberline[len] = line[i];

компилятор сделает остальное, а в происходящих фактически процессах работы с памятью ничего не изменится!

Удачи!


Это сообщение отредактировал(а) Walker - 20.11.2007, 12:58


--------------------
"От вчерашних побед остаётся усталость, если завтрашний день не сулит ничего..."
PM MAIL   Вверх
Foxxx
Дата 20.11.2007, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо. Но хотелось бы еще примеров от других пользователей, простите, программистов smile 
PM MAIL   Вверх
Walker
Дата 20.11.2007, 13:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Другое дело! smile 
Я тоже за "мозговой штурм"! smile 



--------------------
"От вчерашних побед остаётся усталость, если завтрашний день не сулит ничего..."
PM MAIL   Вверх
Optimus
Дата 20.11.2007, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Код

char* GetMaxLenStrNumber(char *str)
{
  char maxLenStrNumber[80]; // надо поставить нужный размер
  int i;
  int j;
  int beg = 0;
  int end = 0;
  int maxLen = 0;

  for (i = 0; str[i] != '\0'; ++i)
  {
    if (str[i] >= '0' && str[i] <= '9')
    {
      for (j = i + 1; str[j] != '\0' && str[j] >= '0' && str[j] <= '9'; ++j);

      if (maxLen < j - i)
      {
    beg = i;
    end = j - 1;
    maxLen = j - i;
      }

      i = j;
    }
  }

  if (maxLen == 0) // если нет подстроки с цифрами, возвращаем пустую строку
  {
    strcpy(maxLenStrNumber, "");
    return maxLenStrNumber;
  }

  for (i = 0; i <= end - beg; ++i)
  {
    maxLenStrNumber[i] = str[i+beg];
  }

  maxLenStrNumber[i] = '\0';

  return maxLenStrNumber;
}


Добавлено через 5 минут и 17 секунд
P.S. в случае если есть несколько строк с наибольшем количества цифр, функция вернет только первую строку
--------------------
"постановка задачи наполовину решает саму задачу"
PM MAIL   Вверх
Dov
Дата 20.11.2007, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Код

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

// функция поиска подстроки
char* FindSubStr(char* str)             
{
    char* buf;
    int   pos;                       // начальная позиция текущей последовательности
    int   len;                       // длина текущей последовательности
    int   max = 0;                   // максимальная длина подстроки
    int   beg = 0;                     // начало подстроки
    int   i;    

    for(i = 0; str[i] != '\0'; i++)
    {
        len = 0;                     
        pos = i;                     
        
        // пока очередной символ 'цифра'
        for( ; isdigit(str[i]); i++)
            len++;                   // увеличиваем текущую длину                                   
        
        // если текущая длина больше максимальной 
        if(len > max)
        {
            // то запоминаем новые значения
            beg = pos;               // начала подстроки
            max = len;               // и её максимальной длины
        }
    }

    // выделяем память для строки 
    if((buf = (char *)malloc(sizeof(char) * (max + 1))) == NULL)
    {
        puts("\nFailed to allocated memory!\n");
        exit(1);
    }

    // и копируем в неё найденную подстроку 
    strncpy(buf, str + beg, max);
    buf[max] = '\0';

    // возвращаем найденную подстроку
    return buf;
} 

int main()
{
    char* str = "qwerty2qwerty 22 2 q 2 1qeqe323eq2";
    char* sub = FindSubStr(str);

    printf("Source: %s\n", str);
    printf("Result: %s\n", sub);

    // освобождаем выделенную в ф-ции FindSubStr память
    free(sub);
    return 0;    
}



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Foxxx
Дата 21.11.2007, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А если немножко изменить задание:

Функция ничего не принимает и не возвращает (void).

Есть глобальные переменная - char data[256] - исходная строка.
char maxnumbers[256] - строка результата.

Необходимо со строкой data проделать тоже самое и скопировать результат в numbers.

У меня что то не получается

Код

void findDigit () {
    unsigned int len = 0;
    unsigned int max = 0;
    char numbers[256];
    char maxnumbers[256];
    for(int i=0; data[i] != '\0'; ++i) {
        if(data[i] >= '0' && data[i] <= '9') {
            numbers[len] = data[i];
            len++;
        } else
            if(len > max) {
                max = len;
                numbers[len] = '\0';
                strcpy ( maxnumbers, numbers );
                len = 0;
            } else len = 0;
    }
    puts(data);
}


PM MAIL   Вверх
Optimus
Дата 22.11.2007, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Foxxx @  21.11.2007,  15:28 Найти цитируемый пост)
А если немножко изменить задание:

а если немножко подумать  smile 

Код

void GetMaxLenStrNumber();

char str[256];
char maxLenStrNumber[256];

void main()
{
  //код
}

void GetMaxLenStrNumber()
{
  int i;
  int j;
  int beg = 0;
  int end = 0;
  int maxLen = 0;

  for (i = 0; str[i] != '\0'; ++i)
  {
    if (str[i] >= '0' && str[i] <= '9')
    {
      for (j = i + 1; str[j] != '\0' && str[j] >= '0' && str[j] <= '9'; ++j);

      if (maxLen < j - i)
      {
    beg = i;
    end = j - 1;
    maxLen = j - i;
      }

      i = j;
    }
  }

  if (maxLen == 0)
  {
    strcpy(maxLenStrNumber, "");
    return;
  }

  for (i = 0; i <= end - beg; ++i)
  {
    maxLenStrNumber[i] = str[i+beg];
  }

  maxLenStrNumber[i] = '\0';
}

--------------------
"постановка задачи наполовину решает саму задачу"
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

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


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

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

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

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


 




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


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

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