LINUX.ORG.RU

Программа: удаление всех повторяющийхся цифр (и букв в слове). С [в доработке]

 ,


1

3

Упражнялся вчера с С и решил что-нибудь более или менее полезное написать для работы со строками символами, с исп. stdio. И вот такое получилось. Принимает один аргумент: Зачем может быть нужна?! Когда тебе твоя девушка пишет все время вот так: «даааааа, вооооот» = ) (но пока удаляет только ASCII - цифры и лат. алфавит. Только из слов без кавычек) и вообще делает символы в слове уникальными, типа на входе «good», на выходе «god» или на входе «pool», на выходе «pol»

Тема отредактирована. См. комментарии ниже. Решение внизу

//This small prorgam removes all duplicated characters out of a word
//Программа удаляет все повторяющиеся символы из слова
//Author dcc0@yandex.ru 2018.

#include <stdio.h>
int main(int argc, char* argv[]) {
  //here we check arguments//проверяем аргументы
  if (argc < 2) {
    printf("Argument must be a word:\n");
    return 0;
  }

  int x, i, j;
  //it calculates an array's length
  //вычисляем длину слова и печатаем
  for (x = 0; argv[1][x] != '\0'; x++);
  printf ("Original length: %d\n", x);
  x=x+1;
  //here we search twins
  //ищем одинаковых
  for (i = 0; i != x; i++) {
    j = i + 1;
    while (j != x) {
      if (argv[1][i] == argv[1][j]) {
        argv[1][i] = '0';
      }
      j++;
    }
  }
j=0;
  //Output
  //Вывод
  for (i = 0; i != x; i++) {
    if (argv[1][i] != '0') {
      printf ("%c", argv[1][i]);
      j++;
    }
  }
  printf ("\nNumber of uniqe symbols: %d\n", j-1);
}

P.S. Форматирование поправил. Лишний блок из кода убрал. Комментарии на русском есть. P.P.S Ну вот еще подсократилось. «Динамическое вычисление длины массива убрали. В принципе можно и вычисление x убрать.

P.P.P.S Теперь и такую строку вроде правильно обрабатывает: „teeest teeestt tteeessstt“ Original length: 25 est Number of uniqe symbols: 4 Осталось сделать транслит функцию.



Последнее исправление: AnonymUser (всего исправлений: 27)

как оно у тебя может обрабатывать «даааааа, вооооот» если у тебя нет даже намека на юникод? Впрочем и английский оно обрабатывает не корректно, пиши ещё. ))

vasyan
()
Ответ на: комментарий от vasyan

Только ASCII А имеется ввиду, когда девушка на английском пишет = ) То. есть уехала она зарубеж и русской раскладки у неё там нет и пишет вот так «daaaaa vooooot»

AnonymUser
() автор топика
Ответ на: комментарий от AnonymUser

Ваша программа не работает вот с такими данными…

Зато вот с такими работает!

anonymous
()
#include <uchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

// Длинна без повторений
// Не используется, но пусть будет.
size_t u_lenwrep(const char32_t* src)
{
  size_t i, k, len;
  
  if(!*src) return 0;
  for(i = 1, len = 1;src[i];i++, len++) {
    if(src[i] == src[i-1]) {
      for(k = i + 1;src[k] && src[k] == src[i];k++);
      if(!(i = k)) break;
    }
  }
  return len;
}

// Копирование в dest строки src но без повторений 
size_t u_cpywrep(char32_t* dest, const char32_t* src)
{
  size_t i, j;
  
  if(!*src) return 0;
  *dest = *src;
  for(i = 1, j = 1;src[j];i++, j++) {
    if(dest[i-1] == src[j])
      for(j++;src[j] == dest[i-1];j++);
    if(!(dest[i] = src[j])) break;
  }
  return i;
}

// Вывод char32_t строки
void u_print(char32_t* str)
{
  mbstate_t state;
  char utf8_char[MB_CUR_MAX];
  size_t len;
  
  for(;*str;str++) {
    len = c32rtomb(utf8_char, *str, &state);
    printf("%.*s", (int)len, utf8_char);
  }
}

int main(int argc, char** argv)
{
  setlocale(LC_ALL, "en_US.utf8");
  char32_t str[] = U"юююнииикоооддд неее ннуужжооонн";
  
  u_cpywrep(str, str);
  u_print(str);
  
  return EXIT_SUCCESS;
}

linuhs_user
()
Последнее исправление: linuhs_user (всего исправлений: 3)
Ответ на: комментарий от vasyan

K&R не читал

Я вот — читал. Юникод тогда ну разве что только рожали. И нормально удалялось в 8-битной кодировке всё.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Класс, что работает. В коде возврат по ссылке вижу.

Не-не,я от stdio ни на шаг, максимум stdlib и string.

Но программу свою выкидывать не буду, так как - я пытаюсь понять, сколько «максимальное среднее» число букв может быть в английском слове, да и в русском тоже. Как мне кажется, за 10 не выходит. Если так, тогда даже мой код все еще имеет смысл.

AnonymUser
() автор топика
Ответ на: комментарий от vodz

Меньше информации, написал бы просто «н.умт.». Ну можно было бы и так, если намек на это.

size_t u_cpywrep(char32_t* dest, const char32_t* src)
{
  size_t i;
 
  *dest = *src;
  if(!*src) return 0;
  for(i = 1;*src;i++, src++) {
    if(dest[i-1] == *src)
      for(src++;*src == dest[i-1];src++);
    if(!(dest[i] = *src)) break;
  }
  return i;
}

linuhs_user
()
Последнее исправление: linuhs_user (всего исправлений: 3)

стиль ни к черту

если ставишь пробел перед открывающей круглой скобкой, то ставь его везде

anonymous
()
Ответ на: комментарий от linuhs_user

у тебя везде d[...]=...
кроме одного места, где *d = ...
это или стилистическая ошибка/небрежность или намеренное подчеркивание разницы

anonymous
()
Ответ на: комментарий от anonymous

А я даже о таком не задумывался, ну со звездочкой тут короче выходит, вот и поставил), спасиба.

linuhs_user
()
Ответ на: стиль ни к черту от anonymous

Пробелы расставил, спасибо.

Заодно удалил один цикл - лишний. Код отредактировал в начале топика,тему тоже.

В общем вот такое слово обрабатывает корректно вроде бы. без пробелов если:

asdffgghhjjklllmmnnttrraasshhffttttttttttsssssssssssssss1111112382367483264283674333333333 dgjklmnrahfts1286743

Соответственно, 34 символа, достаточно, чтобы сопоставить 33 буквам русского алфавита. Напрашивается скрипт на bash с сопоставлением и конвейер, под обработку отдельного слова. Можно другие символы аски по русский алфавит определить, чтобы не трогать лат. алфвавит.

AnonymUser
() автор топика
Ответ на: комментарий от AnonymUser

сперва ты пишешь про удаление повторений, потом переобуваешься в полете и говоришь что твоя программа про уникальные символы, тем самым некрасиво поступая с людьми которые тебе тут уже и с юникодом акробатику показывают. Ты троль? )

vasyan
()
Ответ на: комментарий от vasyan

Вернее, лучше всего как вариант linuhs_user, но еще и вариант со срезанием всех повтором тоже пригодиться

AnonymUser
() автор топика
Ответ на: комментарий от AnonymUser

Так может стоит уже озвучить изначально решаемую задачу, а не твой конкретный метод решения её подзадач.

anonymous
()

а комменты для нас по-русски?

chenger ★★
()
Ответ на: комментарий от AnonymUser

What the hell - gitler? -> what the hel - gitler?

Совсем не роляют..

Для русского языка

еду в ООО остановочка -> еду в О остановочка

chenger ★★
()
Последнее исправление: chenger (всего исправлений: 1)
Ответ на: комментарий от linuhs_user

А почему так много лапши, разве это не то же самое?

size_t u_cpywrep(char32_t * dest, const char32_t * src) {
  char32_t * start = dest;  
  while((*dest = *src++)) dest += (*dest != *src);
  return dest - start;
}
LjubaSherif
()

Это не си. Целиком и полностью. Ну и самое главное, автор указан - куда же без него.

Решение проблемы очень просто - первые, выкинуть нахрен то, либо тех, кто так научил. Попробовать ещё раз, а после запостить сюда для получения ответа на вопрос «сейчас то, либо опять нет».

Иначе это полностью тупиковая ветвь развития.

LjubaSherif
()

более или менее полезное

делает символы в слове уникальными, типа на входе «good», на выходе «god» или на входе «pool», на выходе «pol»

Очень полезно, да, только у тебя совсем другие слова получаются. А на питоне ты бы уже поднял бложик на джанге на локалхосте за то же время.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от chenger

может быть я тролль, чего хотите?

Кстати, после обработки буду троль. Звучит как приказ.

Приказом или императивом будет как раз «тролль!», а «троль!» не имеет смысла, потому что такого слова нет, и значения оно не имеет соответственно.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

А на питоне ты бы уже поднял бложик на джанге

Спасибо, проблевался. А можно теперь нескромный вопрос: наяху еще один санный бложик билять?

anonymous
()
Ответ на: комментарий от anonymous

Друзья, предлагаю обойтись без перепалки. Задача приблизительная. У нас не плановая экономика. Решение, высказанное ранее устраивает, спасибо linuhs_user Свое также буду дорабатывать. Как лучше сделать пока я не знаю сам.

AnonymUser
() автор топика

Мне вот интересно, кому нифиг надо в 21 веке ковырять строки через указатели? Вот кто на плюсах может в одну строчку написать современно, стильно и модно?

Bobby_
()
Ответ на: комментарий от AnonymUser

bool seen[ UCHAR_MAX] = {0}; std::erase(std::remove_if(std::begin(str), std::end(str), [&seen](unsigned x) { unsigned char lower = std::to_lower(x); bool result = seen[lower - 'a']; seen[lower - 'a'] = true; return result; }));

Bobby_
()
Ответ на: комментарий от LjubaSherif

А почему так много лапши, разве это не то же самое?

Вот пристали к человеку, ну не умеет он так. :)

Но код явно из серии меньше символов в исходнике любой ценой производительности? Я угадал? Может оптимизатор и выкинет лишние присваивание, бог его знает, докуда мысль оптимизаторская дошла, но так всё же лучше:

....
while((*dest = *src++)) {
        while (*dest == *src)
                src++;
        dest++;
  }
return ...

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)

Я свой говнокод на гите не афиширую, но здесь...

hbars ★★★★★
()
Последнее исправление: hbars (всего исправлений: 1)

Почини форматирование кода, глаза вытекают.

anonymous
()
Ответ на: комментарий от vodz

Но код явно из серии меньше символов в исходнике любой ценой производительности?

Всё совершенно иначе. Она не только меньше.

Может оптимизатор и выкинет лишние присваивание

Зачем? Лишние этот вот этот мусор - while (*dest == *src), а присваивание не лишнее. Оно бесплатное.

LjubaSherif
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.