Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Хитрая задачка

358
26 августа 2003 года
moonmike
423 / / 18.10.2002
Есть таблица, в которой указаны:
Производитель, поставщик, срок пользования.
Надо подсчитать сколько различных комбинаций этих трех полей встречается.
Потом, соответсвенно разбить эту таблицу на подтаблицы количеством равным количеству комбинаций. То есть:
Таблица до изменений:
|Производитель|Поставщик|Срок|Номер|
|12 |1 |3 |0
|13 |1 |3 |0
|12 |1 |3 |0
|12 |1 |2 |0
|13 |2 |3 |0
|13 |1 |3 |0
|13 |1 |2 |0
Подсчет:
|Производитель|Поставщик|Срок|Номер|
|12 |1 |3 |0
2 штуки;
|Производитель|Поставщик|Срок|Номер|
|12 |1 |2 |0
1 штука;
|Производитель|Поставщик|Срок|Номер|
|13 |1 |3 |0
2 штуки;
|Производитель|Поставщик|Срок|Номер|
|13 |2 |3 |0
1 штука;
|Производитель|Поставщик|Срок|Номер|
|13 |1 |2 |0
1 штука;
Измененная таблица:
|Производитель|Поставщик|Срок|Номер|
|12 |1 |3 |1
|13 |1 |3 |3
|12 |1 |3 |1
|12 |1 |2 |2
|13 |2 |3 |4
|13 |1 |3 |3
|13 |1 |2 |5

Есть идея решить это все с помощью STL но что-то ума не приложу как. В принципе с помощью std::vector можно попытаться решить.
типа
class MySpec
{
public:
int Vendor;
int Dealer;
int Month;
};

std::vector<MySpec> vMySpec;
но потом вот вопрос как сделать так чтоб
vMySpec.push_back(MySpec);
осуществлял вставку только в том случае если класса с такими членами еще нет в векторе.
293
26 августа 2003 года
SEDEGOFF
586 / / 06.10.2002
У тебя это в БД?
Если да то
select a,b,c, count(a) from post group by a,b,c
358
26 августа 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by SEDEGOFF
У тебя это в БД?
Если да то
select a,b,c, count(a) from post group by a,b,c


Эх, еслиб все так просто было, это уже в ClientDataSet.

460
26 августа 2003 года
Berg
261 / / 27.03.2003
2moonmike:
> std::vector<MySpec> vMySpec;
> но потом вот вопрос как сделать так чтоб
> vMySpec.push_back(MySpec);
> осуществлял вставку только в том случае если
> класса с такими членами еще нет в векторе.
1)
Возможно тебе подойдет unique_copy?
//
// unique.cpp
//
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
//Initialize two vectors
int a1[20] = {4, 5, 5, 9, -1, -1, -1, 3, 7, 5,
5, 5, 6, 7, 7, 7, 4, 2, 1, 1};
vector<int> v(a1+0, a1+20), result;
//Create an insert_iterator for results
insert_iterator<vector<int> > ins(result, result.begin());
//Demonstrate includes
cout << "The vector: " << endl << " ";
copy(v.begin(),v.end(),
ostream_iterator<int,char>(cout," "));

//Find the unique elements
unique_copy(v.begin(), v.end(), ins);
//Display the results
cout << endl << endl
<< "Has the following unique elements:"
<< endl << " ";
copy(result.begin(),result.end(),
ostream_iterator<int,char>(cout," "));
return 0;
}

Program Output

The vector:
4 5 5 9 -1 -1 -1 3 7 5 5 5 6 7 7 7 4 2 1 1
Has the following unique elements:
4 5 9 -1 3 7 5 6 7 4 2 1

2) Есть еще map, который в отличии от multimap не позволяет иметь одинаковые ключи. Т.е. в качестве ключа можно иметь структуру из трех твоих полей, а в качестве value частоту...

