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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> исключающие маски 
:(
    Опции темы
zss
Дата 30.4.2009, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



есть маски
Код

enym MASKS
{
    a = 0x00000001,
    b = 0x00000002,
    c = 0x00000004
}


они приходят в любой комбинации. Но маска "а", должна исключать маски "b" и "с".
То есть, если пришла "a", то "b" и "c" должны сброситься, или если пришла "b" или "c". то должна сброситься "a".

Можно ли их как организовать, чтоб при побитовом сложении осуществлялось это исключение. Или только руками проверять ?
PM MAIL ICQ   Вверх
mes
Дата 30.4.2009, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  30.4.2009,  21:36 Найти цитируемый пост)
enym

enum  smile 

Цитата(zss @  30.4.2009,  21:36 Найти цитируемый пост)
они приходят в любой комбинации. Но маска "а", должна исключать маски "b" и "с".
То есть, если пришла "a", то "b" и "c" должны сброситься, или если пришла "b" или "c". то должна сброситься "a".

Ничего не понял, что требуется. Присваивайте значение пришедшей маски, и предыдущее значение сбросится.



--------------------
PM MAIL WWW   Вверх
zss
Дата 30.4.2009, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  30.4.2009,  23:07 Найти цитируемый пост)
Присваивайте значение пришедшей маски, и предыдущее значение сбросится

как это так ?
PM MAIL ICQ   Вверх
mes
Дата 30.4.2009, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  30.4.2009,  22:09 Найти цитируемый пост)

как это так ? 

Как я понял у Вас есть переменная которая должна быть равна значению одной маски, а не их сочетанию.
Ну так присваивайте нужное значение и все. Или вопрос в чем то другом ? тогда перефразируйте плиз, чтоб можно было понять, чтоб Вам требуется.
Можно попробовать подкрепить вопрос примером.  smile 

Это сообщение отредактировал(а) mes - 30.4.2009, 23:22


--------------------
PM MAIL WWW   Вверх
zss
Дата 1.5.2009, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  30.4.2009,  23:22 Найти цитируемый пост)
Как я понял у Вас есть переменная которая должна быть равна значению одной маски, а не их сочетанию.

нет - "b" и "с" сочетаться могут
PM MAIL ICQ   Вверх
MAKCim
Дата 1.5.2009, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(zss @  30.4.2009,  22:36 Найти цитируемый пост)
если пришла "b" или "c"

из-за "или" имхо нельзя


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

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


любитель
****


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

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



Цитата(zss @  30.4.2009,  23:33 Найти цитируемый пост)
нет - "b" и "с" сочетаться могут 

ну полностью задачу, так и не хотите осветить.
Можно например 
1. чтоб маска A включала в себя маски B и C, логичнее сказать для задачи использовать не { А, B, C },  а { ABC, B, C }
2. завести дополнительно исключающие маски :
Код

enum Mask
{
    Mask_A = 1 << 0,
    Mask_B = 1 << 1,
    Mask_C = 1 << 2,
    Mask_XA = Mask_B | Mask_C,
    Mask_XB=  Мask_A,
    Mask_XC = Mask_A
};


тогда установка битов по маске будет провoдиться в два действия. 
Код

bits &= ~XA; 
bits |=A;


Цитата(zss @  30.4.2009,  21:36 Найти цитируемый пост)
То есть, если пришла "a", то "b" и "c" 

кстати выражение "пришла маска" имхо, не очень удачнoe, так как сама маска никуда не ходит, 
она сидит себе тихо и проверяет пришедшие значения на нужное сочетание битов. smile



Это сообщение отредактировал(а) mes - 1.5.2009, 20:03


--------------------
PM MAIL WWW   Вверх
math64
Дата 1.5.2009, 10:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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



Код

enum Bit {
bitA, bitB, bitC
};
enum Mask {
maskA = 1 << bitA,
maskB = 1 << bitB,
maskC = 1 << bitC
};

class BitCombination {
static int disables[];
int value;
public:
   BitCombination();
   BitCombination(const BitCombination&);
   BitCombination& operator=(const BitCombination&);
   int Value() { return value; }
   BitCombination& SetBit(Bit bit);
   BitCombination& SetBits(int bits);
   BitCombination& ClrBit(Bit bit);
};

