How to Selection Sort some structs - c++

I have to put in order some files sorting by year(ano), month(mes), day(dia) but i could only sort by year.
struct registro{
short ano;
char mes;
char dia;
char hora;
char min;
char seg;
};
void selectionSort(struct registro *dados, int n){
int i, j, menor;
struct registro aux;
for(i = 0; i < n - 1; i++){
menor = i;
for(j = i + 1; j < n; j++){
if(dados[menor].ano > dados[j].ano)
{
menor = j;
}
if(i != menor){
aux = dados[i];
dados[i] = dados[menor];
dados[menor] = aux;
}
}
}
}

Check signarturee of standard C library qsort function
void qsort (void* base, size_t num, size_t size,
int (*compar)(const void*,const void*));
As you can see the last parameter is a pointer to a function (callback) which is used to compare values. You are using fixed gretter operator dados[menor].ano > dados[j].ano in your selectionSort. In order to make it generic you can make next modification:
static registroYearCmp(struct registro* lhs, struct registro *rhs)
{
return lhs->ano - rhs->ano;
}
static registroMonthCmp(struct registro* lhs, struct registro *rhs)
{
return lhs->mes - rhs->mes;
}
static registroDayCmp(struct registro* lhs, struct registro *rhs)
{
return lhs->dia - rhs->dia;
}
void selectionSort(struct registro *dados, int n, *(compare_registro)(struct registro*, struct registro*) ){
......
if( compare_registro(dados[menor],dados[j]) > 0 )
......
}
.......
/* Sort by year */
selectionSort(dados, 16, registroYearCmp);
/* Sort by month */
selectionSort(dados, 16, registroMonthCmp);
/* Sort by day */
selectionSort(dados, 16, registroDayCmp);

Related

How do I cast a typename variable parameter as a string

The problem: I am trying to create a function capable of finding the largest number if the array is an integer, double, float, etc. If the array given is a string it returns the string in the string with the most letters. However, I don't know how to cast list [0] and list[i] as strings.
#include <isostream>
#include <algorithm>
using namespace std;
unsigned int strlength(string word) {
char *ch = &word[0];
unsigned int count = 0;
while (*ch != '\0') {
count++;
ch++;
}
return *count;
}
template<typename U>
U maxNumber(U list[], int size) {
unsigned int i;
if (typeid(list) == typeid(string*)) {
unsigned int i;
for (i = 0; i < size; i++) {
if (strlength(list[0]) < strlength(list[i])) {
list[0] = list[i];
}
else {
list[0] = list[0];
}
}
return list[0];
}
else {
for (i = 0; i < size; i++) {
if (list[0] < list[i]) {
list[0] = list[i];
}
else {
continue;
}
}
return list[0];
}
}
if (typeid(list) == typeid(string*)) is the wrong tool.
You need compile time branch,
either with if constexpr
template<typename U>
U maxNumber(U list[], int size) {
if constexpr (std::is_same_v<U, std::string>) {
auto less_by_size = [](const auto& lhs, const auto rhs){
return lhs.size() < rhs.size(); };
return *std::max_element(list, list + size, less_by_size);
} else {
return *std::max_element(list, list + size);
}
}
or via overload/tag dispatching
std::string maxNumber(std::string list[], int size) {
auto less_by_size = [](const auto& lhs, const auto rhs){
return lhs.size() < rhs.size(); };
return *std::max_element(list, list + size, less_by_size);
}
template<typename U>
U maxNumber(U list[], int size) {
return *std::max_element(list, list + size);
}

C++ CycleBuffer unit test fail reason?

