Консультация № 183902
20.08.2011, 06:07
0.00 руб.
0 11 0
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Помогите пожалуйста написать программу!
Задание: Создать класс BitString для работы с битовыми строками не более чем из 100 бит. Битовая строка должна быть представлена массивом типа unsigned char, каждый элемент которого принимает значение 0 или 1. Реальный размер массива задается как аргумент конструктора инициализации. Должны быть реализованы все традиционные операции для работы с битовыми строками: and, or, xor, not. Реализовать сдвиг влево и сдвиг вправо на заданное количество битов!

Для каждой структуры реализовать 3 конструктора: без аргументов, копирования и инициализации. Функции ввода/вывода оформить как дружественные.
Нашел готовую программу на вашем сайте, но мне надо сделать в среде VS 2003

Обсуждение

Неизвестный
20.08.2011, 16:16
общий
А что здесь, https://rfpro.ru/question/167241, не работает под VS 2003?
Неизвестный
20.08.2011, 17:04
общий
В том то и дело
Неизвестный
22.08.2011, 06:54
общий
А что говорит? Какие ошибки или что там?
Неизвестный
22.08.2011, 21:34
общий
Ведь, мягко говоря, не у всех есть все версии. Они кое в чем мешают друг другу... Но можно сообразить, если увидеть сообщения
Неизвестный
23.08.2011, 00:28
общий
ну, ошибок выдает много, не помню какие, поскольку какой-то вирус мне всё форматнул(( Просто среда не подходит. Хоть я и не силён в программировании, но кое что понимаю, и будь у меня время сам бы написал программу. Ошибки, насколько помню, связаны с функциями, и другие ошибки выдает, скорей всего какие-то библиотеки наверное не подкоючены
Неизвестный
23.08.2011, 17:55
общий
А так работает? И что пишет компилятор?
Код:
#include <limits>
#include <stdexcept>
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class bitstring
{
public:
// Тип элемента в котором будут храниться наши данные. int выбран только потому, что современные процессоры
// быстрее работают с 32х битными данными(при условии выравнивания по границе слова), чем с отдельными байтами.
// Если надо Вам unsigned char замените.
typedef unsigned int itemType;
// Конструктор
// value-значение
// length-длина нашей битовои строки(в битах)
bitstring(itemType value = 0, size_t length = _itemSize);
// Конструктор в качестве аргумента принимающий строку символов
bitstring(const string& str, size_t length = _itemSize);
// Битовые операции представлены стандартным набором
// И
bitstring operator&(const bitstring& b) const;
// ИЛИ
bitstring operator|(const bitstring& b) const;
// Исключающее ИЛИ
bitstring operator^(const bitstring& b) const;
// НЕ
bitstring operator~() const;
// Сдвиг влево
bitstring operator<<(unsigned char b) const;
// Сдвиг вправо
bitstring operator>>(unsigned char b) const;
// Индексатор
bool operator[](size_t bit);
// Возвращает размер в битах
size_t length() const;
private:
// Тип вектор для хранения данных
typedef vector<itemType> dataType;
// Количество бит в одном элементе вектора
static const int _itemSize = sizeof (itemType)*8;
// Здесь будем хранить число
dataType _data;
// Длина строки в битах
size_t _length;
// Используется внутри класса
bitstring(dataType data, size_t length);
// Используется для получения маски в для битовых операций

static itemType createMask(size_t length)
{
size_t shift = length % _itemSize;
if (!shift)shift = _itemSize;
return ~(numeric_limits<itemType>::max() << shift);
}
// Используется внутри класса. Обнуляет лишние биты если длина битовой строки не кратна размеру элемента itemType

void trim()
{
if (_data.size())_data[_data.size() - 1] &= createMask(_length);
}
// Операторы ввода-вывода
friend istream & operator>>(istream& stream, bitstring& b);
friend ostream & operator<<(ostream& stream, const bitstring& b);
};
// Будем использовать для ввода битовых строк

void bitstringInput(string msg, bitstring& res)
{
while (true)
{
cout << msg;
cin >> res;
if (cin.fail())
{
cout << "Ошибочный ввод" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
{
cin.ignore(numeric_limits<streamsize>::max(), '\n');
break;
}
}
}

int main()
{
setlocale(LC_ALL, "russian");
// Объявим 2 битовых строки длиной 64 и 16 бит
bitstring A(0, 64), B(0, 16);
// Вводим их
bitstringInput("Введите A:", A);
bitstringInput("Введите B:", B);
// Пример операций
cout << "A=" << A << endl;
cout << "B=" << B << endl;
cout << "A&B=" << (A & B) << endl;
cout << "A|B=" << (A | B) << endl;
cout << "A^B=" << (A^B) << endl;
cout << "~A=" << (~A) << endl;
cout << "~B=" << (~B) << endl;
cout << "A>>2=" << (A >> 2) << endl;
cout << "B>>7=" << (B >> 7) << endl;
cout << "A<<2=" << (A << 2) << endl;
cout << "B<<7=" << (B << 7) << endl;
system("PAUSE");
return 0;
}

bitstring::bitstring(itemType value, size_t length)
: _length(length)
{
if (_length == 0)_length = _itemSize;
size_t dataLength = _length / _itemSize + (_length % _itemSize ? 1 : 0);
_data.resize(dataLength, 0);
_data[0] = value;
trim();
}

bitstring::bitstring(const string& str, size_t length)
: _length(length)
{
if (_length == 0)_length = str.length();
size_t dataLength = _length / _itemSize + (_length % _itemSize ? 1 : 0);
_data.resize(dataLength, 0);
string::const_reverse_iterator strIt = str.rbegin();
dataType::iterator dataIt = _data.begin();
while (strIt != str.rend() && dataIt != _data.end())
{
int bitsCount = 0;
itemType value = 0;
while (strIt != str.rend() && bitsCount < _itemSize)
{
switch (*strIt)
{
case '0':
break;
case '1':
value |= (1 << bitsCount);
break;
default:
_data.clear();
throw invalid_argument("This is not bit String");
}
++bitsCount;
++strIt;
}
*dataIt++ = value;
}
trim();
}

bitstring::bitstring(dataType data, size_t length)
: _data(data)
, _length(length)
{
if (!_data.size())_data.push_back(0);
if (_length == 0)_length = _itemSize;
size_t dataLength = _length / _itemSize + (_length % _itemSize ? 1 : 0);
_data.resize(dataLength, 0);
trim();
}

bitstring bitstring::operator&(const bitstring& b) const
{
size_t maxBits = max(_length, b._length);
size_t minLen = min(_data.size(), b._data.size());
dataType data(minLen);
for (unsigned int i = 0; i < minLen; ++i)
{
data[i] = _data[i] & b._data[i];
}
return bitstring(data, maxBits);
}

bitstring bitstring::operator|(const bitstring& b) const
{
size_t maxBits = max(_length, b._length);
size_t minLen = min(_data.size(), b._data.size());
size_t maxLen = max(_data.size(), b._data.size());
dataType data(maxLen);
for (unsigned int i = 0; i < minLen; ++i)
{
data[i] = _data[i] | b._data[i];
}
const dataType* from = 0;
if (_data.size() > b._data.size())from = &_data;
else if (_data.size() < b._data.size())from = &b._data;
if (from)
{
for (size_t i = minLen; i < maxLen; ++i)
{
data[i] = (*from)[i];
}
}
return bitstring(data, maxBits);
}

bitstring bitstring::operator^(const bitstring& b) const
{
size_t maxBits = max(_length, b._length);
size_t minLen = min(_data.size(), b._data.size());
size_t maxLen = max(_data.size(), b._data.size());
dataType data(maxLen);
for (unsigned int i = 0; i < minLen; ++i)
{
data[i] = _data[i]^b._data[i];
}
const dataType* from = 0;
if (_data.size() > b._data.size())from = &_data;
else if (_data.size() < b._data.size())from = &b._data;
if (from)
{
for (size_t i = minLen; i < maxLen; ++i)
{
data[i] = (*from)[i]^0;
}
}
return bitstring(data, maxBits);
}

bitstring bitstring::operator~() const
{
dataType data(_data.size());
for (unsigned int i = 0; i < _data.size(); ++i)
{
data[i] = ~_data[i];
}
return bitstring(data, _length);
}

bitstring bitstring::operator<<(unsigned char b) const
{
dataType data(_data);
int distance = b / _itemSize;
int shift = b % _itemSize;
if (distance)
{
for (unsigned int i = distance, j = 0; i < data.size(); ++i, ++j)
{
data[i] = data[j];
data[j] = 0;
}
}
itemType carry = 0;
itemType mask = ~(numeric_limits<itemType>::max() >> shift);
for (dataType::iterator it = data.begin(); it != data.end(); ++it)
{
itemType newCarry = ((*it) & mask) >> (_itemSize - shift);
*it = ((*it) << shift) | carry;
carry = newCarry;
}
return bitstring(data, _length);
}

bitstring bitstring::operator>>(unsigned char b) const
{
dataType data(_data);
int distance = b / _itemSize;
int shift = b % _itemSize;
if (distance)
{
for (unsigned int i = distance, j = 0; i < data.size(); ++i, ++j)
{
data[j] = data[i];
data[i] = 0;
}
}
itemType carry = 0;
itemType mask = ~(numeric_limits<itemType>::max() << shift);
for (dataType::reverse_iterator it = data.rbegin(); it != data.rend(); ++it)
{
itemType newCarry = ((*it) & mask) << (_itemSize - shift);
*it = ((*it) >> shift) | carry;
carry = newCarry;
}
return bitstring(data, _length);
}

bool bitstring::operator[](size_t bit)
{
if (bit < _length)
{
unsigned int itemNo = bit / _itemSize;
unsigned int shift = bit % _itemSize;
itemType mask = 1 << shift;
return (_data[itemNo] & mask) != 0;
}
else throw range_error("bool operator[](unsigned int bit):parameter 'bit' out of range");
}

inline size_t bitstring::length() const
{
return _length;
}

istream & operator>>(istream& stream, bitstring& b)
{
string str;
stream >> str;
bitstring::dataType data;
for (string::const_reverse_iterator it = str.rbegin(); it != str.rend();)
{
int bitsCount = 0;
bitstring::itemType value = 0;
while (it != str.rend() && bitsCount < b._itemSize)
{
switch (*it)
{
case '0':
break;
case '1':
value |= (1 << bitsCount);
break;
default:
stream.setstate(ios::badbit);
return stream;
}
++bitsCount;
++it;
}
data.push_back(value);
}
if (b._length == 0)b._length = b._itemSize;
size_t dataLength = b._length / b._itemSize + (b._length % b._itemSize ? 1 : 0);
data.resize(dataLength, 0);
data[data.size() - 1] &= bitstring::createMask(b._length);
b._data = data;
return stream;
}

ostream & operator<<(ostream& stream, const bitstring& b)
{
string res;
for (bitstring::dataType::const_iterator it = b._data.begin(); it != b._data.end(); ++it)
{
unsigned int count = 0;
bitstring::itemType value = *it;
while (count < b._itemSize)
{
if (value & 1)res = '1' + res;
else res = '0' + res;
value >>= 1;
++count;
}
}
if (res.length() > b._length)res.erase(0, res.length() - b._length);
res.erase(0, res.find('1'));
if (res.empty())res = '0';
stream << res;
return stream;
}
Неизвестный
25.08.2011, 17:56
общий
одна ошибка, не находит #include <stdexcept>
Неизвестный
30.08.2011, 12:42
общий
Попробуйте закомментить #include <stdexcept>, если на другие библиотеки ругаться не будет, можно без неё обойтись попробовать. Хотя это странно. Думала, получится на 2003 студии проверить, но не добыла.
Неизвестный
30.08.2011, 18:17
общий
а если коментить, то слишком много ошибок выдает
Неизвестный
31.08.2011, 00:06
общий
Какие ошибки, можете выложить?
Я сейчас просто в 2005 попробовала этот хидер убрать, так ничего не изменилось...
Неизвестный
31.08.2011, 06:09
общий
Я посмотрел этот заголовочный файл, надо закомментировать:

throw invalid_argument("This is not bit String");
и
else throw range_error("bool operator[](unsigned int bit):parameter 'bit' out of range");

или вместо них использовать свои обработчики.

Вроде, больше нигде не используется.
Форма ответа