Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++] Функции и Строки, сравнение без учета пробелов


Автор: Hqw33 25.3.2012, 16:55
Пишу в Microsoft Visual Studio ->Win32 Console application ->C++.
Помогите пожалуйста Разработать функцию, которая сравнивает две строки, игнорируя количество пробелов между словами.

Автор: ColdSpirit 25.3.2012, 19:16
Hqw33, всмысле? Сравнивает, игнорируя пробелы или сравнивает количество букв, игнорируя кол-во пробелов? Напиши поточнее, что требуется от программы, желательно с примерами  smile  - тогда написать ее не то, что другим, даже тебе будет легче =)

Автор: alexvs11 25.3.2012, 20:07
Код

#include <iostream>

template <typename InputIterator1, typename InputIterator2>
bool f (InputIterator1 i, InputIterator1 i_end, InputIterator2 j, InputIterator2 j_end)
{
   for ( ; i != i_end && j != j_end ; ++i, ++j )
   {
       while (*i == ' ' && i != i_end) ++i; 
       while (*j == ' ' && j != j_end) ++j;
       if (*i != *j) return false; 
   }

   return i == i_end && j == j_end;
}

int main()
{
  std::string s1 = "hellow orld", s2 = "he  lloworld";
  std::cout << f (s1.begin(), s1.end(), s2.begin(), s2.end());
}

Автор: Riviero 28.3.2012, 17:26
Если использовать AnisString, то просто Trim (). Или в консольном этого нет...

Автор: baldina 28.3.2012, 17:51
Trim() убирает пробелы слева и справа, но не в середине.
CString можно использовать в консольном (atlstr.h)

а кому не понравился пример alexvs11? можно короче через stringstream, но врядли быстрее

Автор: mes 28.3.2012, 19:27
Цитата(baldina @  28.3.2012,  16:51 Найти цитируемый пост)
 кому не понравился пример alexvs11

только тут надо уточнить у тс.. без учета всех пробелов,  или только без белых ?
хотя это выразится всего лишь в поправке внуренних пока-циклов..

Добавлено через 3 минуты и 20 секунд
но.. если развивать мысль alexvs11, то следующим шагом желательно вынести циклы пропускания пробелов в сам итератор.. тогда можно будет применять стандартные алгоритмы.. 
smile

Автор: volatile 29.3.2012, 00:28
Цитата(baldina @  28.3.2012,  17:51 Найти цитируемый пост)
а кому не понравился пример alexvs11? 

Мне не понравился!

По 2-ум причинам (хотя и одной было бы достаточно smile ).
1. Обращается за пределы контейнера.  (обращение к  *end () недопустимо!)
2. Не делает то что надо. http://liveworkspace.org/code/afb78e70f3bad917c38165d74e09a978

Автор: baldina 29.3.2012, 10:21
Цитата(mes @  28.3.2012,  19:27 Найти цитируемый пост)
вынести циклы пропускания пробелов в сам итератор

это и будет что-то типа чтения из stringstream smile

Добавлено через 5 минут и 28 секунд
Цитата(volatile @  29.3.2012,  00:28 Найти цитируемый пост)
обращение к  *end () недопустимо

да, я не обратил внимание...

Цитата(volatile @  29.3.2012,  00:28 Найти цитируемый пост)
Не делает то что надо

http://liveworkspace.org/code/4da8a37d06529f878c58dad201a3be6e

Автор: alexvs11 29.3.2012, 15:47
volatile, так исправил бы smile 
вроде так правильно
Код

#include <iostream>
#include <functional>
#include <cstdio>
#include <cctype>

template <typename InputIterator1, typename InputIterator2, typename equal, typename skip>
bool f (InputIterator1 i, InputIterator1 i_end, InputIterator2 j, InputIterator2 j_end, equal f_e, skip f_s) 
{
   for ( ; i != i_end || j != j_end; ) 
   {
      while (i != i_end && f_s(*i)) ++i;
      while (j != j_end && f_s(*j)) ++j;
 
      if (i == i_end ^ j == j_end) return false;
      if (i != i_end && j != j_end && !f_e(*i, *j)) return false;
      if (i != i_end) ++i;
      if (j != j_end) ++j;
   }   

   return true; 
}

int main()
{
  std::string s1 = "h ellow    ", s2 = "hellow";
  std::cout << f (s1.begin(), s1.end(), s2.begin(), s2.end(), std::equal_to<char>(), isspace) <<std::endl;
}



Автор: mes 29.3.2012, 15:55
Цитата(alexvs11 @  29.3.2012,  14:47 Найти цитируемый пост)
 ^

тут не || хотелось ?

Добавлено через 47 секунд
Цитата(alexvs11 @  29.3.2012,  14:47 Найти цитируемый пост)
equal f_e, skip f_s

не очень красиво.. 

Автор: alexvs11 29.3.2012, 16:14
Цитата(mes @  29.3.2012,  15:55 Найти цитируемый пост)
тут не || хотелось ?

не, именно xor подразумевался