I have implement my CycleBuffer and run some unit tests. But it fails on a random read/write operation and I cannot find out why. Please help me. I use C++ 14 standard.
My CycleBuffer rely on libfmt and Catch2.
CycleBuffer.h
// Copyright 2019- <shepherd-lang>
// Apache License Version 2.0
#pragma once
#include <cstdio>
namespace detail {
/**
* CycleBuffer memory status
*
* positive: tail >= head
* 1)
* buf = head = tail = nullptr
*
* 2)
* head tail
* | |
* |-----------------------||
* |
* buf
*
* 3)
* head
* |
* |---------||-------------|
* | |
* buf tail
*
* 4)
* head tail
* | |
* |----|---------------|---|
* |
* buf
*
* negative: tail < head
* 1)
* tail head
* | |
* |----|---------------|---|
* |
* buf
*
* 2)
* tail head
* | |
* |----------------|-------|
* |
* buf
*
* 3)
* tail head
* | |
* |----|------------------||
* |
* buf
*
* 4)
* tail head
* | |
* |-----------------------||
* |
* buf
*
* impossible)
* tail head
* | |
* |------------------------|
* |
* buf
*/
template <unsigned int D> class CycleBuffer {
public:
CycleBuffer();
virtual ~CycleBuffer();
virtual int capacity() const;
virtual int size() const;
virtual bool empty() const;
virtual bool full() const;
virtual void reset();
// next position start from <position>
virtual char *next(char *position, int distance = 1) const;
virtual const char *next(const char *position, int distance = 1) const;
// previous position start from <position>
virtual char *prev(char *position, int distance = 1) const;
virtual const char *prev(const char *position, int distance = 1) const;
virtual char *begin();
virtual const char *begin() const;
virtual char *rbegin();
virtual const char *rbegin() const;
virtual char *end();
virtual const char *end() const;
virtual char *rend();
virtual const char *rend() const;
virtual bool contain(const char *position) const;
virtual std::string toString() const;
// write at most <n> bytes to <buf>
// #return bytes really write
virtual int write(char *buf, int n);
// read at most <n> bytes from <buf>
// #return bytes really read
virtual int read(const char *buf, int n);
// write all bytes to <fp>
// #return bytes really write
virtual int writefile(FILE *fp);
// write at most <n> bytes to <fp>
virtual int writefile(FILE *fp, int n);
// read all bytes from <fp>
// #return bytes really read
virtual int readfile(FILE *fp);
// read at most <n> bytes from <fp>
// #return bytes really read
virtual int readfile(FILE *fp, int n);
protected:
virtual char *nextImpl(char *position, int distance = 1) const;
virtual char *prevImpl(char *position, int distance = 1) const;
virtual void release();
virtual int expand(int n);
virtual char *bufEnd();
virtual const char *bufEnd() const;
// if positive direction
virtual bool positive() const;
// positive direction
virtual long pSize() const;
virtual bool pContain(const char *position) const;
// negative direction
virtual long nLeftSize() const;
virtual long nRightSize() const;
virtual bool nLeftContain(const char *position) const;
virtual bool nRightContain(const char *position) const;
virtual int writeImpl(void *src, int n,
int (*writeHandler)(void *, void *, int));
virtual int readImpl(void *src, int n,
int (*readHandler)(void *, void *, int, int));
char *buf_;
char *head_;
char *tail_;
int capacity_;
};
} // namespace detail
class DynamicBuffer : public detail::CycleBuffer<1> {
public:
DynamicBuffer(int capacity = 0);
virtual ~DynamicBuffer() = default;
virtual std::string toString() const;
};
class FixedBuffer : public detail::CycleBuffer<0> {
public:
FixedBuffer(int capacity);
virtual ~FixedBuffer() = default;
virtual std::string toString() const;
};
CycleBuffer.cpp
// Copyright 2019- <shepherd-lang>
// Apache License Version 2.0
#include "CycleBuffer.h"
#include "fmt/format.h"
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <tuple>
#define ALIGN(n) (n < 8 ? 8 : (n % 8 == 0 ? n : ((n / 8 + 1) * 8)))
#define MIN(a, b) (std::min<int>(a, b))
#define BUF_SIZE 1024
namespace detail {
template <unsigned int D> char *CycleBuffer<D>::bufEnd() {
return buf_ + capacity_;
}
template <unsigned int D> const char *CycleBuffer<D>::bufEnd() const {
return buf_ + capacity_;
}
// is positive direction
template <unsigned int D> bool CycleBuffer<D>::positive() const {
return tail_ >= head_;
}
template <unsigned int D> long CycleBuffer<D>::pSize() const {
return tail_ - head_;
}
template <unsigned int D>
bool CycleBuffer<D>::pContain(const char *position) const {
return position >= head_ && position < tail_;
}
template <unsigned int D> long CycleBuffer<D>::nLeftSize() const {
return tail_ - buf_;
}
template <unsigned int D> long CycleBuffer<D>::nRightSize() const {
return bufEnd() - head_;
}
template <unsigned int D>
bool CycleBuffer<D>::nLeftContain(const char *position) const {
return position >= buf_ && position < tail_;
}
template <unsigned int D>
bool CycleBuffer<D>::nRightContain(const char *position) const {
return position >= head_ && position < bufEnd();
}
template <unsigned int D>
CycleBuffer<D>::CycleBuffer()
: buf_(nullptr), head_(nullptr), tail_(nullptr), capacity_(0) {}
template <unsigned int D> CycleBuffer<D>::~CycleBuffer() { reset(); }
template <unsigned int D> int CycleBuffer<D>::capacity() const {
return capacity_ > 0 ? capacity_ - 1 : 0;
}
template <unsigned int D> int CycleBuffer<D>::size() const {
return positive() ? pSize() : (nLeftSize() + nRightSize());
}
template <unsigned int D> bool CycleBuffer<D>::empty() const {
return size() == 0;
}
template <unsigned int D> bool CycleBuffer<D>::full() const {
return size() == capacity();
}
template <unsigned int D> void CycleBuffer<D>::reset() {
release();
head_ = nullptr;
tail_ = nullptr;
capacity_ = 0;
}
template <unsigned int D>
char *CycleBuffer<D>::nextImpl(char *position, int distance) const {
if (position == end() || !position) {
return (char *)end();
}
char *np = position + distance;
if (positive()) {
return np > tail_ ? (char *)end() : np;
} else {
if (nLeftContain(position)) {
return np > tail_ ? (char *)end() : np;
} else {
if (np < bufEnd()) {
return np;
}
np = (char *)buf_ + (distance - (bufEnd() - position));
return np > tail_ ? (char *)end() : np;
}
}
}
template <unsigned int D>
char *CycleBuffer<D>::next(char *position, int distance) const {
return nextImpl(position, distance);
}
template <unsigned int D>
const char *CycleBuffer<D>::next(const char *position, int distance) const {
return nextImpl((char *)position, distance);
}
template <unsigned int D>
char *CycleBuffer<D>::prevImpl(char *position, int distance) const {
if (position == rend() || !position) {
return (char *)rend();
}
char *np = position - distance;
if (positive()) {
return np < head_ ? (char *)rend() : np;
} else {
if (nLeftContain(position)) {
if (np >= buf_) {
return np;
}
np = (char *)bufEnd() - (distance - (position - buf_));
return np < head_ ? (char *)rend() : np;
} else {
return np < head_ ? (char *)rend() : np;
}
}
}
template <unsigned int D>
char *CycleBuffer<D>::prev(char *position, int distance) const {
return prevImpl(position, distance);
}
template <unsigned int D>
const char *CycleBuffer<D>::prev(const char *position, int distance) const {
return prevImpl((char *)position, distance);
}
template <unsigned int D> char *CycleBuffer<D>::begin() { return head_; }
template <unsigned int D> const char *CycleBuffer<D>::begin() const {
return head_;
}
template <unsigned int D> char *CycleBuffer<D>::rbegin() {
return tail_ == buf_ ? bufEnd() - 1 : tail_ - 1;
}
template <unsigned int D> const char *CycleBuffer<D>::rbegin() const {
return tail_ == buf_ ? bufEnd() - 1 : tail_ - 1;
}
template <unsigned int D> char *CycleBuffer<D>::end() { return tail_; }
template <unsigned int D> const char *CycleBuffer<D>::end() const {
return tail_;
}
template <unsigned int D> char *CycleBuffer<D>::rend() { return head_ - 1; }
template <unsigned int D> const char *CycleBuffer<D>::rend() const {
return head_ - 1;
}
template <unsigned int D>
bool CycleBuffer<D>::contain(const char *position) const {
return positive() ? pContain(position)
: (nLeftContain(position) || nRightContain(position));
}
template <unsigned int D> std::string CycleBuffer<D>::toString() const {
return fmt::format("buf_:{}, head_:{}, tail_:{}, capacity_:{}", (void *)buf_,
(void *)head_, (void *)tail_, capacity_);
}
template <unsigned int D> void CycleBuffer<D>::release() {
if (buf_) {
std::free(buf_);
buf_ = nullptr;
}
}
static int writeMemHandler(void *src, void *buf, int n) {
std::memcpy(src, buf, n);
return n;
}
static int writeFileHandler(void *src, void *buf, int n) {
size_t r = std::fwrite(buf, 1, n, (FILE *)src);
return (int)r;
}
#define WINC(n) \
do { \
head_ = next(head_, n); \
writen += n; \
} while (0)
template <unsigned int D>
int CycleBuffer<D>::writeImpl(void *src, int n,
int (*writeHandler)(void *, void *, int)) {
EX_ASSERT(n >= 0, "n {} < 0", n);
if (!src || !n) {
return 0;
}
if (empty()) {
return 0;
}
int writen = 0;
if (positive()) {
int fn = MIN(size(), n);
int fnr = writeHandler(src, head_, fn);
WINC(fnr);
} else {
int fn = MIN(bufEnd() - head_, n);
int fnr = writeHandler(src, head_, fn);
WINC(fnr);
if (n > writen) {
int sn = MIN(n - writen, pSize());
int snr = writeHandler(src, head_, sn);
WINC(snr);
}
}
return writen;
}
template <unsigned int D> int CycleBuffer<D>::write(char *buf, int n) {
return writeImpl(buf, n, writeMemHandler);
}
template <unsigned int D> int CycleBuffer<D>::writefile(FILE *fp, int n) {
return writeImpl(fp, n, writeFileHandler);
}
template <unsigned int D> int CycleBuffer<D>::writefile(FILE *fp) {
int n = 0;
int tmp;
do {
tmp = writefile(fp, BUF_SIZE);
n += tmp;
} while (tmp > 0);
return n;
}
#define RINC(n) \
do { \
tail_ += n; \
readn += n; \
} while (0)
static int readMemHandler(void *src, void *buf, int n, int readn) {
char *src2 = (char *)src + readn;
std::memcpy(buf, src2, n);
return n;
}
static int readFileHandler(void *src, void *buf, int n, int readn) {
size_t r = std::fread(buf, 1, n, (FILE *)src);
return (int)r;
}
template <unsigned int D>
int CycleBuffer<D>::readImpl(void *src, int n,
int (*readHandler)(void *, void *, int, int)) {
if (!src || !n) {
return 0;
}
if (D) {
if (capacity() - size() < n) {
int c1 = capacity() + n + 1;
int c2 = capacity() * 2 + 1;
expand(c1 > c2 ? ALIGN(c1) : ALIGN(c2));
}
}
if (full()) {
return 0;
}
int readn = 0;
if (positive()) {
int fn = MIN(bufEnd() - tail_ - (head_ == buf_ ? 1 : 0), n);
int fnr = readHandler(src, tail_, fn, readn);
RINC(fnr);
if (tail_ == bufEnd()) {
tail_ = buf_;
}
if (n > readn && head_ != buf_) {
int sn = MIN(n - readn, head_ - tail_ - 1);
int snr = readHandler(src, tail_, sn, readn);
RINC(snr);
}
} else {
int fn = MIN(n, head_ - tail_ - 1);
int fnr = readHandler(src, tail_, fn, readn);
RINC(fnr);
}
return readn;
}
template <unsigned int D> int CycleBuffer<D>::read(const char *buf, int n) {
return readImpl((void *)buf, n, readMemHandler);
}
template <unsigned int D> int CycleBuffer<D>::readfile(FILE *fp, int n) {
return readImpl(fp, n, readFileHandler);
}
template <unsigned int D> int CycleBuffer<D>::readfile(FILE *fp) {
int n = 0;
int tmp;
do {
tmp = readfile(fp, BUF_SIZE);
n += tmp;
} while (tmp > 0);
return n;
}
template <unsigned int D> int CycleBuffer<D>::expand(int n) {
if (n <= capacity_) {
return 0;
}
char *newbuf = (char *)std::malloc(n);
if (!newbuf) {
return -1;
}
int sz = size();
if (positive()) {
std::memcpy(newbuf, head_, pSize());
} else {
std::memcpy(newbuf, head_, nRightSize());
std::memcpy(newbuf + nRightSize(), buf_, nLeftSize());
}
release();
buf_ = newbuf;
capacity_ = n;
head_ = buf_;
tail_ = buf_ + sz;
return 0;
}
} // namespace detail
DynamicBuffer::DynamicBuffer(int capacity) {
if (capacity > 0) {
expand(ALIGN(capacity + 1));
}
}
std::string DynamicBuffer::toString() const {
return fmt::format("[#DynamicBuffer {}]", detail::CycleBuffer<1>::toString());
}
FixedBuffer::FixedBuffer(int capacity) {
if (capacity > 0) {
// precise capacity
expand(capacity + 1);
}
}
std::string FixedBuffer::toString() const {
return fmt::format("[#FixedBuffer {}]", detail::CycleBuffer<0>::toString());
}
CycleBufferTest.cpp
// Copyright 2019- <shepherd-lang>
// Apache License Version 2.0
#include "CycleBuffer.h"
#include "catch2/catch.hpp"
#include "fmt/format.h"
#include <algorithm>
#include <cstdlib>
#define C_MIN 0
#define C_MAX 100
#define RAND (rand() % (C_MAX + 1))
TEST_CASE("container/CycleBuffer", "[container/CycleBuffer]") {
SECTION("random read/write") {
{
std::vector<char> v;
DynamicBuffer db;
int rc = 0, wc = 0;
for (int i = C_MIN; i < C_MAX; i++) {
int rn = RAND;
std::vector<char> rbuf(rn);
for (int j = 0; j < rn; j++) {
rbuf[j] = (char)rn;
v.push_back(rbuf[j]);
rc++;
LOG_INFO("DynamicBuffer random rbuf[{}]:{}", rc, (int)rbuf[j]);
}
REQUIRE(db.read(rbuf.data(), rn) == rn);
int wn = std::min(RAND, rn);
std::vector<char> wbuf(wn);
REQUIRE(db.write(wbuf.data(), wn) == wn);
for (int j = 0; j < wn; j++) {
LOG_INFO("DynamicBuffer random wbuf[{}]:{}", wc, (int)wbuf[j]);
if (wbuf[j] != v[wc]) {
LOG_INFO("DynamicBuffer random wbuf[{}]:{}", wc, (int)wbuf[j]); // here's the error place!
}
REQUIRE(wbuf[j] == v[wc]);
wc++;
}
}
}
}
}