int BitCombination::disables[] = { maskB | maskC, maskA, maskA };
BitCombination& BitCombination::SetBit(Bit bit) {
  value &= ~disables[bit];
  value |= 1 << bit;
  return *this;
}



Добавлено через 6 минут и 24 секунды
Если disables сделать обычным (нестатичным), правила запретов можно менять динамически для каждого экземпляра
PM   Вверх
zss
Дата 1.5.2009, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  1.5.2009,  10:16 Найти цитируемый пост)
ну полностью задачу, так и не хотите осветить.


ну смысл такой.
Есть генератор файлов. Он поставляет файлы различных типов - либо они архивированные - либо нет. Но в один момент времени он поставляет файлы одного типа. Также в процессе работы он может поменять тип генерируемых файлов.
1. Неизвестный тип
2. Файл открыт
3. Файл архивирован
    3.1. Архивирован Неизвестным архиватором
    3.1. Zip
    3.3. Rar

Задача - описать генератор файлов. Сложность в том, что их одного файла определить этого нельзя.
Нужно накапливать свойства.

Усложняется еще и тем, что для пользователя Zip и Rar это схожие архиваторы (можно разархивировать одним приложением), но типы эти разные. То есть Zip дополняет Rar. Также можно определить, что файл архивирован, но непонятно чем.

У меня получились следующие маски
Код

enum MASKS
{
    UNKNOWN = 0x00000000,
    OPEN         = 0x00000001,
    ARCHIVE    = 0x00000002,
    XXX            = 0x10000002,
    ZIP             = 0x20000002,
    RAR            = 0x40000002
}


и при получении файла осуществляется проверка
Код

if(value != UNKNOWN)
{
    if (value & ARCHIVE)
    {
        m_value &= ~OPEN;
        m_value |= value;
    }
    else m_value = OPEN;
}


1. Если поставлялись закрытые файлы и пришел открытый, то просто меняется тип на OPEN
2. Если поставлялись открытые файлы и пришел закрытый, то сбрасывается флаг OPEN и взводится тип ARCHIVE. Если же известен тип архивации, то побитовая сумма.

Вся сложность в том, что Rar и Zip могут быть вместе, но XXX с ними не должен быть.
То есть возможные ситуации
1. XXX
2. Zip
3. Rar
4. Zip & Rar

Но вот если поставлялись файлы XXX и вдруг пожли Zip или Rar, то может получиться ток
1. XXX & Zip
2. XXX & Rar
3. XXX & Zip & Rar

что неправильно.

Вывод:
1. Хотелось бы избавиться от операций проверки и ограничиться лишь побитовыми операциями.
2. Для этого нужно как-то организовать исключающие маски.

З.Ы. И можно ли это вообще сделать без проверок ?

Добавлено через 4 минуты и 2 секунды
math64, что-то не понял как это решает мою задачу ?
PM MAIL ICQ   Вверх
math64
Дата 1.5.2009, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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



Твою задачу это не решает, она сложнее.
Можно сделать так:
Код

struct Rule {
int bitsSetted;  // Биты установленные в 1
int bitsCleared;// Биты сброшенные в 1
int bitsToSet;   // Биты, которые нужно установить в 1
int bitsToClear;// Биты, которые нужно сбросить в 1
int bitsCopyed;//  Биты, которые нужно скопировать
}; // Может быть нужны будут дополнительные поля
struct Rule[] rules = {
  // Написание кода заменяется на составление таблицы
  { ARCHIVE, UNKNOWN, ARCHIVE, OPEN, ARCHIVE | ZIP | RAR }
};
const countRules = sizeof(rules)/ sizeof(rules[0]);
// Или использовать array<Rule> rules;
void setBits(int& oldBits, int newBits)
{
   for (int i = 0; i < countRules; i++)
  {
    if ( (~newBits & rules[i].bitsSetted) == 0 &&
         (newBits & rules[i].bitsCleared) == 0 )
    {
      int toCopy = rules[i].bitsToCopy;
      oldBits = (oldbits & ~toCopy) | (newBits & toCopy);
      oldBits |= rules[i].bitsToSet;
      oldBits &= ~rules[i].bitsToClear;
    }
  }
}

PM   Вверх
mes
Дата 1.5.2009, 14:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  1.5.2009,  12:27 Найти цитируемый пост)
И можно ли это вообще сделать без проверок ? 

можно если не создавать самому себе проблем smile
Цитата(zss @  1.5.2009,  12:27 Найти цитируемый пост)
Усложняется еще и тем, что для пользователя Zip и Rar это схожие архиваторы (можно разархивировать одним приложением), но типы эти разные

а может у пользователя вобще не будет WinRara, или такая версия которая любой архив одинаково легко раскроет smile
А так как файл не знает ничего о приложении которое его будет открывать, он должен хранить только тип алгоритма. (т.е никаких сдвоенных масок)

чтоб долго словами не объяснять, вот условный код того, как я вижу решение :

Код

namespace File {
 namespace Archive {
   enum EType { eUnknown, еOpen, eZip, eRar, eXXX };
 } // Archive

  struct Descriptor
  {
      int ArchiveType;
  };
  
  struct Archivator 
  {
      virtual bool CanDecode (const Descriptor&) =0;
  };
} // File

struct WinRar : public File::Archivator
{

        virtual bool CanDecode (const Descriptor& d)  
        { 
            using namespace File::Archive;

            switch (d.ArchiveType)
            {                 
                    case еOpen  : 
                    case eZip   : 
                    case eRar   : return true; 
       
                   default : return false;
            };
        }
};  
}








Это сообщение отредактировал(а) mes - 1.5.2009, 14:16


--------------------
PM MAIL WWW   Вверх
math64
Дата 1.5.2009, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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



Да, с классами код будет понятнее.
PM   Вверх
zss
Дата 1.5.2009, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  1.5.2009,  14:13 Найти цитируемый пост)
а может у пользователя вобще не будет WinRara, или такая версия которая любой архив одинаково легко раскроет smile
А так как файл не знает ничего о приложении которое его будет открывать, он должен хранить только тип алгоритма. (т.е никаких сдвоенных масок)

я лишь привел надуманный пример. Задача ставится именно для сдвоенных масок.

Добавлено @ 14:21
необходимо различать типы
xxx
rar
zip
zip & rar

Добавлено @ 14:22
xxx к тому же исключающий zip и rar

Это сообщение отредактировал(а) zss - 1.5.2009, 14:22
PM MAIL ICQ   Вверх
mes
Дата 1.5.2009, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  1.5.2009,  13:20 Найти цитируемый пост)
я лишь привел надуманный пример. Задача ставится именно для сдвоенных масок.

ну так приводите реальные примеры, что мешает приподнять занавесу таинственности  ? smile

Цитата(zss @  1.5.2009,  13:20 Найти цитируемый пост)
необходимо различать типы

Кому и для чего необходимо ? Поподробней.  smile 





--------------------
PM MAIL WWW   Вверх
zss
Дата 1.5.2009, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  1.5.2009,  16:21 Найти цитируемый пост)
ну так приводите реальные примеры, что мешает приподнять занавесу таинственности  ? 


Цитата(mes @  1.5.2009,  16:21 Найти цитируемый пост)
Кому и для чего необходимо ? Поподробней. 

ну разве это имеет значение.
Я лишь обозвал тепло - мягким.

На суть это не влияет(и на решение задачи тоже)
PM MAIL ICQ   Вверх
mes
Дата 1.5.2009, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  1.5.2009,  15:26 Найти цитируемый пост)
На суть это не влияет(и на решение задачи тоже) 

Если считатете, что тут сидят телепаты Вы ошибаетесь (по крайней мере я пока таких не встречал), и если надеетесь получить ответ от кого нибудь из форумчан,
то проявите усердие и поставьте задачу ясно.

Цитата(mes @  1.5.2009,  15:21 Найти цитируемый пост)
Кому и для чего необходимо ? Поподробней. 

Тут идет вопрос не о программисте или заказачике и не об их личных данных  smile 






--------------------
PM MAIL WWW   Вверх
zss
Дата 1.5.2009, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  1.5.2009,  16:41 Найти цитируемый пост)
то проявите усердие и поставьте задачу ясно.

задача была поставлена четко.

Есть тип А, B и C. B и C могут существовать вместе как побитовая сумма, а А нет.
Причем А исключает существование В и С. Необходимо реализовать это исключение битовыми операциями.