Цитата(mes @  29.3.2012,  15:55 Найти цитируемый пост)
не очень красиво.. 

как-то не пришло в голову как красивей сделать

Автор: mes 29.3.2012, 16:18
alexvs11, отделить логику итерации от логики сравнения..


Цитата(alexvs11 @  29.3.2012,  15:14 Найти цитируемый пост)
не, именно xor подразумевался

получается, что нужно вернуть ложь и в случае если оба не достигли конца..   smile 

Автор: mes 29.3.2012, 16:37
Цитата(baldina @  29.3.2012,  09:21 Найти цитируемый пост)
это и будет что-то типа чтения из stringstream 

угу.. 

вот на скорую руку в первом приближении :
Код

struct view_stream 
{
    view_stream (const char * begin, const char * end, bool(*skip)(char) )
        : _begin (begin) , _end(end), _skip (skip)
    {
    }
 
    char get () { char c = *_begin; next(); return c; }

    void next () { do { ++_begin; } while (!eof() && _skip(*_begin)); }


    bool eof () { return !( _begin<_end); }

  private:
    const char *   _begin,  * _end;
    bool (*_skip)(char);
};

bool compare (view_stream s1, view_stream s2)
{
   for (;! (s1.eof() && s2.eof()); )
   {
       if (s1.get() != s2.get()) return false;
   }
 
    return s1.eof() && s2.eof();
}
bool isspace (char c)
{
    return std::isspace (c);
}

int main ()
{
  const char s1[] = "hello   world !";
  const char s2[] = "hello world   !  ";

  std::cout << compare(view_stream(s1, s1+sizeof(s1), isspace) , 
                       view_stream(s2, s2+sizeof(s2), isspace));


}

Автор: bsa 29.3.2012, 23:45
Для домашних заданий, курсовых, существует "Центр Помощи".

Тема перенесена! 

Автор: alexvs11 29.3.2012, 23:52
Цитата(mes @  29.3.2012,  16:18 Найти цитируемый пост)
получается, что нужно вернуть ложь и в случае если оба не достигли конца..

нет, вернуть ложь только если один достиг конца, а другой нет
если оба достигли или не достигли продолжаем
Цитата(mes @  29.3.2012,  16:18 Найти цитируемый пост)
alexvs11, отделить логику итерации от логики сравнения..

мне видится, что разделять есть смысл только если мы предоставляем клиентам интерфейс интерации или интерфейс сравнения
в вашем примере все равно  view_stream  не совместим с алгоритмами stl

Автор: alexvs11 30.3.2012, 01:31
впрочем

Код

#include <iostream>
#include <functional>
#include <cctype>
#include <algorithm>
#include <iterator>

template <typename InputIterator>
class IteratorWithSkip : public std::iterator<std::forward_iterator_tag, typename InputIterator::value_type>
{
public:
    typedef typename InputIterator::value_type value_type;
    typedef bool (*skip_function)(value_type);
    
    explicit IteratorWithSkip(InputIterator begin, InputIterator end, skip_function f) 
        : m_final(false),  m_it(begin), m_end(end), m_f(f) {}
        
    IteratorWithSkip() : m_final(true) {}
    
    IteratorWithSkip(const IteratorWithSkip& it) : m_it(it.m_it), m_end(it.m_end), m_final(it.m_final), m_f(it.m_f) {
        skip();
    }
    
    IteratorWithSkip& operator=(const IteratorWithSkip& it) {
        if (this != &it) {
            m_it = it.m_it;
            m_end = it.m_end;
            m_final = it.m_final;
            m_f = it.m_f;
        }
        return *this;
    }
    
    IteratorWithSkip operator++(int) { 
        IteratorWithSkip tmp(m_it, m_end, m_f);
        ++(*this);
        return tmp;
    }
    
    IteratorWithSkip& operator++(){
        if (m_it != m_end) ++m_it;
        skip();
        return *this;
    }
    
    bool operator==(const IteratorWithSkip& it) const {
        return (it.m_final && m_it == m_end);
    }
    
    bool operator!=(const IteratorWithSkip& it) const {
        return ! (*this == it);
    }
    
    value_type operator*() {
        return *m_it;
    }
private:
    void skip() {
        while (m_it != m_end && m_f(*m_it)) ++m_it;
    }
    bool m_final;
    InputIterator m_it, m_end;
    skip_function m_f;
};

bool is_space (char s)
{
    return isspace(s);
}

int main()
{
    std::string s1 = "hello world", s2 = " hellow o r l d   ";
    typedef IteratorWithSkip<std::string::iterator> SkipIterator;
    SkipIterator i1(s1.begin(), s1.end(), is_space), i1_end, i2(s2.begin(), s2.end(), is_space), i2_end;
    // std::copy (i1, i1_end, std::ostream_iterator<char>(std::cout)); std::cout << std::endl;
    // std::copy (i2, i2_end, std::ostream_iterator<char>(std::cout)); std::cout << std::endl;
    std::cout << std::boolalpha << std::equal (i1, i1_end, i2) << std::endl;
}


http://ideone.com/cMCTY

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)