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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> удаление предпоследнего слова 
:(
    Опции темы
Weman
Дата 4.12.2005, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Помогите с задачей:
В символьной строке удалить предпоследнее слово.
Если можно, то приведите код с пояснениями для новичка в этом деле.
Спасибо
--------------------
PM MAIL ICQ   Вверх
nikitao
Дата 4.12.2005, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

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



А что можно использоваь?STL можно?


--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
Dov
Дата 4.12.2005, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



А что ты называешь словом? Например: "РжуНиМагу"- сколько здеся слов?


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


Практик
**


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

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



Это для какого класса задачки? smile

Код

 char delimeter=' ';  // символ разделитель слов (в данном случае пробел)

 char szLine[100];
 strcpy(szLine,"Это нельзя делать");

char* ptr, *ptok;
int size;    

ptr=szLine;         // указатель в начале строки

ptok=strrchr(ptr,delimeter);                             // ищем последний пробел (откуда писать)
if (ptok!=NULL) {        // если это не единственное слово (указатель не нулевой)
      
size=ptr+strlen(szLine)-ptok;                // длина последнего слова (сколько писать)
ptr=ptok-1;
ptok++;   

while (ptr>=szLine && *ptr!=delimeter) ptr--;     // ищем предпоследний пробел (куда писать)
                                                             //  если нет, то пишем в начало строки
memmove(ptr+1,ptok,size);
*(ptr+size)='\0';               // ограничитель новой строки
 
}



Это сообщение отредактировал(а) Aleksandor - 4.12.2005, 22:16


--------------------
Call out Gouranga be happy!!!
Gouranga Gouranga Gouranga ....
That which brings the highest happiness!!
PM MAIL   Вверх
nikitao
Дата 4.12.2005, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

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



Я думаю,что слово это последовотельность символоа ограниченная с двух сторон знаками разделителями(за исключением первого и последнего слов).Т е "РжуНиМагу" это одно слово


--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
Dov
Дата 4.12.2005, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(nikitao @ 4.12.2005, 21:48)
Я думаю,что слово это последовотельность символоа ограниченная с двух сторон знаками разделителями(за исключением первого и последнего слов).Т е "РжуНиМагу" это одно слово

Ну, значится, Aleksandor`у нужно доработать. smile


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


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

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



Человек просил по-проще:
Код
#include <string.h>


void main()
{
    char stroka[] = "slovo1 slovo2 slovo3 slovo4";
    char buf[80];
    int dlina = strlen(stroka); // получаем длину строки
    int j = 0, i;
    for (i = dlina-1; i >= 0; i--)
    {
        if ((j != 0)&&(stroka[i] == ' ')) // j - кол-во символов в последнем слове
            break; // если кол-во != 0 и пришли к пробелу, то последнее слово в кармане
        buf[j++] = stroka[i]; //вырезаем с конца - потому задом-наперед
        buf[j] = 0; //добавляем символ завершения строки
    }
    int sled = 0; // флаг - есть ли предпоследнее слово
    for (; i >= 0; i--)
    {
        if (stroka[i] != ' ') // если дошли до "непробельных" символов
            sled = 1; // то след. слово есть
        if ((stroka[i] == ' ')&&(sled)) // если дошли до след. пробела через слово
            break; // значит пришли в положение начала предпоследнего слова
    }
    i++; // оставляем один пробел
    do
    {
        stroka[i++] = buf[--j]; // записываем на место предпоследнего слова последнее
    } while (buf[j]);
}

PM MAIL ICQ   Вверх
Dov
Дата 4.12.2005, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Fixin, не хочется повторятся, но всё-таки, что будет, если ввести такую строку:
Код
char stroka[] = "slovo1,slovo2,slovo3,slovo4";



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


Практик
**


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

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



Вот еще примерчик, приближенный к реальной жизни, так сказать... smile

Код

 char szDelimeters[]={", -"};  // символы разделители слов, любой из трех-запятая, пробел,тире
 char szLine[]={"Гости дорогие,не стесняйтесь-проходите!"};


char* ptr, *ptok;
int size;    

ptr=szLine+strlen(szLine)-1;        // ставим указатель на конец строки

while (NULL==strchr(szDelimeters,*ptr) && ptr>=szLine) ptr--;    // ищем символ-разделитель (первый с конца)
if (ptr>szLine) {                            // нашли, иначе это единственое слово в строке!
      
size=szLine+strlen(szLine)-ptr;   // длина последнего слова
ptok=ptr+1;                                 // указатель на начало последнего слова
ptr--;                                            // указатель на конец предпоследнего слова (предположим что только один разделитель между словами!)

while (ptr>=szLine && NULL==strchr(szDelimeters,*ptr)) ptr--;     // ищем следующий (с конца) разделитель 
                                                             //  если не нашли то пишем в начало строки
memmove(ptr+1,ptok,size);
*(ptr+size)='\0';                                   // записываем 0 в конец новой строки
}




--------------------
Call out Gouranga be happy!!!
Gouranga Gouranga Gouranga ....
That which brings the highest happiness!!
PM MAIL   Вверх
Dov
Дата 5.12.2005, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Тады и я суну свои 5 копеек. Мне и комментировать нечего.
Код
#include <iostream.h> 
#include <string.h>    
#include <ctype.h>

void main()    
{    
    char source[] = "slovo1, slovo2; slovo3 - slovo4 !!!";    
    char *first   = &source[strlen(source) - 1];
    
    while(ispunct(*first) || isspace(*first))
        first--;
    while(isalnum(*first))
        first--;
    while(ispunct(*first) || isspace(*first))
        first--;

    char *last = first + 1;
    while(isalnum(*(first - 1)))
        first--;

    strcpy(first, last);
    
    cout << source << endl;
}



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


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

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



Что-то вроде этого
Код

bool isAlpha(char c)
{
 return c>='a'&&c<='z' || c>='A'&&c<='Z' || c>='а'&&c<='я'&&c>='А'&&c<='Я';
}

int main()
{
  char *stroka="!!!test";//"a rosa upala na lapu asora!!! !!!! @ @@";
  char *end,*last,*begin;
  end=last=&stroka[strlen(stroka)];//указываем на конец строки

  //Перескакиваем слово.
  for(;end!=stroka&&!isAlpha(*end);end--);
  for(;end!=stroka&&isAlpha(*end);end--);

  //Ищем последнее слово
  for(;end!=stroka&&!isAlpha(*end);end--);
  if(stroka==end)
  {
    cout<<"one word only";
    return
  }
  begin=end;
  end++;//указатель после последней буквы последнего слова
  for(;begin!=stroka&&isAlpha(*begin);begin--);
  begin++;//указатель на первую букву последнего слова

  char *result=new char[(begin-stroka)+(last-end)+1]; //вырешиваем длинну новой строки без последнего слова
  memcpy(result,stroka,begin-stroka);//копируем до слова
  memcpy(&result[begin-stroka],end,(last-end)+1);//и после него 1 чтобы взять 0

  cout<<result;

  return 0;
}



--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
blackofe
Дата 5.12.2005, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(sergej @ 5.12.2005, 02:00)
ИМХО так на слово проверять надо:
Код

bool isAlpha(char c)
{
 return c>='A'&&c<='Z' || c>='a'&&c<='z' || c>='А'&&c<='Я'&&c>='а'&&c<='я';
}

имхо, не очень хорошая практика. к примеру в кодировке 1251 ты упустишь букву 'ё'. я уж не говорю о том, что русских кодировок существует, блин, аж не одна.

лучше использовать isalpha().

Код
#include <locale>
#include <iostream>
using namespace std;

int main()
{
    locale loc("russian_Russia.1251");
    //...
    bool eto_bukva = isalpha(c, loc);
    //...
    return 0;
}

PM MAIL   Вверх
sergejzr
Дата 5.12.2005, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

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



blackofe, какие надо такие и вставлять в функцию. Это подразумевается. Библиотеки не сипользовались, для наглядности. Я стараюсь в примерах не использовать либы. Нашёл хорошую стандартную функцию, экономящую кусок кода - молодец.


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
blackofe
Дата 5.12.2005, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(sergej @ 5.12.2005, 21:33)
blackofe, какие надо такие и вставлять в функцию. Это подразумевается. Библиотеки не сипользовались, для наглядности. Я стараюсь в примерах не использовать либы. Нашёл хорошую стандартную функцию, экономящую кусок кода - молодец.

вопрос не в экономии, а в правильности. твой вариант, повторюсь, не будет правильно работать. в кодировке 1251 он не учитывает буквы 'ё' и 'Ё'. в других кодировках будет вообще каша.
PM MAIL   Вверх
nikitao
Дата 5.12.2005, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

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



Не все равно работать не будет даже в стандартной кодировке(к прмеру моей в WINXP).И дело не в ё и Ё .Я топик создавал про RString,там та же проблемма.симвлы от 'А' до 'п' отделены от 'р' до 'я' кучей барохла.Короче правельность этой проги(без серьезной дороботки) можно гарантировать только в Dose,что в сегоднишние дни бесмыссленно.А в Winde сложно увидеть ее в действии т е сложно сказать правельно ли она написана "даже с учетом упрощения ситуации" .


--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
blackofe
Дата 6.12.2005, 00:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(nikitao @ 5.12.2005, 23:44)
Не все равно работать не будет даже в стандартной кодировке(к прмеру моей в WINXP).И дело не в ё и Ё .Я топик создавал про RString,там та же проблемма.симвлы от 'А' до 'п' отделены от 'р' до 'я' кучей барохла.Короче правельность этой проги(без серьезной дороботки) можно гарантировать только в Dose,что в сегоднишние дни бесмыссленно.А в Winde сложно увидеть ее в действии т е сложно сказать правельно ли она написана "даже с учетом упрощения ситуации" .

в том то и дело, что дырка между "п" и "р" существует в определенной кодировке (в частности в 866), а, допустим, в кодировке 1251 дырки нет, но буквы 'ё' и 'Ё' выведены отдельно и не вписываются в формулу 'а' <= ch && ch <= 'я'. и поэтому и существует библиотечная функция isalpha, чтобы учитывать все эти особенности кодировок.

вот пример:

Код
#include <locale>
#include <iostream>
using namespace std;

int main()
{
    unsigned int chs[] = { 0xb8, 0xff, 0x9b };
    cout << "hex, char, 1251, 866" << endl;
    for(int i = 0; i < sizeof(chs)/sizeof(chs[0]); ++i)
        cout << hex << chs[i] << '\t' << (char)chs[i] << ", " << boolalpha
                << isalpha((char)chs[i], locale("russian_Russia.1251")) << ", "
                << isalpha((char)chs[i], locale("russian_Russia.866")) << endl;
    return 0;
}


этот код рисует такую картину (символы показаны в виндовой кодировке):

Код
hex, char, 1251, 866
b8    ё, true, false
ff    я, true, false
9b    >, false, true


символ с кодом 0xb8, которым в виндовой кодировке представлена буква 'ё', в досовской кодировке представляет собой рамочный уголок. isalpha() разрулила эту ситуацию правильно. то же самое в отношении остальных символов.

Это сообщение отредактировал(а) blackofe - 6.12.2005, 01:06
PM MAIL   Вверх
Fixin
Дата 6.12.2005, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

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



Ну вы, народ, даете smile Скоро в религиозный войны уедете.
У автора топика задание на алгоритмизацию, а не на знание языка, посему предполагается простейшее решение без вызовов доп ф-ций и библиотека. А про указатели он сам говорил, что не знает. Да и, кажется, автор и сам больше не приходил. (а так, темка интересная получилась)
PM MAIL ICQ   Вверх
blackofe
Дата 6.12.2005, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Fixin @ 6.12.2005, 12:16)
Ну вы, народ, даете smile Скоро в религиозный войны уедете.
У автора топика задание на алгоритмизацию, а не на знание языка, посему предполагается простейшее решение без вызовов доп ф-ций и библиотека. А про указатели он сам говорил, что не знает. Да и, кажется, автор и сам больше не приходил. (а так, темка интересная получилась)

использовать библиотечные функции незазорно. даже printf().

а если не хочется использовать библиотечную isalpha(), то тогда надо написать свою, но корректно. пример реализации, приведенный sergej.z:

Код
bool isAlpha(char c)
{
 return c>='a'&&c<='z' || c>='A'&&c<='Z' || c>='а'&&c<='я'&&c>='А'&&c<='Я';
}


неверный. о чем, собственно, и речь.

/я уж не говорю о том, что эта функция вообще написана неправильно. но даже если ее и подрехтовать в соответствии с задумкой автора типа

Код
bool isAlpha(char c)
{
 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('а' <= c && c <= 'я') || ('А' <= c && c <= 'Я');
}


то все-равно она будет работать неверно./

Это сообщение отредактировал(а) blackofe - 6.12.2005, 19:06
PM MAIL   Вверх
sergejzr
Дата 7.12.2005, 03:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

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



Да нет, проблема в том, что char никогда не станет русским символом ни в одной совместимой с ASCII кодировкой(Я к сож. очень привык к яваскрипту и PHP). Так что функция правильно определяет букву только для латиницы.
Я ведь не говорю. что isalpha() использовать ненадо. Просто задумка не искать конкретные разделители, а считать все "небуквы" разделителями. для большего функция isAlpha не задумывалась. Только как макет.

Верный - неверный smile Алгоритм в теории показан - отбирать только буквы. Кто виноват, что в конкретных кодировках намудрили с кириллицей? Это уже техническая часть, не алгоритмическая.

Если тебя это устроит, isalpha корректнее конечно. smile

Цитата(blackofe @ 6.12.2005, 18:01)
/я уж не говорю о том, что эта функция вообще написана неправильно. но даже если ее и подрехтовать в соответствии с задумкой автора типа..

Чем твоя правильнее? Просвети.




--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
blackofe
Дата 7.12.2005, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(sergej @ 7.12.2005, 03:07)
Чем твоя правильнее? Просвети.

просвещаю. ошибка в предпоследней операции &&.

Код
bool isAlpha(char c)
{
 return c>='a'&&c<='z' || c>='A'&&c<='Z' || c>='а'&&c<='я'&&c>='А'&&c<='Я';
}


вместо нее надо писать ||.

Код
bool isAlpha(char c)
{
 return c>='a'&&c<='z' || c>='A'&&c<='Z' || c>='а'&&c<='я' || c>='А'&&c<='Я';
}


иначе, ни одна русская буква (если предположить, что русская кодировка подразумевает расположение всех букв алфавита строго друг за дружкой) не будет поймана этой функцией - ни одна русская буква не может находиться среди маленьких И среди больших букв одновременно.
PM MAIL   Вверх
sexton
Дата 7.12.2005, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sexton=Пономарь (eng)
**


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

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



Довольно известная штуковина - кусок кода из MSDN для определения слов в строке
Код

char string[] = "A string\tof ,,tokens\nand some  more tokens";
char seps[]   = " ,\t\n";
char *token;

void main( void )
{
   printf( "Sourse: %s\n\nTokens:\n", string );
   /* Establish string and get the first token: */
   token = strtok( string, seps );
   while( token != NULL )
   {
      /* While there are tokens in "string" */
      printf( " %s\n", token );
      /* Get next token: */
      token = strtok( NULL, seps );
   }
}

Можно это присобачить smile
PM MAIL WWW ICQ   Вверх
sergejzr
Дата 7.12.2005, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

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



Да, тьфу блин! это опечатка была.


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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