Страница 2 из 4

Добавлено: 16 июн 2003, 14:30
kas
А я этого и не отрецаю. Человек спросил - я, как мог, ответил.

Добавлено: 16 июн 2003, 14:45
Lynxer
По мне, так удаление дублирующихся пробелов не тянет на Обработку Текста.

Добавлено: 16 июн 2003, 16:15
Llama
Кстати, в qbasic была функция, которая меняла одну подстрку на другую... Неужели в С такого нет?

Кстати, вот вам без re, если так уж хочется изврата

#!/usr/bin/python2.2
from UserString import UserString
class mystring(UserString):
   def midtrim(self):
     while not ( self.data == self.data.replace(' ',' ') ):
     self.data = self.data.replace(' ',' ')
     return self.data


a = mystring('123 456')
print a.midtrim()

Добавлено: 19 июн 2003, 13:07
kas
Немного оптимизированная версия :lol:

Код: Выделить всё

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

char* strip_spaces(const char* in, char* out)
{
  char *p;

  p = out;
  strcpy(out,in);

  while(1)
  {
    p = strstr(p,"  ");
    if (p==NULL) break;
    strcpy(p+1,p+2);
  }
  return out;
}

int main()
{
  char *a  = "ab   raka   da b r      a";
  char b[strlen(a)];

  strip_spaces(a,b);
  printf("%s\n",a);
  printf("%s\n",b);

  return 0;
}

Добавлено: 19 июн 2003, 13:45
Lynxer
strcpy нельзя использовать для копирования перекрывающихся строк. Может свезти, а может и нет. Лучше использовать memmove.

Добавлено: 19 июн 2003, 13:58
Llama
Пипл, только не надо устраиавть из этого топика то, что из него сделали на лоре плс....

Добавлено: 21 июн 2003, 13:22
kas
Lynxer писал(а):strcpy нельзя использовать для копирования перекрывающихся строк. Может свезти, а может и нет. Лучше использовать memmove.
Спасибо, правильное замечание. Вот пофиксеная версия:

Код: Выделить всё

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

char* strip_spaces(const char* in, char* out)
{
  char *p;
  int len;

  p = out;
  strcpy(out,in);

  while(1)
  {
    p = strstr(p,"  ");
    if (p==NULL) break;
    len = strlen(p+2);
    memmove(p+1,p+2,len);
    *(p+1+len)='\0';
  }
  return out;
}

int main()
{
  char *a  = "ab   raka   da b r      a";
  char b[strlen(a)];

  strip_spaces(a,b);
  printf("%s\n",a);
  printf("%s\n",b);

  return 0;
}

Добавлено: 18 июл 2003, 02:00
satanic_mechanic
Извините за запоздалый ответ. Просто я считаю все примеры на С кривоватыми.

Там и strlen, и strstr, и memmove. Да еще удаляется по пробелу за проход этих функций. Подумайте, как это будет в машинных кодах. Да и о количестве проходов. Уж очень "оптмизированные" версии.
Программирование это не знание какого-либо языка. Это мышление.
За один проход (сложность O(n) ):

Код: Выделить всё

#include <stdio.h>

short strip (const char *from, char *to)	// возвращает длину новой строки (включая '\0')
{
    short i = 0, p = 0;
    short state = 0;      // простенький конечный автомат
                          // 0 - после любого символа
                          // 1 - после пробела

    while (from[i]) {
        if (from[i] == ' ') {
            if (state == 0) {
                to[p++] = ' ';
                state = 1;
            }
        } else {
            to[p++] = from[i];

            if (state == 1)
                state = 0;	
        }
        ++i;
    }

    to[p++] = '\0';

    return (p);
}

void main ()
{
    char a[28] = "ab   ra    ka    da     bra";
    char b[28];
	
    strip (a, b);

    printf ("a : %s\nb : %s\n", a, b);
}
ЗЫ: очень интересно - в каком компиляторе работает char b[strlen(a)];
по моему в квадратных скобках должна быть константа, вычисляемая во время компиляции, а не во время выполнения.

Короче

Добавлено: 18 июл 2003, 02:15
satanic_mechanic
to mend0za и иже с ним:

обычно вы (любители развитых средств обработки текста) говорите, что ваши примеры на perl, в bash и т. п. проще и во всю ругаете С (не все). Это всем давно известно. Но просили то код на C. Да и проще - не значит лучше (пример от kirya85 меньше). Все ведь зависит от ситуации. Проще пользователю. Но когда надо решать реальные задачи в больших приложениях. Когда критична скорость. Вы подумайте во что разворачиваются регулярные выражения в такой простой задаче (на уровне машинного кода).

Извините, наболело.

ЗЫ: насчет обработки текста в С согласен (но никто не мешает реализовать регекспы в нем).

Re: Короче

Добавлено: 18 июл 2003, 13:55
leikind
satanic_mechanic писал(а):to mend0za и иже с ним:

обычно вы (любители развитых средств обработки текста) говорите, что ваши примеры на perl, в bash и т. п. проще и во всю ругаете С (не все). Это всем давно известно. Но просили то код на C. Да и проще - не значит лучше (пример от kirya85 меньше). Все ведь зависит от ситуации. Проще пользователю. Но когда надо решать реальные задачи в больших приложениях. Когда критична скорость. Вы подумайте во что разворачиваются регулярные выражения в такой простой задаче (на уровне машинного кода).
А зачем думать? Сравнивать надо. Возьми большое-большое регулярное выражение, напиши аналог на C, и сравни c grep или awk на большом массиве текстов. Результаты тебя сильно-сильно удивят.
satanic_mechanic писал(а): Извините, наболело.

ЗЫ: насчет обработки текста в С согласен (но никто не мешает реализовать регекспы в нем).
Бред какой-то. А как ты думаешь, на чем реализованы regex engines в высокоуровневых языках? На них самих что-ли? Нет конечно. На C, как и сами языки. Тогда в чем разница использования регулярных выражений из высокоуровневых языков и С? Только в том, что реализация регулярных выражений в библиотеке pcre заставляет многих работавших с ней не очень хорошо о ней отзываться.

Добавлено: 18 июл 2003, 14:18
Гость
satanic_mechanic писал(а):]
ЗЫ: очень интересно - в каком компиляторе работает char b[strlen(a)];
по моему в квадратных скобках должна быть константа, вычисляемая во время компиляции, а не во время выполнения.
Я тестил в gcc - работает.

Добавлено: 18 июл 2003, 14:20
kas
Это был я

Добавлено: 18 июл 2003, 18:57
kas
А как вам такой вариант:

Код: Выделить всё

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

char* strip_spaces(const char* in, char* out)
{
  const char *p1, *p2;
  int l=0;

  p1 = in;
 
  while(1)
  {
    p2 = strstr(p1,"  ");
    
    if (p2 == NULL){
      strcpy(out + l,p1);
      break;
    }

    if (p2 != p1){
      memcpy(out + l, p1, p2 - p1);
      l += p2 - p1;
    }      
    
    p1 = p2 + 1;
  }
  
  return out;
}

int main()
{
  char *a  = "ab   raka   da b r      a";
  char b[strlen(a)];

  strip_spaces(a,b);
  printf("%s\n",a);
  printf("%s\n",b);

  return 0;
}
PS Может кто протестит производительность последних двух вариантов или раскажет как это грамотно сделать?

Добавлено: 18 июл 2003, 20:12
Llama
рандомный текст и time тебе в руки. Если хочешь результаты поточнее - linux single и начинай считать по 30 результатам где-то...

Добавлено: 18 июл 2003, 21:42
satanic_mechanic
[to leikind]
А зачем думать? Сравнивать надо. Возьми большое-большое регулярное выражение, напиши аналог на C, и сравни c grep или awk на большом массиве текстов. Результаты тебя сильно-сильно удивят.
Я вроде говорил: все зависит от ситуации. Сравни по скорости прогу на С, специально написанную под данную задачу, и ту же прогу на перле с регулярными выражениями (при условии, что прога не криво написана). И дело не только в том, что Перл - интерпретатор. Регулярные выражения универсальны и очень удобны. А за это мы платим скоростью. Но дело даже не в этом. Я никоим образом не умаляю роль регулярных выражений. Просто когда задается вопрос о проге на С, а кому-то надо показать как он крут:
ruby -p -e '$_.gsub!(/ +/," ")'
perl -p -e 's/ +/ /'
awk '{gsub(/ +/," "); print}'
Мне кажется это называется оффтопик (а еще позерство, красование и т. п.) !!!!!.
Бред какой-то. А как ты думаешь, на чем реализованы regex engines в высокоуровневых языках? На них самих что-ли? Нет конечно. На C, как и сами языки. Тогда в чем разница использования регулярных выражений из высокоуровневых языков и С? Только в том, что реализация регулярных выражений в библиотеке pcre заставляет многих работавших с ней не очень хорошо о ней отзываться.
Опять извечное стремление кого-то обламать. Я не идиот и прекрасно понимаю, на чем реализован Perl, Python, PHP и т. п. языки. Я говорил о написании библиотеки на С и там же ее использования в свое удовольствие (говорил просто к слову). Реализация такая, какая тебе нравится (под себя), что бы о ней хотя бы сам программист (который ее напишет) хорошо отзывался. Я не выражал мнения, что регекспы реализованы на х.. знает чем. Не правда ли. А вы в желании меня обламать, занимаетесь искажением моих мыслей.

PS. Извините за грубость, но на этом форуме я вообще часто вижу, как на новичков начинают гнать так, что у них во всю отпадает охота что-либо спрашивать. И это линукс-сообщество. Сообщество людей, которые считают, что они круче всех и при каждой возможности пытаются показать это ;(((
// это касается не всех, да и большинства не касается ... но это правда