... в С++ ~ Множество в Pascal!
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Скажите, есть ли в С множественный тип данных? Хотелось бы применить его к задаче: каких двубуквенных сочетаний в строке больше (согл+согл) / (глас+глас) / (согл+глас). Если в С аналогов нет, то подскажите, чем можно заменить множество {в данном случае, согласных и гласных букв}?
Юный Падаван
Стандартного типа данных нет.
В свое время когда-то "для тренировки" я писал в C++ класс - аналог паскалевского множества.
В свое время когда-то "для тренировки" я писал в C++ класс - аналог паскалевского множества.
- Romeo
- Сообщения: 3091
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Можно написать свой простенький набор функций для работы с множествами, используя битовые операции.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ну.. Эээ.. Бывалому то легко говорить)" писал(а):Можно написать свой простенький набор функций для работы с множествами, используя битовые операции.
Юный Падаван
У меня это выглядело примерно так:
PAS_SET.H:
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
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)" */
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" */
А что насчет set<type,minval,maxval>X; ? Уж слишком все вывороченно, никто не поверит, что я такое создал.