Using array instead of set<string>

This is a function for finding all Longest common sequence for X and Y sequence.
But this program is in c++ but I want to write it in C.
Is there any way to use array instead of the set?
For eg. if input is
X = < A, A, T, C, C, >
Y = < A, C, A, C, G, >
then the output should be
< A, C, C, >
< A, A, C, >
m and n are size of sequence X and Y respectively.
/* source : https://www.geeksforgeeks.org/printing-longest-common-subsequence-set-2-printing/ */
/* Returns set containing all LCS for X[0..m-1], Y[0..n-1] */
set<string> findLCS(string X, string Y, int m, int n)
{
// construct a set to store possible LCS
set<string> s;
// If we reaches end of either string, return
// a empty set
if (m == 0 || n == 0)
{
s.insert("");
return s;
}
// If the last characters of X and Y are same
if (X[m - 1] == Y[n - 1])
{
// recurse for X[0..m-2] and Y[0..n-2] in
// the matrix
set<string> tmp = findLCS(X, Y, m - 1, n - 1);
// append current character to all possible LCS
// of substring X[0..m-2] and Y[0..n-2].
for (string str : tmp)
s.insert(str + X[m - 1]);
}
// If the last characters of X and Y are not same
else
{
// If LCS can be constructed from top side of
// the matrix, recurse for X[0..m-2] and Y[0..n-1]
if (L[m - 1][n] >= L[m][n - 1])
s = findLCS(X, Y, m - 1, n);
// If LCS can be constructed from left side of
// the matrix, recurse for X[0..m-1] and Y[0..n-2]
if (L[m][n - 1] >= L[m - 1][n])
{
set<string> tmp = findLCS(X, Y, m, n - 1);
// merge two sets if L[m-1][n] == L[m][n-1]
// Note s will be empty if L[m-1][n] != L[m][n-1]
s.insert(tmp.begin(), tmp.end());
}
}
return s;
}
Here is an example for a self-made C unordered_set using arrays.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Buckets 1000
struct Node {
char *key;
struct Node *next;
};
void initNode(struct Node **node, const char *str) {
*node = (struct Node *) malloc(sizeof(struct Node));
size_t l = strlen(str);
(*node)->key = (char *) malloc(l * sizeof(char));
strncpy((*node)->key, str, l);
(*node)->next = NULL;
}
void freeNode(struct Node *node) {
if (node->next) {
freeNode(node->next);
}
free(node->key);
free(node);
}
struct Set {
struct Node *buckets[Buckets];
};
void initSet(struct Set *set) {
for (unsigned int i = 0; i < Buckets; ++i) {
set->buckets[i] = NULL;
}
}
void freeSet(struct Set *set) {
for (unsigned int i = 0; i < Buckets; ++i) {
if (set->buckets[i]) {
free(set->buckets[i]);
}
}
}
unsigned int hash(const char *str) {
unsigned int sum = 0;
for (; *str; ++str) {
sum += *str;
}
return sum % Buckets;
}
int insert(struct Set *set, const char *str) {
const unsigned int h = hash(str);
if (!set->buckets[h]) {
initNode(&set->buckets[h], str);
return 1;
}
struct Node *node = set->buckets[h];
while (node->next && strcmp(str, node->key)) node = node->next;
if (!strcmp(str, node->key)) return 0;
initNode(&node->next, str);
return 1;
}
int main() {
struct Set set;
initSet(&set);
printf("%d", insert(&set, "Text"));
printf("%d", insert(&set, "Text2"));
printf("%d", insert(&set, "Text"));
freeSet(&set);
}