Вроде все понятно. А пример приводился для наглядности (я уже пожалел, что его привел smile).
PM MAIL ICQ   Вверх
mes
Дата 1.5.2009, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  1.5.2009,  15:48 Найти цитируемый пост)
задача была поставлена четко.


Цитата(zss @  1.5.2009,  15:48 Найти цитируемый пост)
Есть тип А, B и C.

Наверно это :  есть три константы, каждая из которых представлена одним битом.

Цитата(zss @  1.5.2009,  15:48 Найти цитируемый пост)
B и C могут существовать вместе как побитовая сумма, а А нет. Причем А исключает существование В и С. 

тут вроде понятно. Т.е есть битовый набор который может принимать только определенные комбинации.


Цитата(zss @  1.5.2009,  15:48 Найти цитируемый пост)
Необходимо реализовать это исключение битовыми операциями.

А вот тут абсолютно непонятно. 
Вот есть число n. Как именно с ним реализовать это исключение ?  smile 

Наверно имелось ввиду, что при добавлении битовой констаты к набору(т.е при операции OR), исключающие биты должны обнулиться ?
В таком случае ответ был дан  еще тут : http://forum.vingrad.ru/index.php?showtopi...t&p=1857621



Это сообщение отредактировал(а) mes - 1.5.2009, 17:04


--------------------
PM MAIL WWW   Вверх
zss
Дата 1.5.2009, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  1.5.2009,  16:59 Найти цитируемый пост)
Наверно имелось ввиду, что при добавлении битовой констаты к набору(т.е при операции OR), исключающие биты должны обнулиться ?

типа того smile терминология для второй страницы топика, я думаю, не совсем уместна.
Ты давно понял что я хочу smile
PM MAIL ICQ   Вверх
mes
Дата 1.5.2009, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  1.5.2009,  16:06 Найти цитируемый пост)
Ты давно понял что я хочу smile 


ну так подходит решение или нет ?
Цитата(mes @  1.5.2009,  15:59 Найти цитируемый пост)
 http://forum.vingrad.ru/index.php?showtopi...t&p=1857621

если нет, то чего в нем не хватает ?

Добавлено через 4 минуты и 51 секунду
Цитата(zss @  1.5.2009,  16:06 Найти цитируемый пост)
Ты давно понял что я хочу smile 

А понял что Вам надо.. сейчас 

Это сообщение отредактировал(а) mes - 1.5.2009, 17:28


--------------------
PM MAIL WWW   Вверх
zss
Дата 1.5.2009, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  1.5.2009,  17:24 Найти цитируемый пост)

если нет, то чего в нем не хватает ?

то что в данно случае нужно будет проводить проверки.

Код

if (value & Mask_A)
{
   ....
}
else if (value & (Mask_B | Mask_C))
{
   ....
}


а хотелось бы накладывать маску, которая сама контролирует взаимное исключение
PM MAIL ICQ   Вверх
mes
Дата 1.5.2009, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



вот опять условным кодом:  
Код

enum EBits { eA, eB, eC, eMax }; // это выражаясь вашей терминологии значения "типов"
const int Mask[]  = { 1<<eA, 1<<eB, 1<<eC }; // это их маски для хранения в контейнере
const int XMask[] = { /* eA */  Mask[eB] | Mask[eC],     // исключающие маски
                      /* eB */  Mask[eA],
                      /* eC */  Mask[eA]  };
void AddBit (int& set, int bit) // процедура корректного добавления "значения типа"  к "набору"
{
    if (bit >= eMax) return;
    set &= ~XMask[bit];
    set |= Mask[bit];
};
bool HasBit (int& set, int bit) // проверка на нахождение в "наборе" нужного значения типа.
{
      if (bit >= eMax) return false;
      return set & Mask[bit];
};

исправлено 

так пойдет ? 

Это сообщение отредактировал(а) mes - 1.5.2009, 19:43


--------------------
PM MAIL WWW   Вверх
math64
Дата 1.5.2009, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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



