Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: [C++] Обработка строк  (Прочитано 20062 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
Staxxx
Гость
« : 25-12-2008 21:09 » new

очень лёгкая!) но мне ни как не додуматься что надо дописать..

задание: написать программу для обработки строки. Вводиться строка состоящая из букв и цифр. а выводиться обработанная по условию:
символов меньше 10 (сделал);
удаляются все маленькие буквы и знаки пунктуации (и это я сделал);
цифры окружить пробелами (в этом и собстна небольшая загвостка);

пример: ввести строку -> FdFG145F6
              вывести строку -> FFG 1 4 5 F 6

я написал цикл, окружающий цифры в строке (которые я нахожу isdigit'oм), но загвостка в том, что надо ставить пробел и перед цифрой.. с эти и прошу помочь!

код:

Код:
#include <string>  
#include <iostream>
using namespace std ;
int main ( ) 
{
    char tmp [80] ;
    do 
    {
        cout << "Vvedite stroku tmp" << endl ;
        cin.getline (tmp,80) ;
        if (!strcmp (tmp,"")) 
            break ; 
 
    char *px ;
        px = new char [strlen (tmp) +1] ;
        strcpy (px, tmp) ;
        cout << "Blok raven ->" ;
        char *py, *pz ;
        py = px ;
        pz = py ;
            if (strlen (px)< 10)
            {   
                while (*py)
            {
                    if (ispunct(*py) || islower(*py))
                    {
                    for ( pz=py ; *pz ;pz++)
                    *pz = *(pz + 1);
                    }
                    else
                    py++ ;
            }
                py=px; 
            while (*py)
            {
                if (ispunct (*py))
                {
                    for (pz=py+strlen(py) ;pz!=py ; pz--)
                        *(pz+1)=*pz;
                    *(py+1)=*py;
                    py=py+2;
                }
                py=py+1;
            }
            py=px; 
            while (*py)
            { 
 
            if (isdigit (*py))
                {
                   
                    for (pz=py+strlen(py);pz!=py ; pz--)
                        *(pz+2)=*pz;
                    *(py+1)=' ';
                    *(py+2)=' ';
                py=py+2;
                }
                py=py+1;
            }
           
            }
            else cout << "Men'she 10 simvolov"<< endl;
            cout << px << endl ;
            delete px ;
    }   
 
    while (1);//
    int n(0);
    return 0 ;
   
}


прошу помощи!
« Последнее редактирование: 25-12-2008 21:12 от Вад » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 25-12-2008 21:15 » 

Очевидно, нужно ставить пробел перед каждым числом, а также перед каждым не-числом, перед которым находится число Улыбаюсь
Записан
Staxxx
Гость
« Ответ #2 : 25-12-2008 21:21 » 

да, это всё хорошо) но я не понимаю как написать на языке C++)
Записан
Staxxx
Гость
« Ответ #3 : 25-12-2008 21:22 » 

мне препод сказал что типа перед числом нужно просто напросто сдвигать строку вправо на пробел
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 25-12-2008 21:35 » 

в MFC (правда, долгоработающий алгоритм Улыбаюсь Но если действие одноразовое - покатит):

Код:
CString txt= ".... входная строка";

char LitLetter[2]="a";

//удаляем мелкие буквы латинского алфавита
for(LitLetter[0]='a'; LitLetter[0]<='z'; LitLetter[0]++)
{
   txt.Replace(LitLetter,"");
}

//ставим пробелы перед цифрами
char SpNum[3]=" 0";

//сначала чистим: все комбинации " #" (пробел и цифра) заменяем на "#" (цифра)
for(SpNum[1]='0'; SpNum[1]<='9';SpNum[1]++)
{
  while(txt.Replace(SpNum,&SpNum[1]));
}

//теперь перед каждой цифрой вставляем пробел
for(SpNum[1]='0'; SpNum[1]<='9';SpNum[1]++)
{
  txt.Replace(&SpNum[1],SpNum);
}

(компилировал, но не тестировал)

думаю, легко переделать для других классов строк )
« Последнее редактирование: 25-12-2008 22:26 от Алексей1153++ » Записан

Staxxx
Гость
« Ответ #5 : 25-12-2008 22:22 » 

спасибо!
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 25-12-2008 22:30 » 

кстати, два последних цикла можно объединить:

Код:
for(SpNum[1]='0'; SpNum[1]<='9';SpNum[1]++)
{
  //сначала чистим: все комбинации " #" (пробел и цифра) заменяем на "#" (цифра)
  while(txt.Replace(SpNum,&SpNum[1]));

  //теперь перед каждой цифрой вставляем пробел
  txt.Replace(&SpNum[1],SpNum);
}
Записан

Staxxx
Гость
« Ответ #7 : 26-12-2008 17:31 » 

о ужас) короче прога у меня работает на ура, только компилятор ругается.. что я залезаю в невыделенное место в памяти,
мне предложили, чтобы я делал так:
вот строка - DDD123 , "протягиваем" цифру
и получается - DDD11123 , заменяем две единици на два пробела, надо написать что то типа *(py+1)=*py
                               ||  ||                                                                                                                или py-1=py
                               ' '  ' '
и создать цикл, который будет брать каждуу цифру по очереди и таким образом окружать её пробелами, понимаю что это ужасно но прошу помочь))
Записан
Staxxx
Гость
« Ответ #8 : 26-12-2008 18:54 » 

хм) лана, додумаюсь напишу
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 26-12-2008 19:35 » 

Неужели транслятор с автоматом не написать? Или надо непременно в той же самой строчке пробелы вставлять?

Даже не автоматом, а простейшей функцией: на входе символ строки-источника, на выходе строка: либо пустая, если символ нужно исключить, либо с символом, если его надо оставить, либо с символом и пробелами кругом.

Идти по символам строки-источника, результаты функции складывать как строки в приёмник.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Staxxx
Гость
« Ответ #10 : 26-12-2008 20:05 » 

смысл такой, вводиться строка, находяться цифри, окружаются пробелами. тока для этих пробелов место в памяти не выделяется) спп меня в могилу сведёт)
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 26-12-2008 20:18 » 

Цитата: Staxxx
тока для этих пробелов место в памяти не выделяется) спп меня в могилу сведёт)
Да, в C не было и нет автоматического управления памятью. Однако в C++ строчка как тип данных string стандартной библиотеки является динамической, сама управляет памятью и поддерживает в том числе операции сложения. Поэтому в C++ я не вижу таких уж больших трудностей.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Staxxx
Гость
« Ответ #12 : 26-12-2008 20:21 » 

да я бы тут не писал, если бы понимал что написать в коде, чтобы это место выделилось) эта лаба как заноза в ноге если чесно) она была третьей, а я уже 8 сдал, которые намного жещще)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 27-12-2008 03:56 » 

Staxxx, сделай процедуру, которую вызовешь 2 раза:

int mycorrecting(const char* inputstr,char* outputstr=0, int lenofoutput=0);

процедура принимает указатель на входную строку, возвращает количество символов, нужное для выходной строки. Если указать outputstr==0 , то работа с выходной строкой не производится, а только подсчитываются выходные символы

в итоге:
Код:
const char* pIn="входная строка";
int len=0;
len=mycorrecting(pIn);
if(len)
{
   char* pOut=new char[len]

   if(len==mycorrecting(pIn,pOut,len))
   {
     //pOut - искомая выходная строка
   }


   delete [] pOut;
   pOut=0;
}
« Последнее редактирование: 27-12-2008 03:59 от Алексей1153++ » Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 27-12-2008 10:32 » 

Алексей1153++, какой кошмарный стиль WinAPI 80-х годов Улыбаюсь А потом говорят, что винда тормозит Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 27-12-2008 12:35 » 

dimka, покажи, где что тормозит ? ) Ну, кроме того, что 2 раза расчёт. Но это я из лени )

Цитата: мну
(правда, долгоработающий алгоритм  Но если действие одноразовое - покатит)
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #16 : 29-12-2008 06:14 » 

я бы сделал на так:
Код:
void Test()
{
std::string istr;
std::cout << "Enter string: " << std::endl;
std::cin >> istr;
const int max_str_len = 9;

if (istr.size() > max_str_len)
{
std::cout << "Too long" << std::endl;
return;
}

std::string ostr;
bool lastCharIsDigit = false;

typedef std::string::iterator iterator; // можно земенить на номер элемента
for (iterator it = istr.begin(); it != istr.end(); ++it)
{
if(ispunct(*it) || islower(*it))
continue;

if (isdigit(*it))
{
lastCharIsDigit = true;
ostr.push_back(' ');
}
else
{
if (lastCharIsDigit)
ostr.push_back(' ');

lastCharIsDigit = false;
}

ostr.push_back(*it);
}

std::cout << "Result: " << ostr << std::endl;
}

и заметьте один проход.
« Последнее редактирование: 29-12-2008 06:15 от LogRus » Записан

Странно всё это....
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines