... в С++ ~ Множество в Pascal!

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Аватара пользователя
Monopo
Сообщения: 119
Зарегистрирован: 06 дек 2007, 20:08
Откуда: Linux

... в С++ ~ Множество в Pascal!

Сообщение Monopo » 06 дек 2007, 21:08

Скажите, есть ли в С множественный тип данных? Хотелось бы применить его к задаче: каких двубуквенных сочетаний в строке больше (согл+согл) / (глас+глас) / (согл+глас). Если в С аналогов нет, то подскажите, чем можно заменить множество {в данном случае, согласных и гласных букв}?
Юный Падаван

BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

Re: ... в С++ ~ Множество в Pascal!

Сообщение BBB » 07 дек 2007, 10:12

Стандартного типа данных нет.
В свое время когда-то "для тренировки" я писал в C++ класс - аналог паскалевского множества.

Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Re: ... в С++ ~ Множество в Pascal!

Сообщение Romeo » 07 дек 2007, 12:58

Можно написать свой простенький набор функций для работы с множествами, используя битовые операции.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

Аватара пользователя
Monopo
Сообщения: 119
Зарегистрирован: 06 дек 2007, 20:08
Откуда: Linux

Re: ... в С++ ~ Множество в Pascal!

Сообщение Monopo » 07 дек 2007, 18:33

&quot писал(а):Можно написать свой простенький набор функций для работы с множествами, используя битовые операции.
Ну.. Эээ.. Бывалому то легко говорить)
Юный Падаван

BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

Re: ... в С++ ~ Множество в Pascal!

Сообщение BBB » 10 дек 2007, 09:46

У меня это выглядело примерно так:

PAS_SET.H:

Код: Выделить всё

#ifndef __BBB__PAS_SET_H
#define __BBB__PAS_SET_H


typedef unsigned char       byte;
typedef unsigned char       tChar;
typedef signed char         tSChar;

          /* Указатели на "стандартные" типы:  */
typedef tChar         far *   tPtrChar;
typedef tSChar        far *   tPtrSChar;


#define BITS_PER_BYTE  8     /*  кол-во бит в байте */
#if defined (IN)
 #undef IN
#endif
#define IN             <     /*  операция принадлежности элемента к мн-ву */

    class SetPas {
     protected:
       byte abSet [256/BITS_PER_BYTE];
     public:
       SetPas();                         /* constructor */
       SetPas(const SetPas& sSource);    /* constructor */
       SetPas(tPtrChar acSource);    /* constructor */
       SetPas(tPtrSChar acSource);   /* constructor */
       byte Power();
        /* возвращает мощность множества */
     /*--------------------------------------------------------*/

     //-- FRIENDS:
      // операция '+' реализует объединение множеств
       friend SetPas
                     operator + (const SetPas& sSet, byte bItem);
       friend SetPas
                     operator + (const SetPas& sSet1,
                                 const SetPas&  sSet2);

      // операция '-' реализует разность множеств
       friend SetPas
                     operator - (const SetPas& sSet, byte bItem);
       friend SetPas
                     operator - (const SetPas& sSet1,
                                 const SetPas&  sSet2);

      // операция '*' реализует пересечение множеств
       friend SetPas
                     operator * (const SetPas& sSet1,
                                 const SetPas&  sSet2);

       friend boolean
                       operator == (const SetPas& sSet1,
                                    const SetPas& sSet2);
       friend boolean
                       operator != (const SetPas& sSet1,
                                    const SetPas& sSet2);

      // операции <= и >= реализуют вхождение "меньшего"
      // множества в "большее"
       friend boolean
                       operator <= (const SetPas& sSet1,
                                    const SetPas& sSet2);
       friend boolean
                       operator >= (const SetPas& sSet1,
                                    const SetPas& sSet2);
      //  операция IN (<) реализует принадлежность элемента к мн-ву
       friend boolean
                       operator IN (const byte bItem,
                                    const SetPas& sSet);

      // создание диапазона элементов множества
       friend SetPas
                      Range  (const byte bLowItem,
                              const byte bHighItem);

     /*--------------------------------------------------------*/
      };  /* of class "SetPas" */

typedef SetPas tByteSet;
typedef SetPas tCharSet;

 /*---------------------------------------------------------------*/
 /*     ╔═══════════════════════════════════════════════════╗     */
 /*     ║              Сопутствующие функции                ║██   */
 /*     ╚═══════════════════════════════════════════════════╝██   */
 /*       █████████████████████████████████████████████████████   */
 /*---------------------------------------------------------------*/

extern const tByteSet sZERO;     /* пустое множество */
extern const tByteSet& scZERO;   /* пустое множество, alias */
extern const tByteSet& sbZERO;   /* пустое множество, alias */

#endif

BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

Re: ... в С++ ~ Множество в Pascal!

Сообщение BBB » 10 дек 2007, 09:47

