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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Является ли строка палиндромом? (КЛАССЫ) 
:(
    Опции темы
DewDrop
  Дата 9.3.2012, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



  Палиндром - строка, которая читается одинаково в обе стороны, например: "радар" , "потоп", " а роза упала на лапу азора"(если игнорировать пробелы). Используя классы написать программу, которая возвращает 1 если строка является палиндромом и 0 в противном случае. 
Это моя первая программа , поэтому просьба не смеяться=))
Мой вариант решения: (Буду делать на цифрах)
Создать класс, где хранится строка из массива символов типа char, задать две функции: 1) считывает строку и убирает пробелы 2) с использованием функции strcmp и strrev проверить является ли она палиндромом.
 

Код

#include <iostream>
#include <string> 
#include <cstdio>
using namespace std;

class first { 
public:
char str[50]; 
char newstr[50];
void delspace(char str[50]);
int testPalindrome(char newstr[50]);
};
void first::delspace(char str[50])
{
    int i =0;
    for(int a = 0; a < strlen(str); a++)
    {
        if(str[a] != ' ') newstr[i] = str[a];
        i++;
    }
newstr[i]='\0';
}
int first::testPalindrome(char newstr[50]) 
{ 
    int result;
    result = strcmp(newstr,strrev(newstr));
    cout << result  << endl;
    return result; 
}

int main() 
{ 
    first q;
    cout << "Vvedite stroky:" << '\n' << endl;
    gets(q.str);
    q.delspace(q.str);
    q.testPalindrome(q.newstr);
    return 0;
}


Это сообщение отредактировал(а) DewDrop - 9.3.2012, 18:30
PM MAIL   Вверх
feodorv
Дата 9.3.2012, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



А в чём вопрос?)))

У Вас в delspace() строка не закончена завершающим символом '\0':
Код

  ...
  newstr[i] = '\0';
}


Более того, Вы в testPalindrome отправляете q.newstr, делаете ей strrev, а затем с ней же сравниваете (ну, хотя бы аргумент иначе назовите, а то его имя совпадает с именеи одного из членов класса first). 

В принципе, зная длину строки, можно проверить её на полиндромность и без strrev (и даже не убивая пробелы), но если решение видится таким образом, то Вам нужны хотя бы 2е строки: оригинальная и перевёрнутая (то есть хранить их стоит в разных массивах).

И не мешало бы сделать проверку на переполнение ;)

И ещё. Программа таки не возвращает 0 или 1 в зависимости от результата теста)))

Это сообщение отредактировал(а) feodorv - 9.3.2012, 18:10


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
DewDrop
Дата 9.3.2012, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Зато хотя бы я попытался решить, разве это не ценится?)... 
Цитата

Более того, Вы в testPalindrome отправляете q.newstr, делаете ей strrev, а затем с ней же сравниваете (ну, хотя бы аргумент иначе назовите, а то его имя совпадает с именем одного из членов класса first). 
  По моему логично сравнивать именно так и почему я сравниваю с одним и тем же, не могли бы вы исправить это в моем коде. 
Что значит проверка на пререполнение? 
Остальное сейчас исправлю. 
Заранее спасибо! 

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


Эксперт
****


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

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



Цитата(DewDrop @  9.3.2012,  19:21 Найти цитируемый пост)
Зато хотя бы я попытался решить

Да я не в претензии, наоборот. Но вопрос так и не прозвучал smile 


Цитата(DewDrop @  9.3.2012,  19:21 Найти цитируемый пост)
почему я сравниваю с одним и тем же

Ну а как ещё можно воспринять такой код:
Цитата(DewDrop @  9.3.2012,  18:19 Найти цитируемый пост)
strcmp(newstr,strrev(newstr))

Распишите пошагово то, что он делает, тогда придёт понимание:
Цитата(feodorv @  9.3.2012,  19:00 Найти цитируемый пост)
Вам нужны хотя бы 2е строки: оригинальная и перевёрнутая (то есть хранить их стоит в разных массивах).



Цитата(DewDrop @  9.3.2012,  19:21 Найти цитируемый пост)
Что значит проверка на пререполнение? 