Выбирай из трёх вариантов:
1. Пиши ifы, как собирался сам.
2. Составляй таблицу Rule rules[], как предлагал я.
Возможно struct Rule будет сложнее, для хранения их можно выбрать какой нибудь контейнер stl, который позволит быстрее найти нужную/-ые запись/-и.
3. Пиши набор классов Archivator, как предложил mes.
4. ЭКЗОТИКА: Выбрать другой язык программирования типа LISP или Prolog или запрограммировать ПЛМ.
Врядли можно придумать что-то ещё.
IMHO, вариант mes лучше
PM   Вверх
zss
Дата 1.5.2009, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  1.5.2009,  17:51 Найти цитируемый пост)
так пойдет ? 

Код

    int value = eA;
    AddBit(value, eB);
    AddBit(value, eC);

value == eC, а должен == eB | eC

Код

    int value = eA;
    AddBit(value, eB | eC);

value == 0, а должен == eB | eC
PM MAIL ICQ   Вверх
mes
Дата 1.5.2009, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(zss @  1.5.2009,  18:22 Найти цитируемый пост)
value == eC, а должен == eB | eC

из за написания на скорую руку, код содержал глюки - вот подправил

Цитата(zss @  1.5.2009,  18:22 Найти цитируемый пост)
AddBit(value, eB | eC);

А так применять нельзя, так как eB это не маска, а значение типа. 
Чтоб можно было за раз устанавливать оба бита, то можете добавить в список тип eBC с необходимыми масками.
К тому же приведенный код лишь демонстрация  и для заключительной версии требует доработки smile

Добавлено через 5 минут и 25 секунд
Цитата(zss @  1.5.2009,  18:22 Найти цитируемый пост)
 int value = eA;

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

Добавлено через 6 минут и 54 секунды
Поэтому лучше подобные вещи разгружать через типы, а не значения.
Тогда можно будет определить те операции которые требуется и компилятор сам будет следить за коректностью. 

Это сообщение отредактировал(а) mes - 1.5.2009, 19:49


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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



По коду mes (1.5.2009, 17:51)
Код

void AddBit (int set, int bit) // процедура корректного добавления "значения типа"  к "набору"
{
    if (bit >= eMax) return;
    set &= ~XMask[bit]; // В XMask биты которые нужно снять, а не оставить
    set |= Mask[bit];
};


Код

    int value = eA;
    AddBit(value, eB | eC);

Так нельзя, eВ и eC - номера битов, их нельзя оъбединять по или
Код

    int value = Mask[eA];
    value = AddBits1(value, Mask[eB] | Mask[eC]);

или
Код

    int value = Mask[eA];
    value = AddBits2(value, eB, eC, -1);

Код

int AddBits1(int set, int mask) {
  for (int i = 0; i < eMax; i++)
     if ( (mask & Mask[i]) != 0)
       AddBit(set, i);
  return set;
}
int AddBits2(int set, ...) {
  va_list v;
  va_start(v, mask)
  for (;;) {
    int i = va_arg(v, int); 
    if (i < 0)
      break;
    AddBit(set, i);
  }
  va_end();
  return set;
}


Добавлено через 14 минут и 27 секунд
Вот тебе код без if:
Код

int Table[64];
void InitTable() {
  for(int i = 0; i < 8; i++)
    for (int j = 0; j < 8; j++) {
       Table[i*8+j] = AddBits1(i, j);
    }
}