PAS_SET.CPP (часть 1)

Код: Выделить всё

/*************************************************************************/
/*       Эмуляция паскалевских множеств Set of byte/tChar для C++        */
/*************************************************************************/

/*************************************************************************/
/*                           Interface                                   */
/*************************************************************************/

#include <MEM.H>
#include <STRING.H>

#include "Pas_Set.H"


#define div     /
#define mod     %

#define FillChar(dest,size,symb) \
            (  memset( &(dest), (symb), (size) )  )


 //--------------------------------------------


const tByteSet  sZERO;            /* "пустое" множество, т.е. sZERO==[] */
const tByteSet& scZERO = sZERO;   /* "пустое" множество, alias */
const tByteSet& sbZERO = sZERO;   /* "пустое" множество, alias */

SetPas::SetPas()         /* constructor */
{
  FillChar(abSet, sizeof(abSet), 0 );       /* обнулили */
};  /* of "SetPas::SetPas()" */

SetPas::SetPas (const SetPas& sSource)   /* constructor */
{
  *this=sSource;
};  /*  of "SetPas::SetPas(const SetPas& sSource) */

SetPas::SetPas(tPtrChar acSource)    /* constructor */
{
 word wLen;
 //---------------------------------
  FillChar(abSet, sizeof(abSet), 0 );       /* обнулили */
  for (wLen=0; wLen<strlen((char*)acSource); wLen++)
    {
      *this = *this+acSource[wLen];
    };
};  /* of "SetPas::SetPas(tPtrChar acSource)" */

SetPas::SetPas(tPtrSChar acSource)   /* constructor */
{
 word wLen;
 //---------------------------------
  FillChar(abSet, sizeof(abSet), 0 );       /* обнулили */
  for (wLen=0; wLen<strlen((char*)acSource); wLen++)
    {
      *this = *this+acSource[wLen];
    };
};  /* of "SetPas::SetPas(tPtrSChar acSource)" */

byte SetPas::Power()
  /* возвращает мощность множества */
{
 byte bPower = 0;
 byte bOutLoop, bInLoop, bCurrByte;
 //------------------
  for (bOutLoop=0; bOutLoop<sizeof(abSet); bOutLoop++)
    {
      bCurrByte=abSet[bOutLoop];
      for (bInLoop=0; bInLoop<BITS_PER_BYTE; bInLoop++)
        {
          bPower+=(bCurrByte & 1);
          bCurrByte>>=1;
        };  /* of "for (bInLoop=0; bInLoop<sizeof(abSet); bInLoop++)" */
    };  /* of "for (bOutLoop=0; bOutLoop<sizeof(abSet); bOutLoop++)" */
  return (bPower);
};  /* SetPas::Power() */


   /* FRI}S of class "StringPas": */

SetPas  operator + (const SetPas& sSet, byte bItem)
  /* операция '+' реализует объединение множеств */
{
 byte    bByte, bBit;   /* номера смещения(байта) и бита в множестве */
 SetPas  sTmp;
 //----------------
  sTmp=sSet;
  bByte=bItem div BITS_PER_BYTE;
  bBit =bItem mod BITS_PER_BYTE;
 /* устанавливаем соответствующий бит */
  sTmp.abSet[bByte]=(sTmp.abSet[bByte] | (1<<bBit) );
 /* возвращаем результат */
  return (sTmp);
};   /* of " + (const SetPas& sSet, byte bItem)" */

SetPas  operator + (const SetPas& sSet1, const SetPas& sSet2)
  /* операция '+' реализует объединение множеств */
{
 word    w;
 SetPas  sTmp;
 //----------------
 /* идем по байтам множества */
  for (w=0; w<sizeof(sTmp.abSet); w++)
    {
     /* устанавливаем соответствующий байт */
      sTmp.abSet[w]=(sSet1.abSet[w] | sSet2.abSet[w] );
    };  /* for */
 /* возвращаем результат */
  return (sTmp);
};   /* of " + (const SetPas& sSet1, const SetPas& sSet2)" */

SetPas  operator - (const SetPas& sSet, byte bItem)
      /* операция '-' реализует разность множеств */
{
 byte bByte, bBit;     /* номера смещения(байта) и бита в множестве */
 SetPas  sTmp;
 //----------------
  sTmp=sSet;
  bByte=bItem div BITS_PER_BYTE;
  bBit =bItem mod BITS_PER_BYTE;
 /* сбрасываем соответствующий бит */
  sTmp.abSet[bByte]=(sTmp.abSet[bByte] & (~(1<<bBit)) );
 /* возвращаем результат */
  return (sTmp);
};   /* of " - (const SetPas& sSet, byte bItem)" */

