Converting 1D to 2D? - c++

This might seem like a stupid question but it's really bugging me.
Basically, I have a 1D array that I need to convert into a 2D array. Basically, the size of the array is: 62017 now from this, I need to get the Rows and Cols of this. But, do this dynamically, so for example, it would take the number of say: 43101 and then establish the rows+cols and then re-size the vector accordingly.
I hope I've explained enough and hope someone can help, thanks :)

And here it is old school array style (since I can't access a C++0x compiler at the moment)
#include <iostream>
//#include <array>
#include <inttypes.h>
#include <math.h>
void calc_new_sizes(const size_t old_size, size_t& new_size1, size_t& new_size2)
{
new_size1 = 1;
new_size2 = 1;
size_t stop_at = (size_t)sqrt(old_size) + 1;
for (size_t i = 1; i<stop_at; i++)
{
if ( old_size % i == 0 )
{
new_size1 = i;
new_size2 = old_size / i;
}
}
}
template <class T>
T** twoDimensionify(T* p_old_array, const size_t old_size)
{
size_t new_size1=1, new_size2=1, old_i=0;
calc_new_sizes(old_size, new_size1, new_size2);
T** returnValue = new T*[new_size1];
for (size_t i=0; i<new_size1; i++)
{
returnValue[i] = new T[new_size2];
for (size_t j=0; j<new_size2; j++)
{
returnValue[i][j] = p_old_array[old_i];
old_i++;
}
}
return returnValue;
}
int main()
{
size_t old_size=20, new_size1=0, new_size2=0;
calc_new_sizes(old_size, new_size1, new_size2);
std::cout << "From " << old_size << " to " << new_size1 << "x" << new_size2 << std::endl;
int old_array[20] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int **new_array = twoDimensionify<int>(old_array, 20);
for (size_t i=0; i<new_size1; i++)
{
for (size_t j=0; j<new_size2; j++)
{
std::cout << "new array[" << i << "," << j << "] = " << new_array[i][j] << std::endl;
}
}
// Clean up my memory. This is C++ afterall.
for (size_t i=0; i<new_size1; i++)
{
delete [](new_array[i]);
}
delete []new_array;
return 0;
}

I believe you're looking for something like this. Though with some challenges accessing a proper compiler I can't verify...
#include <iostream>
#include <array>
#include <inttypes.h>
#include <math.h>
void calc_new_sizes(const size_t old_size, size_t& new_size1, size_t& new_size2)
{
new_size1 = 1;
new_size2 = 1;
size_t stop_at = (size_t)sqrt(old_size) + 1;
for (size_t i = 1; i<stop_at; i++)
{
if ( old_size % i == 0 )
{
new_size1 = i;
new_size2 = old_size / i;
}
}
}
template <class T, size_t new_size_1, size_t new_size_2, size_t old_size>
std::array<new_size_1, std::array<T, new_size_2>> twoDimensionify(std::array<T, old_size> p_input)
{
std::array<new_size_1, std::array<T, new_size_2>> returnValue;
int old_i = 0;
for (int i=0; i<new_size_1; i++)
{
for (int j=0; j<new_size_2; j++)
{
returnValue[i][j] = p_input[old_i];
old_i++;
}
}
return returnValue;
}
int main()
{
size_t old_size=20, new_size1=0, new_size2=0;
calc_new_sizes(old_size, new_size1, new_size2);
std::cout << "From " << old_size << " to " << new_size1 << "x" << new_size2 << std::endl;
return 0;
}

Related

how to update a variable in contiguous memory atomicly

I have a struct with multi variables packed which is not aligned.Then I make an array of the struct and set up a reader thread and a writer thread to update the variable concurrently.I find error value which only half of the variable is updated from output.I guess this is caused by one variable lay in two cache lines.Change the variable to atomic doesn't solve the problem.So,is there a way to solve this without memory aligned?
#include <thread>
#include <atomic>
#include <iostream>
#include <mutex>
#include <stdalign.h>
#pragma pack(1)
struct Foo {
uint64_t key;
uint64_t key2;
uint64_t key3;
uint32_t key4;
uint64_t key5;
};
#pragma pack()
const int block_size = 10;
uint64_t keys[10];
void printEle(const Foo* ele) {
std::cout << "Key " << ele->key
<< " key2 " << ele->key2
<< " key3 " << ele->key3
<< " key5 " << ele->key5 << std::endl;
}
void reader(Foo* list) {
for (int i = 0; i < 1000000; ++i) {
for (int j = 0; j < block_size; ++j) {
Foo* ele = reinterpret_cast<Foo*>(list + j);
printEle(ele);
}
}
}
void writer(Foo* list) {
for (int i = 0; i < 1000000; ++i) {
for (int j = 0; j < block_size; ++j) {
Foo* ele = reinterpret_cast<Foo*>(list + j);
if (i % 2 == 0) {
ele->key = keys[j];
ele->key2 = keys[j];
ele->key3 = keys[j];
ele->key5 = keys[j];
} else {
ele->key = j;
ele->key2 = j;
ele->key3 = j;
ele->key5 = j;
}
}
}
}
void test() {
keys[0]= 1556273083026830079;
keys[1]= 6541630416163430395;
keys[2]= 2310622570815837826;
keys[3]= 12643974306886634761;
keys[4]= 15393333677141345392;
keys[5]= 3591765785331799809;
keys[6]= 5404586990109662840;
keys[7]= 1376395845958874653;
keys[8]= 7620513273959825252;
keys[9]= 16620834775579010287;
Foo* list = new Foo[block_size];
for (int i = 0; i < block_size; ++i) {
uint64_t k = keys[i];
Foo* ele = reinterpret_cast<Foo*>(list + i);
ele->key = k;
ele->key2 = k;
ele->key3 = k;
ele->key4 = 707406378;
ele->key5 = k;
}
std::thread write(writer, list);
std::thread read(reader, list);
read.join();
write.join();
}
int main(int argc, char* argv[]) {
std::cout << "Size " << sizeof(Foo) << std::endl;
test();
std::cout << "done." << std::endl;
return 0;
}

C++ buffer manipulation

My professor gave us an example main\source.cpp file and wants us to create the necessary class\header file to make it work. He's the no example code vague "helpful hints" type so I'm lost.
I know this is a long post any input anyone may be willing to help me with at all would be a huge help.
Source.cpp he provided;
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setw
#include <string>
#include "DataBuffer.h"
using namespace std;
void testDataBuffer(int arr[], int length);
int main() {
const int ARR0_LEN = 2;
int arr0[ARR0_LEN] = { -2,-1 };
const int ARR1_LEN = 10;
int arr1[ARR1_LEN] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const int ARR2_LEN = 25; int arr2[ARR2_LEN] = { 2, 4, 6, 8, 10, 12, 14, 16, 7, 6, 22, 8, 9, 16, 5, 2, 7, 8, 12, 2, 0, 14, 17, 19, 22 };
testDataBuffer(arr0, ARR0_LEN);
testDataBuffer(arr1, ARR1_LEN);
testDataBuffer(arr2, ARR2_LEN);
//hold console open
std::cin.get();
return 0;
}
void testDataBuffer(int arr[], int length) {
DataBuffer buf; buf.copyData(arr, length);
buf.print(); cout << "Sum " << buf.sum() << endl;
cout << "Min " << buf.minValue() << endl;
cout << "Max " << buf.maxValue() << endl;
cout << "Range " << buf.range() << endl;
cout << "Mean " << buf.mean() << endl;
}
My DataBuff.h
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setw
#include <string>
#pragma once
class DataBuffer {
static const int BUFFER_SIZE = 256;
int buffer[BUFFER_SIZE];
static const int length = 5;
int arr[length] = { 1,2,3,4,5 };
public:
bool copyData(int intArray, int length);
string print();
double mean(int sum);
int sum();
int maxValue();
int minValue();
int range(int small, int large);
};
My DataBuffer.cpp
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setw
#include <string>
#include <array> // .sizeof()
#include "DataBuffer.h"
using namespace std;
bool DataBuffer::copyData(int arr, int length) {
for (int i = 0; i < length; i++) {
arr = buffer[i];
}
cout << "Length of buffer is " << length;
if (sizeof(buffer) < length) {
return false;
}
else {
return true;
}
}
string DataBuffer::print() {
if (length <= 0) {
cout << "{}" << endl;
}
else {
cout << buffer[0];
for (int i = 1; i < length; i++) {
cout << setw(10) << buffer[i];
cout << endl;
}
}
}
int DataBuffer::sum()
{
int i, sum = 0;
for (i = 0; i < length; i++)
{
sum += buffer[i];
}
return sum;
}
double DataBuffer::mean(int sum) {
double mean = sum / length;
return mean;
}
int DataBuffer::maxValue() {
int i = 0;
int large = buffer[0];
for (i = 1; i < length; i++)
{
if (buffer[i] > large)
large = buffer[i];
}
return large;
}
int DataBuffer::minValue() {
int i;
int small = buffer[0];
for(i=1; i < length; i++)
{
if(buffer[i] < small)
small = buffer[i];
}
return small;
}
int DataBuffer::range(int small, int large)
{
int range = large - small;
return range;
}
Main errors I'm stuck on;
The professor states that range and mean should accept parameters, so why doesn't the method call in his cpp have parameters? I'm getting errors stating range doesn't take 0 arguments
Error C3646 'print': unknown override specifier AustinNorrisBuffer c:\users\austinn\downloads\austinnorrisbuffer\databuffer.h 19
Error C2039 'print': is not a member of 'DataBuffer' AustinNorrisBuffer c:\users\austinn\downloads\austinnorrisbuffer\source.cpp 29
Again long post I know, any help appreciated!
I suggest the following approach (so that you learn what your professor had in mind and keep your sanity along the way):
Comment everything out.
Uncomment selected pieces of code.
Use a search engine to research those specific errors. Fix the code/header and proceed.
If you hit a very specific issue and need help then you can post a well formed question here and you will get a specific answer quickly.
Good luck.
Here is what I had to comment out to get it to compile at least:
DataBuff.h
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setw
#include <string>
#pragma once
class DataBuffer {
static const int BUFFER_SIZE = 256;
int buffer[BUFFER_SIZE];
static const int length = 5;
int arr[length] ={1,2,3,4,5};
public:
bool copyData(int intArray,int length);
//string print();
double mean(int sum);
int sum();
int maxValue();
int minValue();
int range(int small,int large);
};
DataBuffer.cpp
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setw
#include <string>
#include <array> // .sizeof()
#include "DataBuff.h"
using namespace std;
bool DataBuffer::copyData(int arr,int length)
{
for (int i = 0; i < length; i++) {
arr = buffer[i];
}
cout << "Length of buffer is " << length;
if (sizeof(buffer) < length) {
return false;
}
else {
return true;
}
}
//string DataBuffer::print()
//{
//if (length <= 0) {
// cout << "{}" << endl;
//}
//else {
// //cout << buffer[0];
// for (int i = 1; i < length; i++) {
// //cout << setw(10) << buffer[i];
// cout << endl;
// }
//}
//}
int DataBuffer::sum()
{
int i,sum = 0;
for (i = 0; i < length; i++) {
sum += buffer[i];
}
return sum;
}
double DataBuffer::mean(int sum)
{
double mean = sum / length;
return mean;
}
int DataBuffer::maxValue()
{
int i = 0;
int large = buffer[0];
for (i = 1; i < length; i++) {
if (buffer[i] > large)
large = buffer[i];
}
return large;
}
int DataBuffer::minValue()
{
int i;
int small = buffer[0];
for (i=1; i < length; i++) {
if (buffer[i] < small)
small = buffer[i];
}
return small;
}
int DataBuffer::range(int small,int large)
{
int range = large - small;
return range;
}
Source.cpp
#include <iostream> // std::cout, std::endl
#include <iomanip> // std::setw
#include <string>
#include "DataBuff.h"
using namespace std;
void testDataBuffer(int arr[],int length);
int main()
{
const int ARR0_LEN = 2;
int arr0[ARR0_LEN] ={-2,-1};
const int ARR1_LEN = 10;
int arr1[ARR1_LEN] ={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const int ARR2_LEN = 25; int arr2[ARR2_LEN] ={2, 4, 6, 8, 10, 12, 14, 16, 7, 6, 22, 8, 9, 16, 5, 2, 7, 8, 12, 2, 0, 14, 17, 19, 22};
testDataBuffer(arr0,ARR0_LEN);
testDataBuffer(arr1,ARR1_LEN);
testDataBuffer(arr2,ARR2_LEN);
//hold console open
std::cin.get();
return 0;
}
void testDataBuffer(int arr[],int length)
{
DataBuffer buf;
//buf.copyData(arr,length);
//buf.print(); cout << "Sum " << buf.sum() << endl;
//cout << "Min " << buf.minValue() << endl;
//cout << "Max " << buf.maxValue() << endl;
//cout << "Range " << buf.range() << endl;
//cout << "Mean " << buf.mean() << endl;
}

How to optimize random sort algorithm?

Here is some random sort program I wrote in C++. It works pretty fine for 10 elements or so. But for 15 elements it works so slow I can't even wait enough to get the result. Is there some way to optimize random sort algorithm?
Here's my code:
// randomsort.h
#ifndef RANDOMSORT_H
#define RANDOMSORT_H
#include <stdlib.h>
#include <time.h>
class RandomSort
{
private:
template <class T>
static bool isOrdered(T*, int);
public:
template <class T>
static int sort(T*, int);
};
template <class T>
bool RandomSort::isOrdered(T* arr, int size)
{
for(int i = 1; i < size; i++)
{
if(arr[i-1] > arr[i])
{
return false;
}
}
return true;
}
template <class T>
int RandomSort::sort(T* arr, int size)
{
int stepAmount = 0;
srand(time(NULL));
while(!isOrdered(arr, size))
{
int i = rand() % size;
int j = rand() % size;
std::swap(arr[i], arr[j]);
stepAmount++;
}
return stepAmount;
}
#endif // RANDOMSORT_H
And main.cpp file
// main.cpp
#include <iostream>
#include "randomsort.h"
int main()
{
int size;
std::cout << "Enter amount of elements to sort: ";
std::cin >> size;
std::cout << std::endl;
int arr[size];
for(int i = 0; i < size; i++)
{
arr[i] = (rand() % (size * 10));
}
std::cout << "Input array: " << std::endl;
for(int i = 0; i < size; i++)
std::cout << arr[i] << ' ';
std::cout << std::endl << std::endl;
int stepAmount = RandomSort::sort(arr, size);
std::cout << "Output array: " << std::endl;
for(int i = 0; i < size; i++)
std::cout << arr[i] << ' ';
std::cout << std::endl << std::endl;
std::cout << "Number of steps: " << stepAmount;
return 0;
}
Any suggestions?
Your code is completely random. So it can swap when it should not. An easy fix would be to swap only if you need it.
int i = rand() % size;
int j = rand() % size;
// to know which should be first
if (i > j)
std::swap(i, j);
if (arr[i] > arr[j])
std::swap(arr[i], arr[j]);
Your array probably will not be sorted immediately, so you could also test if it is sorted only every five steps (for example) instead of every step.
But i think the most important is, you should not expect good performances from such an algorithm.

Mode of Array C++

My code to find the mode (most often) and how many times said mode was displayed runs into a never-ending loop. Does anyone know what I can do to fix it?
EDIT I UPDATED THE CODE: It returns 0, which is not the mode.
void calculateMode(int array[], int size)
{
int counter = 0;
int max = 0;
int mode = 0;
for (int pass = 0; pass < size - 1; pass++)
for (int count = pass + 1; count < size; count++) {
if (array[count] > max) {
max = array[count];
mode = 1;
counter = array[pass];
}
cout << "The mode is: " << counter "It's been displayed: " << count << "times" << endl;
}
A solution using map. Compile with g++ -std=c++11 a.cpp.
Here is definition of mode
#include <iostream>
#include <map>
#include <vector>
using namespace std;
int main()
{
vector<int> v = {1, 1, 2, 2, 3, 3};
map<int, int> count;
for (size_t i = 0; i < v.size(); ++i)
count[v[i]]++;
vector<int> mode;
int cnt = 0;
for (map<int, int>::iterator it = count.begin(); it != count.end(); ++it) {
if (it->second > cnt) {
mode.clear();
mode.push_back(it->first);
cnt = it->second;
} else if (it->second == cnt) {
mode.push_back(it->first);
}
}
if (mode.size() * cnt == v.size()) {
cout << "No mode" << endl;
} else {
cout << "mode:";
for (size_t i = 0; i < mode.size(); ++i)
cout << ' ' << mode[i];
cout << endl;
}
return 0;
}
This code uses "map" to find out the MODE from the given array. I hope this solution might help you.
int findMode(int * arr, int size)
{
map<int, int> modeMap;
sort(arr, arr + size);
for (int i = 0; i < size; ++i) {
++modeMap[arr[i]];
}
auto x = std::max_element(modeMap.begin(), modeMap.end(),
[](const pair<int, int>& a, const pair<int, int>& b) {
return a.second < b.second; });
return x->first;
}

How do you save a whole array to a disk in c++

I've been looking, but i've never been able to save anything other than one coordinate in a 2 dimensional array
This is called serialization. Have a look at this question for more info on using Boost to do just that.
Based on StackedCrooked's idea, here's a solution that allows you to user either a C-style array of std::vector or any other sequence whose elements have << defined for them.
#include <cstddef>
#include <fstream>
#include <iostream>
// Beware, brain-compiled code ahead!
template<class InpIt>
void save_seq(const std::ostream& os, InpIt begin, InpIt end)
{
if(begin != end)
os << *begin++;
while(begin != end)
os << ' ' << *begin++;
}
template<class OutpIt>
bool load_seq(const std::istream& is, OutpIt begin, std::size_t n)
{
for( std::size_t i=0; is && i<n; ++i)
is >> *begin++
return is.good() || is.eof();
}
template<class OutpIt>
bool load_seq(const std::istream& is, OutpIt begin)
{
while(is.good())
is >> *begin++
return is.eof();
}
template<class T, std::size_t N>
void save_array(const std::ostream& os, const T (&data)[N])
{
save_seq(os, data, data+N);
}
template<class T, std::size_t N>
bool load_array(const std::istream& is, T (&data)[N])
{
return load_seq(is, data, N);
}
int main()
{
const std::size_t size = 5;
int numbers[size];
numbers[0] = 10;
numbers[1] = 11;
numbers[2] = 12;
numbers[3] = 13;
numbers[4] = 14;
{
std::oftsream ofs("array.txt");
if(!ofs.good())
return 1;
save_array(ofs, numbers);
}
{
std::iftsream ifs("array.txt");
if(!ifs.good())
return 2;
int test[size];
load_array(ifs, test);
for (std::size_t idx = 0; idx < size; ++idx)
std::cout << "test[" << idx << "]: " << test[idx] << std::endl;
}
std::vector<int> numbers2;
numbers2.push_back(20);
numbers2.push_back(21);
numbers2.push_back(22);
numbers2.push_back(23);
{
std::oftsream ofs("array.txt");
if(!ofs.good())
return 1;
save_Seq(ofs, numbers2.begin(), numbers2.end());
}
{
std::iftsream ifs("array.txt");
if(!ifs.good())
return 2;
std::vector<int> test;
load_seq(ifs, std::back_inserter(test));
for (std::size_t idx = 0; idx < numbers2.size(); ++idx)
std::cout << "test[" << idx << "]: " << test[idx] << std::endl;
}
return 0;
}
You could use a std::fstream or boost::serialization. Your question is a bit vague, so I'm not entirely sure what it is you want, need?
If the array contains flat data (i.e., data that does not include pointers to other data), you can write an entire array in a single write to a file.
Without any idea what your data looks like, it would not be possible to say much more about it.
After some tinkering I came up with this:
#include <cstddef>
#include <fstream>
#include <iostream>
template<class T>
void SaveArray(const std::string & file, T * data, std::size_t length)
{
std::ofstream out(file.c_str());
for (std::size_t idx = 0; idx < length; ++idx)
{
if (idx != 0)
{
out << " ";
}
out << *data++;
}
}
template<class T>
std::size_t LoadArray(const std::string & file, T * data, std::size_t length)
{
std::ifstream in(file.c_str());
std::size_t count = 0;
while (count++ < length && in >> *data++);
return count - 1; // return number of items
}
int main()
{
int numbers[5];
numbers[0] = 10;
numbers[1] = 11;
numbers[2] = 12;
numbers[3] = 13;
numbers[4] = 14;
SaveArray("array.txt", &numbers[0], 5);
int test[5];
LoadArray("array.txt", &test[0], 5);
for (std::size_t idx = 0; idx < 5; ++idx)
{
std::cout << "test[" << idx << "]: " << test[idx] << std::endl;
}
return 0;
}
Suggestions for improvement are welcome.