int AddBits3(int set1, int set2) {
  return Table[set1*8+set2);




Это сообщение отредактировал(а) math64 - 1.5.2009, 19:59
PM   Вверх
KEHT
Дата 3.5.2009, 21:16 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

#include <iostream>
#include <cassert>
using namespace std;
/*Класс T представляет тип маски и требует выполнения следующих условий
    1)Наличие конструктора по умолчанию
    2)Наличие копирующего конструктора
    3)Наличие оператора присваивания
    4)Наличие оператора сравнения
    4)Наличие функций для побитовых операций
*/
/*
Каждому объекту задается disallowed_mask. Если объект, подаваемый на вход содержится в этой маске,
то значения объекта замещается.
*/
template<typename T> class Mask;

template<typename T>
class Mask{
    T mask, disallowed_mask;
public:
    Mask(): mask(), disallowed_mask(){}
    Mask(const Mask &m): mask(m.mask), disallowed_mask(m.disallowed_mask){}
    Mask(T _mask, T _disallowed_mask): mask(_mask), disallowed_mask(_disallowed_mask){}
    Mask& operator=(const Mask &r){
        if(this != &r){
            mask = r.mask;
            disallowed_mask = r.disallowed_mask;
        }
        return *this;
    }
    //Бинарные операторы
    friend const Mask operator|(const Mask &l, const Mask &r){
        if(r.mask == (r.mask & l.disallowed_mask))
            return r;
        else
            return Mask(l.mask | r.mask, l.disallowed_mask);
    }
    Mask& operator|=(const Mask &r){
        if(r.mask == (r.mask & disallowed_mask) && this != &r)
            mask = r.mask;
        else
            mask |= r.mask;
        return *this;
    }
    //Функции доступа
    T get() const{ return mask; }
};

int main(){
    Mask<int> a(1, 4), b(2, 4), c(4, 3);
    
    assert((a | b).get() == 3);
    assert((a | c).get() == 4);
    assert((c | a).get() == 1);
    assert((b | c).get() == 4);
    assert((c | b).get() == 2);
    assert((c | c).get() == 4);
    
    return 0;
}


Минус реализации, что если тебе нужно будет, чтобы 
A = 00000001
B = 00000010
C = 00000011

С замещала B, то придеца указать B запрещающую маску 00000011, а это приведет к блокированию A

Как вариант использовать vector<T>(или другой контейнер) для хранения масок
PM MAIL   Вверх
math64
Дата 4.5.2009, 07:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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



Идея неплохая, но в реализации operator |= и operator | есть ошибки, нужно вычислять новую disallowed_mask и mask вычисляется не всегда правильно.
Можно добавить friend T operator |(const T&, const Mask&); чтобы искючить ненужное вычисление disallowed_mask.
PM   Вверх
KEHT
Дата 4.5.2009, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

нужно вычислять новую disallowed_mask

Я исходил из условия задачи, в котором следовало, что объект справа от оператора подается на вход левому, поэтому и disallowed_mask оставлял от левого объекта.
Цитата

mask вычисляется не всегда правильно

Тут да. В данной реализации к типу T предъявляются довольно существенные ограничения. Идеально было бы хранить контейнер со всем запрещенными масками.
Цитата

Можно добавить friend T operator |(const T&, const Mask&); чтобы искючить ненужное вычисление disallowed_mask.

Я так понял, что по условию задачи левый от оператора объект предъявляет требования к правому, поэтому скорее
friend T operator |(const Mask&, const T&);


Это сообщение отредактировал(а) KEHT - 4.5.2009, 14:05
PM MAIL   Вверх
J0ker
Дата 4.5.2009, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

enum MASKS
{
    UNKNOWN = 0x00000000,
    OPEN         = 0x00000001,
    ARCHIVE    = 0x10000000,
    ZIP             = 0x30000000,
    RAR            = 0x50000000,
    ZIP_RAR     = 0x70000000
}




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


Опытный
**


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

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



J0ker, и как их пользовать ?
PM MAIL ICQ   Вверх
J0ker
Дата 4.5.2009, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(zss @ 4.5.2009,  19:04)
J0ker, и как их пользовать ?

Код

enum MASKS
{
    UNKNOWN = 0x00000000,
    OPEN         = 0x00000001,
    ARCHIVE    = 0x10000000,
    ZIP             = 0x30000000,
    RAR            = 0x50000000,
    ZIP_RAR     = 0x70000000
}

bool is_open(unsigned int f)
{
    return (f & OPEN) != 0;
}

bool is_archive(unsigned int f)
{
    return (f & ARCHIVE) != 0;
}

bool is_zip(unsigned int f)
{
    return (f & ZIP) == ZIP;
}

bool is_rar(unsigned int f)
{
    return (f & RAR) == RAR;
}

bool is_zip_rar(unsigned int f)
{
    return (f & ZIP_RAR) == ZIP_RAR;
}

unsigned int set_open(unsigned int &f)
{
    return f &= OPEN;
}

unsigned int set_archive(unsigned int &f)
{
    return f &= ARCHIVE;
}

unsigned int set_zip(unsigned int &f)
{
    return f &= ZIP;
}

unsigned int set_rar(unsigned int &f)
{
    return f &= RAR;
}

unsigned int set_zip_rar(unsigned int &f)
{
    return f &= ZIP_RAR;
}

//====================================

unsigned int f = UNKNOWN;

set_zip(f);

if(is_archive(f))
    cout << "archive" << endl;



Это сообщение отредактировал(а) J0ker - 4.5.2009, 19:28


--------------------
user posted image
PM MAIL   Вверх
mes
Дата 4.5.2009, 19:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



zss, ловите идею, может пригодится :
Код

#include <iostream>

struct Type
{
    struct TMeta
    {
        int Mask;
        int XMask;
    };
    virtual TMeta Meta() const =0;
};

struct AType : Type
{
      virtual TMeta Meta() const  { TMeta Meta ={1<<0, 1<<1 | 1<<2 }; return Meta; };
};

struct BType : Type
{
      virtual TMeta Meta() const  { TMeta Meta ={1<<1, 1<<0 }; return Meta; };
};

struct CType : Type
{
      virtual TMeta Meta() const  { TMeta Meta ={1<<2, 1<<0}; return Meta; };
};

class TypeSet
{
    public:
        TypeSet () : set (0) {}

        void Add (const Type& type)
        {
              set &= ~type.Meta().XMask;
              set |=  type.Meta().Mask;
        }
        bool Has (const Type& type)
        {
            return set & type.Meta().Mask;
        }

    private:
        int set;
};

void Test (TypeSet& set, const Type& type)
{
    set.Add (type);
    std::cout <<set.Has(AType())<<" "<<set.Has(BType())<<" "<<set.Has(CType())<<" " << std::endl;
}

int main ()
{
     TypeSet set;

     Test (set, AType());
     Test (set, BType());
     Test (set, CType());
     Test (set, AType());


    system ("pause");
    return 0;
}




блок с 13й по 26ю строку можно записать примерно так :
Код

#define DECLARE_TYPE(name, Mask, XMask)  struct name : Type{ virtual TMeta Meta() const   { return (TMeta){ Mask, XMask }; } };

 DECLARE_TYPE (AType, 1<<0,  1<<1 | 1<<2 )
 DECLARE_TYPE (BType, 1<<1,  1<<0 )
 DECLARE_TYPE (CType, 1<<2,  1<<0 )

#undef DECLARE_TYPE 

подправлено забытое, в связи с  замечанием J0ker'а

Это сообщение отредактировал(а) mes - 4.5.2009, 21:22


--------------------
PM MAIL WWW   Вверх
J0ker
Дата 4.5.2009, 20:12 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



6: #undef DECLARE_TYPE


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


Опытный
**


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

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



J0ker, идея хорошая, только у тебя нет исключающего архива.
PM MAIL ICQ   Вверх
math64
Дата 5.5.2009, 08:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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



Код

struct Type
{
   int Mask;
   int XMask;
};
const Type AType = { 1<<0,  1<<1 | 1<<2 };
const Type BType = { 1<<1,  1<<0 };
const Type CType = { 1<<2,  1<<0 };

с соответствующими упрощениями  TypeSet.
PM   Вверх
J0ker
Дата 5.5.2009, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(zss @ 5.5.2009,  07:02)
J0ker, идея хорошая, только у тебя нет исключающего архива.

то есть?
все комбинации в моем варианте заведомо верны
или вы это имели ввиду:
Код

enum MASKS
{
    UNKNOWN = 0x00000000,
    OPEN         = 0x00000001,
    ARCHIVE    = 0x10000000,
    ZIP             = 0x30000000,
    RAR            = 0x50000000,
    ZIP_RAR     = 0x70000000,
    ARCHIVE_FLAGS = 0x70000000
}

bool is_archive_unknown(unsigned int f)
{
    return (f & ARCHIVE_FLAGS) == ARCHIVE;
}



Это сообщение отредактировал(а) J0ker - 5.5.2009, 09:09


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


Бывалый
*


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

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



Позвольте вопрос...
Код

enum MASKS
{
    UNKNOWN = some_mask1,
    OPEN         = some_mask2,
    ARCHIVE    = some_mask3,   //а вот это действительно нужно?
    ZIP             = some_mask4,
    RAR            = some_mask5,
    XXX     = some_mask6,
}


Ведь если файл zip, rar или unknown_archive - он ведь все равно архив...

Это сообщение отредактировал(а) Static - 5.5.2009, 14:21
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
zss
Дата 5.5.2009, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(J0ker @  5.5.2009,  09:02 Найти цитируемый пост)
то есть?

архив xxx, который не может существовать с zip и rar
PM MAIL ICQ   Вверх
J0ker
Дата 5.5.2009, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(zss @ 5.5.2009,  14:31)
Цитата(J0ker @  5.5.2009,  09:02 Найти цитируемый пост)
то есть?

архив xxx, который не может существовать с zip и rar

ну как-же нет
ARCHIVE


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


Опытный
**


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

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



Цитата(J0ker @  5.5.2009,  16:10 Найти цитируемый пост)
ну как-же нет
ARCHIVE 

нет - ARCHIVE говорит что он закрыт, но возможно неизвестным архиватором - это не тип архива
а тип - автоматически должен подразумевать архивацию
PM MAIL ICQ   Вверх
J0ker
Дата 5.5.2009, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(zss @  5.5.2009,  16:31 Найти цитируемый пост)
ARCHIVE говорит что он закрыт, но возможно неизвестным архиватором 

ARCHIVE с учетом не выставленных ZIP и RAR говорит об этом совершенно прямолинейно



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


Опытный
**


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

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



Цитата(J0ker @  5.5.2009,  17:01 Найти цитируемый пост)
ARCHIVE с учетом не выставленных ZIP и RAR говорит об этом совершенно прямолинейно

это понятно. нужно сто 3 архив xxx исключал их. весь вопрос именно в этом
PM MAIL ICQ   Вверх
J0ker
Дата 5.5.2009, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(zss @  5.5.2009,  17:32 Найти цитируемый пост)
это понятно. нужно сто 3 архив xxx исключал их. весь вопрос именно в этом 

Код

enum MASKS
{
    UNKNOWN = 0x00000000,
    OPEN         = 0x00000001,
    ARCHIVE    = 0x10000000,
    ZIP             = 0x30000000,
    RAR            = 0x50000000,
    ZIP_RAR     = 0x70000000,
    XXX            = 0xF0000000,
    ARCHIVE_FLAGS = 0xF0000000
}



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


любитель
****


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

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



J0ker,  
Цитата(zss @  1.5.2009,  16:06 Найти цитируемый пост)
Цитата

Наверно имелось ввиду, что при добавлении битовой константы к набору(т.е при операции OR), исключающие биты должны обнулиться ?

типа того smile 






--------------------
PM MAIL WWW   Вверх
J0ker
Дата 5.5.2009, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @ 5.5.2009,  17:41)
J0ker,  
Цитата(zss @  1.5.2009,  16:06 Найти цитируемый пост)
Цитата

