Штука то интересная. Вес Хэмминга это количество единиц в числе, если его перевести в двоичную систему. Реализовать можно разными способами. Например так:
[code lang=»c»]
#include «stdafx.h»
#include <stdio.h>
#include <locale.h>
#include <math.h>
#include <stdlib.h>
int getWeightOfHemming(int number);
int main()
{
int number;
scanf(«%d»,&number);
char local[255];
printf(«%d»,getWeightOfHemming(atoi(itoa(number,local,2))));
}
int getWeightOfHemming(int number)
{
int sum=0;
while(number!=0)
{
sum+=number%10;
number/=10;
}
return sum;
}[/code]
Здесь есть мудреная строчка (это нифига не правильно, не красиво, но работает шикарно!)
printf("%d",getWeightOfHemming(atoi(itoa(number,local,2))));
А суть тут такова. Берется число number. Функцией itoa это число переводится в массив символов с основанием 2 — т.е на данном этапе у нас уже двоичная запись. Далее функцией atoi переводим эту строку в число. Получается двоичное число. Далее считаем количество единичек внутри функции нами описанной — getWeightOfHemming.
Ну это уже C++. И с использованием бинарных сдвигов.
За код спасибо!
о_О где бинарные сдвиги?
а. Показалось :)
конечно по сути / 2 и * 2 — это бинарный сдвиг. но это только после компиляции с некоторыми оптимизациями, до этого момента это деление и умножение.
// lab6.cpp : Defines the entry point for the console application.
//
#include «stdafx.h»
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#include
using namespace std;
string encodeStr;
char ROR(unsigned char ch)
{
short byte = ch & 0x01;
char nchar = ch >> 1;
if(byte == 1)
nchar = nchar | 0x80;
return nchar;
}
char ROL(unsigned char ch)
{
short byte = ch & 0x80;
char nchar = ch << 1;
if(byte == 0x80)
nchar = nchar | 0x01;
return nchar;
}
short WriteBiteCode(string str, string filename, bool writeSkip = true)
{
ofstream outBin(filename, ios::binary | ios::out);
short offset = 0;
short byte = 0;
char ch = 0x00;
char skip = 0x00;
for(int i = 0; i < str.length(); i++, byte++)
{
if(byte == 8)
{
outBin.write((char*)&ch, sizeof(ch));
ch = 0x00;
byte = 0;
}
offset = (str.at(i) == '1') ? 1 : 0;
ch = ROL(ch);
ch = ch | offset;
}
for(int i = 0; i < 8 — byte; i++)
{
ch = ROL(ch);
ch = ch | 0;
}
outBin.write((char*)&ch, sizeof(ch));
if(writeSkip)
{
skip = (8 — byte) % 8 + 8;
outBin.write((char*)&skip, sizeof(skip));
}
outBin.close();
return (short)skip;
}
string ReadBiteCode(string filename)
{
string str = "";
ifstream in(filename, ios::binary | ios::in);
short skip;
char ch;
char k;
while(!in.eof())
{
in.read((char*)&ch, sizeof(ch));
if(in)
{
skip = ch;
for(int i = 0; i < 8; i++)
{
k = (((ch & 0x80) == 0x80) ? '1' : '0');
str.push_back(k);
ch = ROL(ch);
}
}
}
in.close();
return str.substr(0, str.length() — skip);
}
short GetBitChr(char ch, int number)
{
for(int i = 0; i > 1;
return (ch & 1);
}
short GetBitStr(string str, int number)
{
int num = floor((number — 1) / 8.0);
int index = ((number — 1) % 8) + 1;
return GetBitChr(str.at(num), index);
}
short GetBitInt(int n, int number)
{
for(int i = 0; i > 1;
return (n & 1);
}
string HammingDecode(string myStr = «»)
{
string str = (myStr.length() == 0) ? ReadBiteCode(«out.my») : myStr;
string decode;
map controlBits;
short skip;
int err = 0;
bool isValid = true;
int countControlBit = floor(log((double)str.length()) / log((double)2)) + 1;
int degree = 1;
for(int i = 0; i < countControlBit; ++i)
{
short controlBit = 0;
for(int j = 0; j < str.length(); ++j)
{
int num = j + 1;
if(GetBitInt(num, i) == 1 && str.at(j) == '1')
controlBit++;
}
controlBits[i] = controlBit % 2;
if(controlBits[i])
isValid = false;
err += controlBits[i] * pow(2.0, i);
}
for(int i = 0; i < str.length(); i++)
{
if(i + 1 == degree)
degree *= 2;
else
decode.push_back(str.at(i));
}
if(!isValid)
{
cout << "Error in " << err << " bit!" << endl;
str.at(err — 1) = (str.at(err — 1) == '1') ? '0' : '1';
decode = "";
degree = 1;
for(int j = 0; j < str.length(); ++j)
{
if(j + 1 == degree)
degree *= 2;
else
decode.push_back(str.at(j));
}
}
else
cout << endl << "True decode" << endl << endl;
//cout << "Decode: " << decode << endl;
WriteBiteCode(decode, "result_decode.txt", false);
return decode;
}
void HammingEncode(string str)
{
map controlBits;
char buffer [33];
int degree = 1;
int num = 1;
int countControl = 0;
for(int i = 0; i < str.length() * 8; ++i)
{
num = i + 1;
while(countControl + num == degree)
{
degree *= 2;
countControl++;
encodeStr.push_back('0');
}
encodeStr.push_back(GetBitStr(str, num) ? '1' : '0');
//cout << GetBitStr(str, num) ? '1' : '0';
}
cout << "Count control bit: " << countControl << endl << endl;
degree = 1;
for(int i = 0; i < countControl; ++i)
{
int number = i + 1;
short controlBit = 0;
for(int j = 0; j < encodeStr.length(); ++j)
{
num = j + 1;
if(GetBitInt(num, i) == 1 && encodeStr.at(j) == '1')
controlBit++;
}
controlBits[i] = controlBit % 2;
cout << "Control bit " << i << " = " << controlBits[i] << endl;
encodeStr.at(degree — 1) = controlBits[i] ? '1' : '0';
degree *= 2;
}
ofstream out("out.txt");
for(int i = 0; i < encodeStr.length(); i++)
out.put(encodeStr.at(i));
out.close();
WriteBiteCode(encodeStr, "out.my");
}
void main()
{
setlocale(0, "Russian");
//freopen("log.txt", "w+", stdout);
ifstream in("in.txt", ios::binary | ios::in);
ifstream inEncode("out.txt");
string str;
string strEncode;
char ch;
while(!in.eof())
{
in.read((char*)&ch, sizeof(ch));
if(in)
str.push_back(ch);
}
//HammingEncode(str);
HammingDecode();
/*
while(!inEncode.eof())
{
ch = inEncode.get();
if(inEncode)
strEncode.push_back(ch);
}
HammingDecode(strEncode);
*/
fstream compression("out.my", std::fstream::in);
compression.seekp(0, std::ios::end);
double sizeCompression = compression.tellp();
compression.close();
fstream source("in.txt", std::fstream::in);
source.seekp(0, std::ios::end);
double sizeSource = source.tellp();
source.close();
cout << "До кодирования: " << sizeSource << " байт" << endl;
cout << "После кодирования: " << sizeCompression << " байт" << " ( + " << ((sizeCompression — sizeSource) / sizeCompression) * 100 << " % )" << endl;
inEncode.close();
in.close();
return;
}