Rabin Karp using linear hash

For course I am taking I need to implement the Rabin-Karp string search algorithm, with different hash implementation. First I have done a rolling hash and that works just fine. Problem is when it comes to linear and separate chaining hash. I have made a linear hash header file and for primary hash methods it works Ok, also I have written a Rabin-Karp algorithm that works with other versions of hash. But now I do not know how to put this two together.
Here is what I have written by now
hash.h
#ifndef HASH_H
#define HASH_H
#include <vector>
using namespace std;
template <typename Tip>
class Hash {
struct Element {
int key;
Tip value;
int mark; //0 free, 1 occupied, 2 was occupied
Element(int key = 0, Tip value = Tip(), int mark = 1):key(key),value(value),mark(mark){}
};
int h1(int key) {
return key%capacity;
}
int h2(int key) {
return 2*(key%5) + 1;
}
int capacity;
int no_of_elements;
const double factor_of_full;
vector<Element> Tabel;
public:
Hash():capacity(128),no_of_elements(0),factor_of_full(0.5){
Tabel.resize(capacity);
for(int i=0;i<capacity;i++)
Tabel[i].mark = 0;
}
void Insert(pair<int,Tip> element);
Tip Find(int key);
void Delete(int key);
};
template <typename Tip>
void Hash<Tip>::Insert(pair<int,Tip> element) {
if((double(no_of_elements+1))/capacity>factor_of_full) {
vector<Element> coppy = Tabel;
capacity*=2;
Tabel.resize(capacity);
no_of_elements = 0;
for(int i=0;i<Tabel.size();i++)
Tabel[i].mark = 0;
for(int i=0;i<coppy.size();i++)
if(coppy[i].mark == 1)
Insert({coppy[i].key,coppy[i].value});
}
int index = h1(element.first);
while(Tabel[index].mark == 1)
index = (index + h2(element.first))%capacity;
Tabel[index] = Element(element.first,element.second);
no_of_elements++;
}
template <typename Tip>
Tip Hash<Tip>::Find(int key) {
int index = h1(key);
for(int i=0;i<capacity;i++) {
if(Tabel[index].mark == 0)
break;
if(Tabel[index].mark == 1 && Tabel[index].key == key)
return Tabel[index].value;
else index = (index+h2(key))%capacity;
}
return Tip();
}
template <typename Tip>
void Hash<Tip>::Delete(int key) {
int index = h1(key);
for(int i=0;i<capacity;i++) {
if(Tabel[index].mark == 0)
return;
if(Tabel[index].mark == 1 && Tabel[index].key == key) {
Tabel[index].mark = 2;
no_of_elements--;
}
else index = (index+h2(key))%capacity;
}
return;
}
#endif // HASH_H
Rabin_Karp.cpp
#include <bits/stdc++.h>
#include "hash.h"
using namespace std;
const int P_B= 227;
const int P_M = 1000005;
int rabin_karp(const string& n, const string& find) {
int h1 = Hash(n);
int h2 = 0;
int pow = 1;
for (int i = 0; i < n.size(); i++)
pow = (pow * P_B) % P_M;
for (int i = 0; i < find.size(); i++) {
h2 = h2*P_B + find[i];
h2 %= P_M;
if (i >= n.size()) {
h2 -= pow * find[i-n.size()] % P_M;
if (h2 < 0)
h2 += P_M;
}
if (i >= n.size()-1 && h1 == h2)
return i - (n.size()-1);
}
return -1;
}