3) ...
293
26 августа 2003 года
SEDEGOFF
586 / / 06.10.2002
Создай привив на основе запроса который ты используешь в датасет, а у привива запроси как выше говорил
А у тебя IB
358
26 августа 2003 года
moonmike
423 / / 18.10.2002
2 SEDEGOFF:
У меня MSSQL2k. Содержимое ClientDataSet формируется на клиенте. Так что кидать его на сервер, а потом обратно выдергивать запросом, при том, что пользователь еще может и не захотеть сохранять это в БД, нет никакого резона.

Так что задачка тут явно для STL только вот я с ним уж шибко давно не работал. ВОт так что и задумался.

2 Berg: Щас посмотрим что нам там std::map предложит на эту тему=)))
460
26 августа 2003 года
Berg
261 / / 27.03.2003
Цитата:
Originally posted by moonmike
2 SEDEGOFF:
2 Berg: Щас посмотрим что нам там std::map предложит на эту тему=)))



Если ничего, то вот еще:

1)
- Заполняешь вектор v значениями;
- Делаешь v.sort(), чтобы одинаковые элементы стали соседними;
- Подсчитываешь число вхождений каждогоэлемента через for_each() & count();
- Делаешь
typename типструктуры::iterator
p = unique(v.begin(), v.end());
- v.erase(p, v.end()); При этом удаляются все соседние одинаковые элементы

2) На крайняк можно самому делать find перед вставкой...

358
26 августа 2003 года
moonmike
423 / / 18.10.2002
2 Berg:
Вот с find сейчас и заморачиваюсь, проблема в том что если find не нашел ни одного такого элемента то он возвращает итератор на последний элемент вектора.=)))
Ну щас я его поборю, а так оператор сравнения дописал, получилось вот что:
class MySpec
{
private:
protected:
public:
int Vendor;
int Dealer;
int Month;
bool operator==(const MySpec&);
};
bool MySpec::operator == (const MySpec& rhs)
{
return (this->Vendor == rhs.Vendor &&
this->Dealer == rhs.Dealer &&
this->Month == rhs.Month);
}

Да кстати откуда толковый талмуд по STL желательно на русском можно утянуть?
460
26 августа 2003 года
Berg
261 / / 27.03.2003
Цитата:
Originally posted by moonmike
2 Berg:
Вот с find сейчас и заморачиваюсь, проблема в том что если find не нашел ни одного такого элемента то он возвращает итератор на последний элемент вектора.=)))

А какая тебе разница? Если не нашел делай push и все...А если нашел, то счетчик++ у элемента с вернувшимся итератором или я чего-то не догоняю?

Да кстати откуда толковый талмуд по STL желательно на русском можно утянуть?



Вот тут немного есть от Страуструпа:
http://lib.ru/CPPHB/cpptut.txt

460
26 августа 2003 года
Berg
261 / / 27.03.2003
Сорри за предыдущий пост...:-(

Цитата:
Originally posted by moonmike
2 Berg:
Вот с find сейчас и заморачиваюсь, проблема в том что если find не нашел ни одного такого элемента то он возвращает итератор на последний элемент вектора.=)))



А какая тебе разница? Если не нашел делай push и все...А если нашел, то счетчик++ у элемента с вернувшимся итератором или я чего-то не догоняю?

Цитата:
Originally posted by moonmike
Да кстати откуда толковый талмуд по STL желательно на русском можно утянуть?



Вот тут немного есть от Страуструпа:
http://lib.ru/CPPHB/cpptut.txt

Тут более подробно, но на аглицком:
http://www.cs.rpi.edu/projects/stl/htdocs/stl.html

358
26 августа 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by Berg
А какая тебе разница? Если не нашел делай push и все...А если нашел, то счетчик++ у элемента с вернувшимся итератором или я чего-то не догоняю?


Да разница в том, что если вектор не пустой, то find в любом случае вернет итератор, если нет совпадений то она вернет указатель на последний элемент вектора.
В общем решил я эту задачку=)))
Вот примерчик:

3
26 августа 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by moonmike

Да разница в том, что если вектор не пустой, то find в любом случае вернет итератор, если нет совпадений то она вернет указатель на последний элемент вектора.
В общем решил я эту задачку=)))
Вот примерчик:



Посмотрел твой пример.
Во-первых, чем не подошел std::unique ?
Во-вторых есть несколько придирок:
1. Почему бы не сделать так (File.h):

Код:
#ifndef My_StructH
#define My_StructH

class MySpec
{
public:
  int Vendor;
  int Dealer;
  int Month;
 
  bool operator==(const MySpec& rhs)
  {
    return (this->Vendor == rhs.Vendor &&
            this->Dealer == rhs.Dealer &&
            this->Month == rhs.Month);
  }

  bool operator!=(const MySpec& rhs)
  {
    return !(this==rhs);
  }
};

#endif


2. Не только ненужное сравнение, но и опасный код:
(*vMySpec.end() != tmp)
Посмотри, что возвращает end()

3. Условие в Unit1.cpp можно записать проще и нагляднее:
 
Код:
iterator it1 = std::find(vMySpec.begin(),vMySpec.end(), tmp);
if(it1 == vMySpec.end())
{
        AnsiString S = "Vendor: " + IntToStr(tmp.Vendor) + \
            ", Dealer: " + IntToStr(tmp.Dealer) + \
            ", Month: " + IntToStr(tmp.Month);
        Memo1->Lines->Add(S);
        vMySpec.push_back(tmp);
}
358
27 августа 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by Green


Посмотрел твой пример.
Во-первых, чем не подошел std::unique ?


Дык чтобы знать где искать, надо знать что искать. Ну не знал я об этом std::unique, а доки никакой нету=(. Щас вот заказал Effective STL by Scott Meyers.

Цитата:
Originally posted by Green

Во-вторых есть несколько придирок:
1. Почему бы не сделать так (File.h):
Код:
#ifndef My_StructH
#define My_StructH

class MySpec
{
public:
  int Vendor;
  int Dealer;
  int Month;
 
  bool operator==(const MySpec& rhs)
  {
    return (this->Vendor == rhs.Vendor &&
            this->Dealer == rhs.Dealer &&
            this->Month == rhs.Month);
  }

  bool operator!=(const MySpec& rhs)
  {
    return !(this==rhs);
  }
};
#endif


Так пытался, но чегой-то он у меня ругнулся на подобное написание.

Цитата:
Originally posted by Green


2. Не только ненужное сравнение, но и опасный код:
(*vMySpec.end() != tmp)
Посмотри, что возвращает end()


А чего там не так с end()? Я просто думаю что означает загадочная фраза в хелпе "past-the-end"

Цитата:
Originally posted by Green

3. Условие в Unit1.cpp можно записать проще и нагляднее:
 
Код:
iterator it1 = std::find(vMySpec.begin(),vMySpec.end(), tmp);
if(it1 == vMySpec.end())
{
        AnsiString S = "Vendor: " + IntToStr(tmp.Vendor) + \
            ", Dealer: " + IntToStr(tmp.Dealer) + \
            ", Month: " + IntToStr(tmp.Month);
        Memo1->Lines->Add(S);
        vMySpec.push_back(tmp);
}


А вот это действительно, условие в рабочей программе именно в такое и превратилось, просто изначально стояла задача заставить прогу работать, а потом уже оптимизировать.

3
27 августа 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by moonmike

А чего там не так с end()? Я просто думаю что означает загадочная фраза в хелпе "past-the-end"



end() возвращает итератор указывающий за последний элемент вектора, т.е. за пределы самого вектора. Т.о. получается, что он указвает в никуда (в контексте данного вектора), т.е. сам указатель невалиден и его разыменовавание опасно.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог