Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Битовая логика.docx
Скачиваний:
2
Добавлен:
11.07.2019
Размер:
122.24 Кб
Скачать

Реализация алгоритмов работы с целыми числами, представленными в виде строки на c#

Для сравнения приведем реализацию тех же самых алгоритмов на языке C# (версии 3.5)

class LongNumber {

private string num;

public LongNumber(string _num) {

Debug.Assert(_num != null);

num = _num;

}

public override string ToString() {

return num;

}

public static LongNumber operator +(LongNumber a, LongNumber b) {

var res = new LongNumber("");

var str1 = a.num;

var str2 = b.num;

str1 = str1.PadLeft(str2.Length, '0');

str2 = str2.PadLeft(str1.Length, '0');

var f = false;

for (var i = str1.Length - 1; i > -1; i--) {

var sum = Byte.Parse("" + str1[i]) + Byte.Parse("" + str2[i]);

if (f) {

sum++;

}

f = (sum > 9);

sum = sum % 10;

res.num = "" + sum + res.num;

}

if (f) {

res.num = "1" + res.num;

}

return res;

}

public static LongNumber operator *(LongNumber a, LongNumber b) {

var res = new LongNumber("0");

int offset = 0;

for (int i = b.num.Length - 1; i > -1; i--) {

var tempMul = new LongNumber(a.num);

var curVal = Int32.Parse("" + b.num[i]);

tempMul = tempMul*curVal;

for (int k = 0; k < offset; k++) {

tempMul.num = tempMul.num + "0";

}

offset++;

res = res + tempMul;

}

res.num = res.num.TrimStart('0');

if (res.num == "") {

res.num = "0";

}

return res;

}

public static LongNumber operator -(LongNumber a, LongNumber b) {

var s1 = a.num;

var s2 = b.num;

s1 = s1.PadLeft(s2.Length, '0');

s2 = s2.PadLeft(s1.Length, '0');

var res = "";

var f = false;

for (int i=s1.Length - 1;i>-1;i--) {

var n1 = Int32.Parse("" + s1[i]);

var n2 = Int32.Parse("" + s2[i]);

if (f) {

n1--;

}

var r = n1 - n2;

f = (r < 0);

if (f) {

r += 10;

}

res = "" + r + res;

}

res = res.TrimStart('0');

if (res == "") {

res = "0";

}

if (f) {

var tempStr = new String('0', res.Length);

tempStr = "1" + tempStr;

var l1 = new LongNumber(tempStr);

var l2 = new LongNumber(res);

res = (l1 - l2).num;

res = "-" + res;

}

return new LongNumber(res);

}

public int compare(LongNumber a) {

if (this.num.Length > a.num.Length) {

return 1;

}

if (this.num.Length < a.num.Length) {

return -1;

}

for (int i = 0; i < this.num.Length; i++) {

if (this.num[i] == a.num[i]) {

continue;

}

if (this.num[i] > a.num[i]) {

return 1;

}

return -1;

}

return 0;

}

public static LongNumber operator *(LongNumber a, int k) {

Debug.Assert(k > -1);

Debug.Assert(k < 10);

var res = new LongNumber("");

int f = 0;

for (int i = a.num.Length - 1; i > -1; i--) {

var sum = Int32.Parse("" + a.num[i]);

sum *= k;

sum += f;

f = sum / 10;

sum = sum % 10;

res.num = "" + sum + res.num;

}

if (f > 0) {

res.num = "" + f + res.num;

}

res.num = res.num.TrimStart('0');

if (res.num == "") {

res.num = "0";

}

return res;

}

}

Реализация алгоритмов работы с целыми числами, представленными в виде строки на C++

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

Для удобства реализации создан специальный класс CppString, который облегчает работу с динамической строкой.

Полный код реализации приведен ниже:

#pragma once

#include <assert.h>

class CppString {

public:

~CppString() {

if (data != NULL) {

delete data;

}

}

CppString() {

data = new char[1];

data[0] = 0;

}

int length() {

return strlen(data);

}

CppString(char *_data) {

int size = strlen(_data);

data = new char[size + 1];

memmove(data, _data, sizeof(char) * size + 1);

}

CppString(const CppString &_data) {

int size = strlen(_data.data);

data = new char[size + 1];

memmove(data, _data.data, sizeof(char) * size + 1);

}

void addCharToEnd(char newC) {

int oldSize = strlen(data);

char *newData = new char[oldSize + 2];

memmove(newData, data, oldSize * sizeof(char));

newData[oldSize] = newC;

newData[oldSize + 1] = 0;

if (data != NULL) {

delete data;

}

data = newData;

}

char getChar(int index) {

assert(data != NULL);

assert(index > -1);

assert(index < strlen(data));

return data[index];

}

void print() {

if (data == NULL) {

printf("%s\n", "String is empty");

} else {

printf("%s\n", data);

}

}

void delCharFromStart() {

int oldSize = strlen(data);

char *newData = new char[oldSize ];

memmove(newData, &data[1], oldSize * sizeof(char));

if (data != NULL) {

delete data;

}

data = newData;

}

void addCharToStart(char newC) {

int oldSize = strlen(data);

char *newData = new char[oldSize + 2];

memmove(&newData[1], data, oldSize * sizeof(char));

newData[0] = newC;

newData[oldSize + 1] = 0;

if (data != NULL) {

delete data;

}

data = newData;

}

CppString operator + (const char &newChar) {

CppString res = CppString(*this);

res.addCharToEnd(newChar);

return CppString(res);

}

friend CppString operator + (const char &newCgar, const CppString &right);

CppString operator + (const CppString &left) {

CppString res;

int sizeRight = strlen(data);

int sizeLeft = strlen(left.data);

int sumSize = sizeLeft + sizeRight + 1;

res.data = new char[sumSize];

memmove(res.data, data, sizeof(char) * sizeRight);

memmove(&res.data[sizeRight], left.data, sizeof(char) * sizeLeft);

res.data[sizeLeft + sizeRight] = 0;

return CppString(res.data);

}

CppString operator = (const CppString &left) {

if (this == &left) {

return *this;

}

if (data != NULL) {

delete data;

}

int size = strlen(left.data) + 1;

data = new char[size];

memmove(data, left.data, size * sizeof(char));

return *this;

}

private:

char *data;

};

class NumberWorker {

public:

static CppString getSum(const CppString &right, const CppString &left) {

CppString a = right;

CppString b = left;

while (a.length() < b.length()) {

a = '0' + a;

}

while (b.length() < a.length()) {

b = '0' + b;

}

CppString res;

bool f = false;

for (int i = a.length() - 1; i > -1; i--) {

char ca = a.getChar(i) - '0';

char cb = b.getChar(i) - '0';

char c = ca + cb;

if (f) {

c++;

}

f = (c > 9);

if (c > 9) {

c -= 10;

}

res = (c + '0') + res;

}

if (f) {

res = '1' + res;

}

return CppString(res);

}

static int compare(CppString &right, CppString &left) {

if (right.length() > left.length()) {

return 1;

}

if (right.length() < left.length()) {

return -1;

}

for (int i = 0; i < right.length(); i++) {

if (right.getChar(i) == left.getChar(i)) {

continue;

}

return (right.getChar(i) - left.getChar(i));

}

return 0;

}

static CppString getMul(CppString &right, int k) {

char f = 0;

CppString res;

for (int i = right.length() - 1; i > -1; i--) {

char curVal = right.getChar(i) - '0';

curVal *= k;

curVal += f;

f = (curVal / 10);

curVal = curVal % 10;

res = (curVal + '0') + res;

}

if (f != 0) {

res = (f + '0') + res;

}

return CppString(res);

}

static CppString getMul(CppString &right, CppString &left) {

CppString res;

int offset = 0;

for (int i = left.length() - 1; i > -1; i--) {

char curChar = left.getChar(i) - '0';

CppString curMul = getMul(right, curChar);

for (int i = 0; i < offset; i++) {

curMul = curMul + '0';

}

offset++;

res = getSum(res, curMul);

}

return CppString(res);

}

static CppString getSub(const CppString &right, const CppString &left) {

CppString s1 = right;

CppString s2 = left;

while (s1.length() < s2.length()) {

s1 = '0' + s1;

}

while (s2.length() < s1.length()) {

s2 = '0' + s2;

}

CppString res;

bool flag = false;

for (int i = s1.length() - 1; i > -1; i--) {

char n1 = s1.getChar(i) - '0';

char n2 = s2.getChar(i) - '0';

if (flag) {

n1--;

}

char r = n1 - n2;

flag = (r < 0);

if (flag) {

r = r + 10;

}

res = (r + '0') + res;

}

while ((res.length() > 1) && (res.getChar(0) == '0')) {

res.delCharFromStart();

}

if (flag) {

CppString tempStr("1");

while (tempStr.length() <= res.length()) {

tempStr = tempStr + '0';

}

res = getSub(tempStr, res);

res = '-' + res;

}

return CppString(res);

}

};

CppString operator + (const char &newChar, const CppString &right) {

CppString res(right);

res.addCharToStart(newChar);

return CppString(res);

}

1 Порядок от младшего к старшему принят в памяти персональных компьютеров с x86-процессорами, в связи с чем, иногда, его называют интеловский порядок байтов (по названию фирмы-создателя архитектуры x86).

2 Этот порядок является стандартным для протоколов TCP/IP, он используется в заголовках пакетов данных и во многих протоколах более высокого уровня, разработанных для использования поверх TCP/IP. Поэтому, порядок байтов от старшего к младшему часто называют сетевым порядком байтов (англ. network byte order). Этот порядок байтов используется процессорами IBM 360/370/390, Motorola 68000, SPARC (отсюда третье название — порядок байтов Motorola, Motorola byte order)

48