Наверно имелось ввиду, что при добавлении битовой константы к набору(т.е при операции OR), исключающие биты должны обнулиться ?

типа того smile 

для этого к флагам прилагаются функции
можно засунуть все это в класс
от битовых флагов в чистом виде такого поведения добиться невозможно


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


Опытный
**


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

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



Цитата(J0ker @  5.5.2009,  17:54 Найти цитируемый пост)
от битовых флагов в чистом виде такого поведения добиться невозможно 

ну mes приводил не плохое решение. наверное на этом и остановимся smile

всем спасибо
PM MAIL ICQ   Вверх
math64
Дата 6.5.2009, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

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




Код

enum Bit {
   Unknown,
   Unpacked, // насколько я понял OPEN - это НЕ ЗАПАКОВАННЫЙ файл
   Archived,
   Rar,
   Zip,
   Other // Запаковано другим архиватором
};

class Set<Bit> set;
class Map<Bit, Set<Bits> > plus, minus;
void AddBit(Set<Bit> set,  Bit bit) {
   set -= minus[bit];
   set += plus[bit];
}

А теперь, какая самая простая реализация Set<Bit>? int (или short, unsigned char...).
А Map<Bit, Set<Bits> >? int[Other+1].
Код

int plus[] = {...};
int minus[] = {...};
void AddBit(int set,  Bit bit) {
   set &= ~minus[bit];
   set |= plus[bit];
}

PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.2191 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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