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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Расширенный поиск в структуре стрингов, помогите понять как сделать 
:(
    Опции темы
plastiv
Дата 7.6.2007, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Помогите разобраться как организовывается поиск в структуре стрингов. Когда я провожу не точную проверку на наличие таких символов, а смогу вводить часть фамилии (оценки или группы)и по этому запросу выводить всю строчку структуры. Попутно возник вопрос: как сортировать стринги по возрастанию, алфавиту? 

Код

typedef struct student {
    string name; 
    string group;
    string mark;
}
stud;

PM MAIL   Вверх
zkv
Дата 7.6.2007, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



plastiv, самый важный вопрос, что можно использовать? 
Если юзать STL, то задача решается быстро и просто. Если изобретать велосипеды, то... подольше будет... smile  
PM MAIL   Вверх
plastiv
Дата 7.6.2007, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да, STL нужно

Это сообщение отредактировал(а) plastiv - 7.6.2007, 22:38
PM MAIL   Вверх
zkv
Дата 8.6.2007, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



для примера:
Код

#include <iostream>
#include <list>
#include <string>
#include <algorithm>

struct STUDENT
{
    std::string name; 
    std::string group;
    std::string mark;
}    g_SampleInit[] = 
    {
        { "Petrov",  "2121", "ud"    },
        { "Ivanov",  "1212", "neud"    },
        { "Sidorova", "3211","ud" },
        { "sidorova", "3211","ud" },
        { "Sidorov", "3211", "neud" }
    };

int g_iSampleSize = sizeof( g_SampleInit ) / sizeof( g_SampleInit[0] ); 

void PrintStudent( const STUDENT &stud );
bool LessName( const STUDENT &stud1, const STUDENT &stud2 );

class PrintIfNameContain //просто декларация class PrintIfNameContain; что-то не катит :(
{
private:
    std::string m_str;
public:
    PrintIfNameContain( const std::string &str ) 
        : m_str( str )
   {
   }

   void operator ( ) ( const STUDENT &stud ) 
   {
       if( std::string::npos != stud.name.find( m_str ) )
           PrintStudent( stud );
   }
};

int main(int argc, char* argv[])
{
    std::list< STUDENT > listStud( &g_SampleInit[0], &g_SampleInit[g_iSampleSize] );
    std::cout<<"Initial list:\n";
    std::for_each( listStud.begin(), listStud.end(), PrintStudent );

    listStud.sort( LessName );
    std::cout<<"\nSorted list:\n";
    std::for_each( listStud.begin(), listStud.end(), PrintStudent );
    
    std::cout<<"\nPrint all, with \"dor\" in name:\n";
    std::for_each( listStud.begin(), listStud.end(), PrintIfNameContain( "dor" ) );

    std::cin.get();
    return 0;
}

bool LessName( const STUDENT &stud1, const STUDENT &stud2 )
{
    return std::lexicographical_compare( &stud1.name[0], &stud1.name[stud1.name.length()],
                                         &stud2.name[0], &stud2.name[stud2.name.length()] );
}

void PrintStudent( const STUDENT &stud )
{
    std::cout<<stud.name<<"     "<<stud.group<<"     "<<stud.mark<<'\n';
}


Это сообщение отредактировал(а) zkv - 8.6.2007, 00:28
PM MAIL   Вверх
Xenon
Дата 8.6.2007, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Черт, не успел я глянуть, а zkv уже сделал smile
Ну выложу то, что накропал:
Код

template <typename PRED, typename InIter, typename OutIter> void copy_if(InIter FIRST, InIter LAST, OutIter OUT, PRED Cond)
{
    for ( ; FIRST != LAST; ++FIRST)
        if ( Cond(*FIRST) ) OUT = *FIRST;
}

struct STUDENT
{
    std::string m_name; 
    std::string m_group;
    std::string m_mark;
    STUDENT(const std::string& name, const std::string& group, const std::string& mark): m_name(name), m_group(group), m_mark(mark) {}
};

std::ostream& operator << (std::ostream& stream, const STUDENT& obj)
{
    stream << obj.m_name << ' ' << obj.m_group << ' ' << obj.m_mark;
    return stream;
}

std::ostream& operator << (std::ostream& stream, STUDENT* obj)
{
    stream << obj->m_name << ' ' << obj->m_group << ' ' << obj->m_mark;
    return stream;
}

class almost_equal
{
private:
    std::string m_str;
public:
    bool operator()(const STUDENT& obj) 
    {
        return (obj.m_name.find(m_str) !=  std::string::npos);
    }
    bool operator()(STUDENT* obj) 
    {
        return (obj->m_name.find(m_str) !=  std::string::npos);
    }
    almost_equal(const std::string& str):m_str(str) {}
};

int main(int argc, char* argv[]) 
{
    typedef std::vector<STUDENT*> StudArr;
    StudArr stud_base;
    stud_base.push_back( new STUDENT("Anatoly Vetrov", "10", "shit") );
    stud_base.push_back( new STUDENT("Viktor Petrovich", "10", "good") );
    copy_if( stud_base.begin(), stud_base.end(), std::ostream_iterator<STUDENT*>(std::cout, "\n"), almost_equal("Vetr") );
    for (StudArr::iterator iter = stud_base.begin(); iter != stud_base.end(); ++iter) delete *iter;
    std::cin.sync();
    std::cin.get();
    return 0;
}


Это сообщение отредактировал(а) Xenon - 18.1.2012, 19:33


--------------------
user posted image  
PM MAIL   Вверх
zkv
Дата 8.6.2007, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Зато теперь у plastiv'а будет пища для размышлений  smile  
PM MAIL   Вверх
plastiv
Дата 8.6.2007, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо! Сейчас буду разбираться.

zkv, зачем нужно лексографическое сравнение массивов?

Это сообщение отредактировал(а) plastiv - 8.6.2007, 18:17
PM MAIL   Вверх
zkv
Дата 8.6.2007, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(plastiv @  8.6.2007,  17:38 Найти цитируемый пост)
зачем нужно лексографическое сравнение массивов?

а поиск отменили уже? тут например все написано, добавить нечего

PM MAIL   Вверх
korbian
Дата 9.6.2007, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



К слову, недавно использовал boost::multi_index для схожих целей, вообщем остался доволен.


--------------------
korbian ©
PM   Вверх
plastiv
Дата 9.6.2007, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



В общем-то написал код программки, посмотрите , пожалуйста, на наличие явных ляпов

Код

#include <string>           //строки
#include <iostream>            //потоки входа\выхода
#include <fstream>            //файловые потоки
#include <stdio.h>            //структура
#include <list>                //список
#include <algorithm>

using std::cout;
using std::cin;
using std::string;
using std::list;
using std::lexicographical_compare;
using std::ifstream;
using std::ofstream;
using std::ios;
using std::binary_function;
using std::input_iterator_tag;
using std::endl;

 
typedef struct student {
    string name; 
    string group;
    string mark;
}
mass;
    

//обьвление перменных
const int size = 2;
mass s[size];
mass *ss=&s[0];
int massSize = sizeof ( s ) / sizeof ( s [0] ); 


int open (); //открытие файла
void PrintStudent( const student &stud ); //вывод всего содержимого на экран
int menu (); //ф-ция экранного меню
void savexit (); //сохранение всех изменений в файл, завершение работы
void find();
void input (); //ф-ция ввода
int sort (); //ф-ция сортировки данных по алфавиту
bool LessName ( const student &stud1, const student &stud2 ); //лексографическое сравнение
void PrintFile (); //печать на экран

class PrintIfNameContain 
{
private:
    string m_str;
public:
    PrintIfNameContain( const string &str ) 
        : m_str( str )
   {
   }

   void operator ( ) ( const student &stud ) 
   {
       if( string::npos != stud.name.find( m_str ) )
           PrintStudent( stud );
   }
};





//основная main
int main()
{
   for ( ; ; ) //Бесконечный цикл выбора функций
    { 
        switch ( menu () ) 
        {
            case 1:  open ();  break; 
            case 2:  PrintFile ()  ;  break; 
            case 3:  input ();  break;
            case 4:  sort ();  break; 
            case 5:  find (); break;
            case 0:  savexit();  break; 
            default: exit(0);
        }
    }    


    return 0;
}

int open ()
{
    system ("cls");
    ifstream in ("student.txt", ios::in | ios::binary); // открываем файл для чтения
    //проверка на открытие файла
    if (!in)
        {
        cout << "Error 1: can't open student.txt \n";
        return 1;
        }

    for(int i=0; i < size; i++)
    {    
        in >> s[i].name;
        in >> s[i].group;
        in >> s[i].mark;
         }
   in.close(); // закрываем файл

   cout << "File is open \n" << endl;
   system ("pause");
   return 0;
}
int menu()
{
    int choice;
    system("cls");
 
    cout << "Choose current item: \n";
   
    cout << "================================== \n"; 
    cout << "1. Read information from file student.txt \n";
    cout << "2. Print information from file student.txt on screen \n";
    cout << "3. Input new information to file student.txt \n";
    cout << "4. Sort struct by nameSearch in file student.txt\n";
    cout << "5. Search in file student.txt \n";
    cout << "0. Save & exit \n\n";
    cout << "> ";
    cin >> choice;
    cout << endl;
    return choice;
}

void savexit ()
{
    ofstream fileout("student.txt", ios::out | ios::binary);
    for(int i=0; i< size; i++)             
        fileout << s[i].name << " \t\t" << s[i].group << " \t " << s[i].mark  << endl;
    fileout.close();
    system("cls");        
    exit(0);


void input ()
{
    ofstream infile ("student.txt", ios::out | ios::binary); // открываем файл для записи
    
    for ( int i = 0; i < size; i ++, ss++)
    {
        cout << "\n Input name\n";
        cin >> ss -> name;
        cout << " Input group\n";
        cin >> ss -> group;
        cout << "Input mark\n";
        cin >> ss -> mark;
        infile.write ( (char*) &s [i], sizeof s [i]); //вывод в файл
    }

    infile.close ();

}

void PrintStudent( const student &stud )
{
    cout << stud.name << "     " << stud.group << "     " << stud.mark << '\n';

}

bool LessName( const student &stud1, const student &stud2 )
{
    return lexicographical_compare( &stud1.name[0], &stud1.name[stud1.name.length()],
                                         &stud2.name[0], &stud2.name[stud2.name.length()] );
}

int sort ()
{
    system ("cls");
    list < student > listStud ( &s[0], &s[massSize] );
    cout<<"Initial list:\n";
    for_each( listStud.begin(), listStud.end(), PrintStudent );

    listStud.sort( LessName );
    cout<<"\nSorted list:\n";
    for_each( listStud.begin(), listStud.end(), PrintStudent );
    
   
    system ("pause");
    return 0;
 
}

void find ()
{
    system ("cls");
    list < student > listStud ( &s[0], &s[massSize] );
    string tmp;
    cout << "Input search text \n";
    cin >> tmp;
    cout<<"\nPrint all, with " << tmp << " in name:\n";
    for_each( listStud.begin(), listStud.end(), PrintIfNameContain( tmp ) );
    system ("pause");
}

void PrintFile ()
{
    system ("cls");
    list < student > listStud ( &s[0], &s[massSize] );
    for_each( listStud.begin(), listStud.end(), PrintStudent );
    system ("pause");
}


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


Эксперт
***


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

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



plastiv, глобальные переменные - не есть хорошо. Объедини схожие по смыслы функции в пространство имен и в бесконечном цикле анализа возвращаемого значения функции menu() вместо exit(0) пиши return 0; так как exit(0) - это грубый выход smile В даном случае разницы особой вроде нет, но если ты бы в main создавал какие-либо объекты в стеке они бы не уничтожались.


--------------------
user posted image  
PM MAIL   Вверх
DigitSphinx
Дата 9.6.2007, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

using std::cout;
using std::cin;
using std::string;
using std::list;
using std::lexicographical_compare;
using std::ifstream;
using std::ofstream;
using std::ios;
using std::binary_function;
using std::input_iterator_tag;
using std::endl;

просто 
Код

using namespace std;

 smile 


--------------------
Чтобы пробить стену лбом нужен или большой разбег, или много лбов.
(Альберт Эйнштейн)
Умен ты или глуп, велик ты или мал, не знаем мы, пока ты слова не сказал.
(Альберт Эйнштейн)
user posted image
PM MAIL ICQ   Вверх
zkv
Дата 9.6.2007, 22:59 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(DigitSphinx @  9.6.2007,  22:20 Найти цитируемый пост)
просто

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

Это сообщение отредактировал(а) zkv - 9.6.2007, 23:06
PM MAIL   Вверх
Xenon
Дата 9.6.2007, 23:20 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



DigitSphinx, в CPP файлах вообще не рекомендуется using директивы использовать, а почему zkv уже сказал

Это сообщение отредактировал(а) Xenon - 9.6.2007, 23:28


--------------------
user posted image  
PM MAIL   Вверх
plastiv
Дата 11.6.2007, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Если сделать динамическую структуру, то при вводе значений надо поставить символ, отвечающий за завершение набора - подскажите как правильно его описать?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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