Ну, в самом начале main Вы бесшабашно делаете
Цитата(DewDrop @  9.3.2012,  18:19 Найти цитируемый пост)
    gets(q.str);

Если ввести более 50-ти символов, произойдёт переполнение массива q.str со всеми вытекающими последствиями... Впрочем, забейте, просто не вводите слишком длинные строки)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 9.3.2012, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Вдогонку про изничтожение пробелов...

В строку при gets ещё может попасть перевод строки (символ '\n'), от него тоже стоит избавиться:
Код

if(str[a] != ' ' && str[a] != '\n') newstr[i] = str[a];


Далее, i++ следует делать только при присваивании, а не на каждом шаге цикла:
Код

    for(int a = 0; a < strlen(str); a++)
    {
        if(str[a] != ' ' && str[a] != '\n')
        { 
            newstr[i] = str[a];
            i++;
        }
    }


или проще:
Код

    for(int a = 0; a < strlen(str); a++)
       if(str[a] != ' ' && str[a] != '\n') newstr[i++] = str[a];


Конечно, компиляторы сейчас стали умными и правильно трактующими цикл с условием a < strlen(str), но, всё же, стоит выделить вычисление длины строки из цикла:
Код

int len = strlen(str);
for(int a = 0; a < len; a++) ...


А если учесть, что строка заканчивается символом '\0', и мы всё равно просматриваем всю строку, то от strlen можно и отказаться:
Код

for( int a = 0; str[a] != '\0'; a++)
   if( str[a] != ' ' && str[a] != '\n' ) newstr[i++] = str[a];
newstr[i] = '\0';


Как-то так)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
DewDrop
Дата 9.3.2012, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо feodorv , надо взять на заметку:  вставил ваши изменения в программу и прочитал на одно сайте что можно использовать strdup и тогда программа работает, посмотрите пожалуйста, я правда не совсем понял что она делает еще=) 
Код

#include <iostream>
#include <string> 
#include <cstdio>
using namespace std;

class first { 
public:
char str[50]; 
char newstr[50];
void delspace(char str[50]);
int testPalindrome(char newstr[50]);
};
void first::delspace(char str[50])
{
    int i =0;
    for( int a = 0; str[a] != '\0'; a++)
    if( str[a] != ' ' && str[a] != '\n' ) newstr[i++] = str[a];
    newstr[i] = '\0';
}
int first::testPalindrome(char newstr[50]) 
{ 
    int result;
    result = strcmp(newstr,strrev(strdup(newstr)));
    if (result == 0) cout << "POLINOM"  << endl;
    else cout << "NE POLINOM" << endl;
    return result; 
}

int main() 
{ 
    while (true) {
    first q;
    cout << "Vvedite stroky:" << '\n' << endl;
    gets(q.str);
    q.delspace(q.str);
    q.testPalindrome(q.newstr);
    }
    return 0;
}
 

PM MAIL   Вверх
feodorv
Дата 9.3.2012, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(DewDrop @  9.3.2012,  20:17 Найти цитируемый пост)
тогда программа работает

То есть программа правильно пишет "палиндром-не палиндром"? Поздравляю!

Цитата(DewDrop @  9.3.2012,  20:17 Найти цитируемый пост)
можно использовать strdup

Использовать можно всё что угодно, важно как и когда. Например, в нашем случае мы заранее ограничили размеры строк 50-ю символами, поэтому везде можем спокойно писать:
Код
char supernovastr[50];
 в любом нам необходимом месте кода. strdup же заказывает память у системы, следовательно, когда-нибудь мы должны будем её вернуть посредством free(). А у Вас в коде мы теряем указатель на скопированную строку (вернуть память никак не удастся). Это можно было бы не пропустить, если бы не вновь введённый цикл while в main(). На каждом шаге while мы будем терять память (это так называемая утечка). Опять же, никакой необходимости в strdup (а, следовательно, в утечке памяти) нет  smile 

Более того, в классе first уже зарезервированы два массива, зачем нам новые? Один массив мы можем использовать как упакованную строку (в смысле - без пробелов), второй - как перевёрнутую упакованную. delspace переделаем в set:
Код