How do I interface a merge_sort algorithm to Vector and a user defined dynamic_array? - to_do

I want to take this merge_sort I wrote and put it into a class. Because their is some coupling of the variables, particularly - left, right_begin, right...I want to make these class members. The variables that are local to each function I will leave as local function variables.
Also this function will be used for another class I have called dynamic_array which is a bit more efficient than vector. However I want to make it available to the STL vector as well.
How do I do this. Do I use inheritance? Do I make the class a composite class of my dynamic_array...If I do this it will not be available to vector though.
The Question:
How do I make my merge_sort class interface with the STL container Vector and to my own container dynamic_array.
This is for an interview preparation.
Thank you. Dynamic Array code below(remove old merge_sort cold)
Merge Sort Code - to be converted to a class
#include <iostream>
using namespace std;
const int size=8;
int scratch[size],array[size]={6,5,3,1,8,7,2,4};
void print_array(int arr[]){ for (int i = 0; i < size; i++) cout << arr[i] << endl;}
void flip_if_unordered(int &x, int &y)
{
if(array[x]>array[y])
{
int tmp = array[x];
array[x] = array[y];
array[y] = tmp;
}
}
void merge_algo(int &left, int &right_begin, int &right)
{
int iter,iter_left=left,iter_right=right_begin;
for(iter=left;iter<=right;++iter)
{
if( (iter_right>right) || ((iter_left < right_begin) && (array[iter_left]<=array[iter_right])))
{
scratch[iter]=array[iter_left];
++iter_left;
}
else
{
scratch[iter]=array[iter_right];
++iter_right;
}
}
for(iter=left;iter<=right;++iter){array[iter]=scratch[iter];}
}
void merge_recurse(int left,int right)
{
int left_end=(left+((right-left)/2));
int right_begin=left_end+1;
if(((left+1)==right)){flip_if_unordered(left,right);return;}
else if ((left==right)){return;}
else
{
merge_recurse(left,left_end);
merge_recurse(right_begin,right);
merge_algo(left,right_begin,right);
}
}
int main()
{
merge_recurse(0,(size-1));
print_array(array);
return 0;
}
Dynamic Array
#include "c_arclib.cpp"
using namespace std;
template <class T> class dynamic_array
{
private:
T* array;
T* scratch;
void merge_recurse(int left, int right)
{
if(right == left + 1)
{
return;
}
else
{
int i = 0;
int length = right-left;
int midpoint_distance = length/2;
int l = left, r = left + midpoint_distance;
merge_recurse(left, left + midpoint_distance);
merge_recurse(left + midpoint_distance, right);
for(i = 0; i < length; i++)
{
if((l < (left + midpoint_distance)) && (r == right || array[l] > array[r]))
{
scratch[i] = array[l];
l++;
}
else
{
scratch[i] = array[r];
r++;
}
}
for(i = left; i < right; i++)
{
array[i] = scratch[i - left];
}
}
}
void quick_recurse(int left, int right)
{
int l = left, r = right, tmp;
int pivot = array[(left + right) / 2];
while (l <= r)
{
while (array[l] < pivot)l++;
while (array[r] > pivot)r--;
if (l <= r)
{
tmp = array[l];
array[l] = array[r];
array[r] = tmp;
l++;
r--;
}
}
if (left < r)quick_recurse(left, r);
if (l < right)quick_recurse(l, right);
}
public:
int size;
void rorder();
void order();
void randorder();
dynamic_array(int sizein)
{
size=sizein;
array=new T[size]();
}
void print_operator(std::ostream &os = cout) const
{
for (int i = 0; i < size; i++) os << array[i] << endl;
}
int merge_sort()
{
scratch = new T[size]();
if(scratch != NULL)
{
merge_recurse(0, size);return 1;
}
else{return 0;}
}
void quick_sort()
{
quick_recurse(0,size);
}
};
template <class T> void dynamic_array<T>::randorder()
{
srand(time(NULL));
int *ap;
for(ap=array;ap!=array+size;++ap){*ap=rand();}
}
template <class T> void dynamic_array<T>::order()
{
int *ap,i=0;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
++i;
}
}
template <class T> void dynamic_array<T>::rorder()
{
int *ap,i=size;
for(ap=array;ap!=array+size;++ap)
{
*ap=i;
--i;
}
}
template<class T> ostream& operator<<(ostream& stream, dynamic_array<T> const& data)
{
data.print_operator(stream);
return stream;
}
int main()
{
dynamic_array<int> d1(10);
d1.order();
cout << d1;
/*
clock_t time_start=clock();
d1.merge_sort();
clock_t time_end=clock();
double result = (double)(time_end - time_start) / CLOCKS_PER_SEC;
cout << result;
cout << d1;
*/
}
Just make it a template. You need 2 template parameter, the type of the elements, and the type of the container.
Tipp: if you want to use the class "like a function" define the operator ()
template<class _Item, class _Container> MergeSort
{
...
operator () (_Container & C);
...
}
now you can use C[] and to access elemets for any class that defines operator [], and you can use the size() function with any class that has it. You only have to add them to your dynamic_array class, and you can use MergeSort<int, vector<int> > with vectors, and MergeSort<int, dynamic_array<int> > with dynamic arrays.