SetPas  operator - (const SetPas& sSet1, const SetPas& sSet2)
  /* операция '-' реализует разность множеств */
{
 word    w;
 SetPas  sTmp;
 //----------------
 /* идем по байтам множества */
  for (w=0; w<sizeof(sTmp.abSet); w++)
    {
     /* устанавливаем соответствующий байт нужным образом */
      sTmp.abSet[w]=(sSet1.abSet[w] & (~(sSet2.abSet[w])) );
    };  /* for */
 /* возвращаем результат */
  return (sTmp);
};   /* of " - (const SetPas& sSet1, const SetPas& sSet2)" */

SetPas  operator * (const SetPas& sSet1, const SetPas& sSet2)
  /* операция '*' реализует пересечение множеств */
{
 word    w;
 SetPas  sTmp;
 //----------------
 /* идем по байтам множества */
  for (w=0; w<sizeof(sTmp.abSet); w++)
    {
     /* устанавливаем соответствующий байт нужным образом */
      sTmp.abSet[w]=(sSet1.abSet[w] & sSet2.abSet[w] );
    };  /* for */
 /* возвращаем результат */
  return (sTmp);
};   /* of " * (const SetPas& sSet1, const SetPas& sSet2)" */

BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

Re: ... в С++ ~ Множество в Pascal!

Сообщение BBB » 10 дек 2007, 09:48

PAS_SET.CPP (часть 2, окончание)

Код: Выделить всё

boolean  operator == (const SetPas& sSet1, const SetPas& sSet2)
{
  word w;
 //------------
 /* Делаем побайтное сравнение */
  for (w=0; w<sizeof(sSet1.abSet); w++)
    {
      if (sSet1.abSet[w] != sSet2.abSet[w])  return (FALSE);
    };  /* for */
 /* Здесь, если множества равны */
  return (TRUE);
};     /* of "== (const SetPas& sSet1, const SetPas& sSet2)" */

boolean  operator != (const SetPas& sSet1, const SetPas& sSet2)
{
  word w;
 //------------
 /* Делаем побайтное сравнение */
  for (w=0; w<sizeof(sSet1.abSet); w++)
    {
      if (sSet1.abSet[w] == sSet2.abSet[w])  return (FALSE);
    };  /* for */
 /* Здесь, если множества НЕ равны */
  return (TRUE);
};     /* of "!= (const SetPas& sSet1, const SetPas& sSet2)" */

      /* операции <= и >= реализуют вхождение "меньшего" */
      /* множества в "большее" */

boolean  operator <= (const SetPas& sSet1, const SetPas& sSet2)
{
  return( (sSet1-sSet2)==sZERO );
};   /* of "<="  */

boolean  operator >= (const SetPas& sSet1, const SetPas& sSet2)
{
  return( (sSet2-sSet1)==sZERO );
};   /* of ">="  */

      /*  операция IN (<) реализует принадлежность элемента к мн-ву */
boolean  operator IN (const byte bItem, const SetPas& sSet)
{
 byte bByte, bBit;     /* номера смещения(байта) и бита в множестве */
 //----------------
  bByte=bItem div BITS_PER_BYTE;
  bBit =bItem mod BITS_PER_BYTE;
 /* смотрим, установлен ли соответствующий бит и возвращаем результат */
  return ( (sSet.abSet[bByte] & (1<<bBit))==0 ? FALSE : TRUE);
};   /* of "IN"  */

      /* создание диапазона элементов множества */
SetPas   Range (const byte bLowItem, const byte bHighItem)
{
 SetPas sTmp;    /* конструктор инициализирует ПУСТЫМ МНОЖЕСТВОМ */
 byte  bByteLow, bBitLow, bByteHigh, bBitHigh;
 word  w;
 //------------
  if (bLowItem>bHighItem)  return(sTmp);
 /* начинаем "операцию" */
  bByteLow=bLowItem div BITS_PER_BYTE;
  bBitLow =bLowItem mod BITS_PER_BYTE;
  bByteHigh=bHighItem div BITS_PER_BYTE;
  bBitHigh =bHighItem mod BITS_PER_BYTE;
 /* Устанавливаем единичные биты */
  for (w=bByteLow; w<=bByteHigh; w++)
    {
      sTmp.abSet[w]=0xFF;
    };  /* for */
 /* Корректируем "крайние" байты */
  sTmp.abSet[bByteLow] &=(0xFF<<bBitLow);
  sTmp.abSet[bByteHigh]&=(0xFF>>(BITS_PER_BYTE-bBitHigh-1));
 /* возвращаем результат */
  return(sTmp);
};  /* of "Range" */

Аватара пользователя
Monopo
Сообщения: 119
Зарегистрирован: 06 дек 2007, 20:08
Откуда: Linux

Re: ... в С++ ~ Множество в Pascal!

Сообщение Monopo » 11 янв 2008, 18:08

А что насчет set<type,minval,maxval>X; ? Уж слишком все вывороченно, никто не поверит, что я такое создал.

Ответить