void first::set(const char *s)
{
    int i =0;
    for( int a = 0; s[a] != '\0' && i < 49; a++)
      if( s[a] != ' ' && s[a] != '\n' ) str[i++] = s[a];
    str[i] = '\0';
}


А в testPalindrome мы сначала скопируем нашу строку в newstr, перевернём её и сравним с str:
Код

int first::testPalindrome() 
{ 
    strcpy( newstr, str);
    strrev(newstr);
    return strcmp( str, newstr);
}


Ну а в main напечатаем результат:
Код

int main() 
{ 
    char str[50];

    while (true) 
    {
      first q;
      cout << "Vvedite stroky:" << '\n' << endl;
      gets(str);
      q.set(str);
      if (q.testPalindrome() == 0) 
         cout << "POLINOM"  << endl;
      else 
         cout << "NE POLINOM" << endl;
    }
    return 0;
}


Осталось вместо set() сделать нормальный конструктор/деструктор, вместо char[50] использовать класс string (ну не зря же в коде присутствует #include <string>), что нам даст строки переменной длины, gets заменить на что-нибудь более вменяемое в C++ и .... всё!!!)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Result
Дата 9.3.2012, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Можно еще с помощью STL'я.

Код

#include <string>
#include <algorithm>
#include <iostream>
#include <functional>

using namespace std;
//-----------------------------------------------
bool isPoli(const wstring & arg){
   wstring tmp(arg);
   tmp.erase(remove_if(tmp.begin(), tmp.end(), 
             bind2nd(equal_to<wstring::value_type>(), L' ')), tmp.end());  
   return equal(tmp.begin(), tmp.end(), tmp.rbegin());
}
//-----------------------------------------------
int main(){
   wstring str1(L"abba");
   wstring str2(L"a roza upala na lapu azora");
   wstring str3(L"some string");
   wstring str4(L"а роза упала на лапу азора");
   wstring str5(L"");
   
   if(isPoli(str1))
      cout << "OK - str1" << endl;

   if(isPoli(str2))
      cout << "OK - str2" << endl;
      
   if(!isPoli(str3))
      cout << "OK - str3" << endl;
      
   if(isPoli(str4))
      cout << "OK - str4" << endl;

   if(isPoli(str5))
      cout << "OK - str5" << endl;
}

PM   Вверх
volatile
Дата 10.3.2012, 00:24 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Моя природная жадность smile , не дала пройти мимо, ссори.
Можно сэкономить 
  • На памяти (зачем выделять память на лишнюю строку без пробелов)
  • На времени (зачем сравнивать всю строку, достаточно до середины)

Код

bool is_polindrom (const char * left)
{
   const char * right = left + strlen (left) - 1;
   while (left < right)
   {
      if (isspace (*left))
      {
         ++ left;
         continue;
      }
      if (isspace (*right))
      {
         -- right;
         continue;
      }
      if (*left++ != *right--)
      {
         return false;
      }
   }
   return true;
}


PM MAIL   Вверх
feodorv
Дата 10.3.2012, 05:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



volatile, Вы как всегда изящны и лаконичны)))

Идеальная программа для:
Цитата(feodorv @  9.3.2012,  19:00 Найти цитируемый пост)
можно проверить её на полиндромность и без strrev (и даже не убивая пробелы)


Друзья! Но ведь задача звучала:
Цитата(DewDrop @  9.3.2012,  18:19 Найти цитируемый пост)
Используя классы

Эту задачу проще решить без классов, чем с классами))) К тому же:
Цитата(DewDrop @  9.3.2012,  19:21 Найти цитируемый пост)
Зато хотя бы я попытался решить, разве это не ценится?)... 




--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
mes
Дата 10.3.2012, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(volatile @  9.3.2012,  23:24 Найти цитируемый пост)
Моя природная жадность

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

Это сообщение отредактировал(а) mes - 10.3.2012, 12:45


--------------------
PM MAIL WWW   Вверх
DewDrop
  Дата 10.3.2012, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Огромное всем спасибо!!!  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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