so i need to swap row 2 and row 3 of my array. There is a catch our professor had us use a one dimensional array and use a pointer instead of a 2d array. We cannot reference the array only the pointer. I have no idea how to do this.
int numbers[25] = { 1,3,5,7,9 , -2,-4,-6, -8, -10 , 3,3,3,3,3 , 55, 77, 99, 22, 33, -15, -250, -350, -450, -550 };
this array is supposed to look like this:
1 3 5 7 9
-2 -4 -6 -8 -10 // i need to swap this row
3 3 3 3 3 // for this row
55 77 99 22 33
-15 -250 -350 -450 -550
This is how i need to print it
1 3 5 7 9
3 3 3 3 3
-2 -4 -6 -8 -10
55 77 99 22 33
-15 -250 -350 -450 -550
Note: this is not my whole HW assignment is just where i am stuck.
Why not try something like:
constexpr std::size_t rowLength = 5u;
const auto beginRow2 = std::begin(numbers) + (rowLength * 2);
const auto endRow2 = std::begin(numbers) + (rowLength * 3);
const auto beginRow3 = std::begin(numbers) + (rowLength * 3);
std::swap_ranges(beginRow2, endRow2, beginRow3);
This is idiomatic C++ and can easily be adapted to provide a generic function that accepts a 1-dimensional container, a row-length and the two rows to swap.
Just define a temporary array:
int tmp_row[5];
Save the third row:
int bytes = sizeof(tmp_row);
memcpy(tmp_row, &numbers[10], bytes);
Then fill in the second and third rows appropriately:
memcpy(&numbers[10], &numbers[5], bytes);
memcpy(&numbers[5], tmp_row, bytes);
Related
I would like to do simple stuff - extract every second row in a matrix of shape [4,5] to get two output matrices of shapes [2,5]. My matrix is:
Eigen::MatrixXf m(4,5);
m << 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20;
when I print I get the expected:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
Now how to obtain the expected outputs: ?
// expected mOut1:
1 2 3 4 5
11 12 13 14 15
// and expected mOut2:
6 7 8 9 10
16 17 18 19 20
So far I tried with Eigen::Map and strides, but I have no idea how do those strides work.
I made a function:
Eigen::Map<Eigen::MatrixXf, 0, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>> myMatrixSlice(const float* data, unsigned dim1, unsigned dim2, int stride1, int stride2) {
using Stride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
return Eigen::Map<Eigen::MatrixXf, 0, Stride>{
const_cast<float*>(data), dim1, dim2, Stride{stride1, stride2}};
}
and I want to call it like this:
auto mOut1 = myMatrixSlice(m.data(), 2, 5, ?, ?);
auto mOut2 = myMatrixSlice(m.data(), 2, 5, ?, ?); // remember to start with row=1
but I guess I need some help on this.
The problem: I need to print the Pascal triangle for any (unsigned int) input passed as a command line argument. All the values must be stored in a LINEAR array and elements must only be manipulated as dereferenced pointers. Following this, the array elements must printed as a lower triangular matrix and subsequently deleted. My implementation functions perfectly for input ranging from 0 to 12 but produces spurious results for higher values.
I tried two different implementations.
Declare a pointer to an array of size (n+1)*(n+2)/2 (which is the number of elements in the triangle for input 'n'). Assign/print variables within a nested loop. Delete the pointer once both loops have been executed.
Run a nested loop, 0 <= i <= n, and 0 <= j <= i. Declare a pointer to an array of size (i+1) in the outer loop. Assign/print elements in the inner loop. Delete the pointer once the inner loop has been executed.
// VERSION 1
unsigned N = (n+1)*(n+2)/2;
unsigned* elements = new unsigned[N];
for(i = 0; i <= n; i++) {
for(j = 0; j <= i; j++) {
*(elements + j+(i*i+i)/2) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
cout << endl;
}
delete [] elements;
// VERSION 2
for(i = 0; i <= n; i++) {
unsigned* elements = new unsigned[i+1];
for(j = 0; j <= i; j++) {
*(elements + j) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
delete [] elements;
cout << endl;
}
Both these versions were tried separately on Xcode. In both cases, the triangle printed correctly until the 12th layer, i.e. n=12, but generated incorrect results for higher values.
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 | 1 7 21 35 35 21 7 1
8 | 1 8 28 56 70 56 28 8 1
9 | 1 9 36 84 126 126 84 36 9 1
10 | 1 10 45 120 210 252 210 120 45 10 1
11 | 1 11 55 165 330 462 462 330 165 55 11 1
12 | 1 12 66 220 495 792 924 792 495 220 66 12 1
13 | 1 4 24 88 221 399 532 532 399 221 88 24 4 1
14 | 1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
15 | 1 1 0 0 2 4 7 9 9 7 4 2 0 0 1 1
16 | 1 0 0 0 0 4 0 1 1 1 0 4 0 0 0 0 1
The debugger, to the extent that I can use it, produced no error messages.
What is happening and how do I fix it?
fact(i) overflows really fast. I haven't checked the numbers, but I'm pretty sure that's what's happening.
Instead, use the fact that a number in Pascal's triangle is the sum of the two numbers above it.
Wikipedia has a nice animation for this.
When i is 13, fact(i) is 6227020800, which is too big to fit in a 32-bit unsigned integer, so integer overflow occurs.
I’m trying to implement Radix-Sort with arrays of long int.
My Algorithm has 2 inputs:
The number ’n’ of elements to be sorted
The number ‘b’ of bits per digit (So, insted of taking the last decimal number, I take the groups of ‘b’ digits, representing one digit)
But, when I try to sort the vector, I find 2 problems:
First one: It doesn’t sort the vector properly
Second one: I have implemented it for taking from the last group of bits to the first one. But it seems like it tries to sort in in the opposite direction.
Here is the code:
#define MAX_BITS sizeof(long int)*8
#define VectorL vector<long int>
struct Compare
{
int beg = 0;
int bits_per_digit = 2;
Compare(int x, int y){
beg = x;
bits_per_digit = y;
}
bool operator() (long& a, long& b){
int _begin = beg;
int _final = _begin + bits_per_digit - 1;
assert(_begin <= _final); // b==f if bits_per_digit = 1;
bitset<sizeof(long int)> _x(a), _y(b);
for(_begin; _begin <= _final; _begin++)
if(_x[_begin] != _y[_begin])
return (_x[_begin] < _y[_begin]) ? true : false;
return false;
}
};
void ALG(VectorL& nums, int n, int b)
{
assert(nums.size() == n);
assert(MAX_BITS%b == 0);
int _grupos = MAX_BITS/b;
Compare myobject(MAX_BITS,b);
for (int g = 1; g <= _grupos; g++)
{
myobject.beg -= b;
sort(nums.begin(), nums.end(), myobject);
}
}
Here’s the main:
int n=5, b=2;
VectorL nums(n);
nums[0] = 2;
nums[1] = 6;
nums[2] = 1;
nums[3] = 5;
nums[4] = 0;
ALG(nums, n, b);
And here’s the output:
Initial Vector: 2 6 1 5 0
From bit 62 to bit 63
Vector after the 1º sort: 2 6 1 5 0
From bit 60 to bit 61
Vector after the 2º sort: 2 6 1 5 0
From bit 58 to bit 59
Vector after the 3º sort: 2 6 1 5 0
From bit 56 to bit 57
Vector after the 4º sort: 2 6 1 5 0
From bit 54 to bit 55
Vector after the 5º sort: 2 6 1 5 0
From bit 52 to bit 53
Vector after the 6º sort: 2 6 1 5 0
From bit 50 to bit 51
Vector after the 7º sort: 2 6 1 5 0
From bit 48 to bit 49
Vector after the 8º sort: 2 6 1 5 0
From bit 46 to bit 47
Vector after the 9º sort: 2 6 1 5 0
From bit 44 to bit 45
Vector after the 10º sort: 2 6 1 5 0
From bit 42 to bit 43
Vector after the 11º sort: 2 6 1 5 0
From bit 40 to bit 41
Vector after the 12º sort: 2 6 1 5 0
From bit 38 to bit 39
Vector after the 13º sort: 2 6 1 5 0
From bit 36 to bit 37
Vector after the 14º sort: 2 6 1 5 0
From bit 34 to bit 35
Vector after the 15º sort: 2 6 1 5 0
From bit 32 to bit 33
Vector after the 16º sort: 2 6 1 5 0
From bit 30 to bit 31
Vector after the 17º sort: 2 6 1 5 0
From bit 28 to bit 29
Vector after the 18º sort: 2 6 1 5 0
From bit 26 to bit 27
Vector after the 19º sort: 2 6 1 5 0
From bit 24 to bit 25
Vector after the 20º sort: 2 6 1 5 0
From bit 22 to bit 23
Vector after the 21º sort: 2 6 1 5 0
From bit 20 to bit 21
Vector after the 22º sort: 2 6 1 5 0
From bit 18 to bit 19
Vector after the 23º sort: 2 6 1 5 0
From bit 16 to bit 17
Vector after the 24º sort: 2 6 1 5 0
From bit 14 to bit 15
Vector after the 25º sort: 2 6 1 5 0
From bit 12 to bit 13
Vector after the 26º sort: 2 6 1 5 0
From bit 10 to bit 11
Vector after the 27º sort: 2 6 1 5 0
From bit 8 to bit 9
Vector after the 28º sort: 2 6 1 5 0
From bit 6 to bit 7
Vector after the 29º sort: 2 6 1 5 0
From bit 4 to bit 5
Vector after the 30º sort: 2 6 1 5 0
From bit 2 to bit 3
Vector after the 31º sort: 2 1 0 6 5
From bit 0 to bit 1
Vector after the 32º sort: 0 2 6 1 5
As you can see in the output, the changes only happens in the 31st and 32nd sort (so, that means the significant bits are found in the last searchs).
Anyone can help me to find my mistake?
Thanks in advance.
I'm working on a a project for my class where I have to use all four algorithms for the maximum subarray sub problem (cubic, quadratic, linear, and recursive). My problem is that I'm supposed to read the input from a file and I'm having trouble figuring out how to read until the end of a line, execute code with that data, and then move onto the next line. The input file looks like this:
2
-5 -10 -2 -4
2
-2 10 -5 -6
3
-10 -5 0 5 -20 20 -50
4
10 8 2 -20 -50 -100 -150
0
-1 -2 -3 -4 -5
1
-100 -200 0
4
200 500 -700 1000 2000 -5000 4 10
4
100 200
6
0 0 0 0 0 0 -10
5
-4 10 -3 200 500 -700 2
0
5 10 15 20 25 30 35
2
10 30 50 70 100
3
-15 16 23 -30 0 -2 13 8 6 0 -4 -15
12
9 8 23 -1 -23 -4 0 0 4 7 9 10 -23 68 1 -2 -3 -6 -19 10 5 1 1 2 4 3 -46 12 -100 78 -23 0 0 12 2 7
5
-1 -3 0 2 3 6 1 -5 -3 -2
now my issue is that I want to be able to read in a single number (the minimum subarray length) and then fill the array with the row of numbers below it, then execute all four algorithms using that data, then I want to move on to the next minimum subarray length and the next array of values below it, execute all four algorithms etc., and I want to be able to do this all in one go.
For example, I want to read 2 as the minimum subarray length, then use (-5,-10,-2,-4) as the array, execute all four algorithms, then use 2 as the minimum length, (-5,10,-5,-6) as the array, execute all four algorithms, and keep doing that until the end of the file.
Here is a quick possible solution that might help ("test.txt" contains your values...)
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
ifstream in("test.txt");
string str;
int value;
while (in)
{
vector<int> vec;
getline(in, str);
stringstream stream(str);
while (stream)
{
stream >> value;
vec.push_back(value);
}
vec.erase(vec.end()-1);
//Here the vec conntains all values of the current line
for (auto v : vec)
cout << v << " ";
cout << endl;
}
}
In attempt to understand recursion better, I tried to print some output within my code so that I could study the steps.
#include <tuple>
#include <string>
#include <iostream>
#include <map>
#include "print.h"
std::tuple<int, int, int> find_max_crossing_subarray(int A[], int low, int mid, int high)
{
int max_left, max_right;
int left_sum = std::numeric_limits<int>::min();
int sum = 0;
for(int i = mid; i >= low; i--) {
sum += A[i];
if(sum > left_sum) {
left_sum = sum;
max_left = i;
}
}
int right_sum = std::numeric_limits<int>::min();
sum = 0;
for(int j = mid + 1; j <= high; j++) {
sum += A[j];
if(sum > right_sum) {
right_sum = sum;
max_right = j;
}
}
return std::make_tuple(max_left, max_right, left_sum + right_sum);
}
std::tuple<int, int, int> find_max_subarray(int A[], int low, int high)
{
if(high == low) {
return std::make_tuple(low, high, A[low]);
}
else {
int mid = (high + low) / 2;
std::tuple<int, int, int> left(find_max_subarray(A, low, mid));
std::cout << "left: ";
print(left);
int left_low, left_high, left_sum;
std::tie(left_low, left_high, left_sum) = left;
std::tuple<int, int, int> right(find_max_subarray(A, mid + 1, high));
std::cout << "right: ";
print(right);
int right_low, right_high, right_sum;
std::tie(right_low, right_high, right_sum) = right;
std::tuple<int, int, int> cross(find_max_crossing_subarray(A, low, mid, high));
std::cout << "cross: ";
print(cross);
int cross_low, cross_high, cross_sum;
std::tie(cross_low, cross_high, cross_sum) = cross;
if(left_sum >= right_sum && left_sum >= cross_sum) {
return left;
}
else if(right_sum >= left_sum && right_sum >= cross_sum) {
return right;
}
else {
return cross;
}
}
}
int main()
{
int arr_3[3] = {-3, 2, 3};
int arr_4[4] = {5, -23, 1, 44};
int arr_6[6] = {5, -23, 1, 44, -2, 5};
int arr[16] = {-23, 3, 9 ,7, -12, 87, -25, 2, 3, 5, 32, -8, 6, -82, 3, 9};
print(arr_4, 4);
std::tuple<int, int, int> maple(find_max_subarray(arr_4, 0, 3));
print(maple);
return 0;
}
OUTPUT::
5 -23 1 44
left: 0 0 5
right: 1 1 -23
cross: 0 1 -18
left: 0 0 5
left: 2 2 1
right: 3 3 44
cross: 2 3 45
right: 2 3 45
cross: 0 3 27
2 3 45
I understand the first three lines of the output (that is, where the left, right, cross begin). But I do not understand where the fourth line and beyond come from. I tried tracing back the functions and I keep thinking I should get left: 1 1 -23 in my fourth line of output after cross: 0 1 -18.
EDIT:
I should point out that after left: 2 2 1, although it's hard to visualize, I understand somewhat. The recursion has reached the end and the code is just cascading backwards.
SECOND EDIT:
I guess what is happening in the fourth line is that the very first find_max_subarray is completing and it is returning the first if statement in the function code. Now it is moving to the second find_max_subarray.
THIRD EDIT:
I guess my confusion is that the code doesn't cascade backwards but instead just returns to the very first call after it reaches the end of the recursion.
FOURTH EDIT:
When I go out to six elements though it seems like it doesn't simply return to the first call.
5 -23 1 44 -2 5
left: 0 0 5
right: 1 1 -23
cross: 0 1 -18
left: 0 0 5
right: 2 2 1
cross: 0 2 -17
left: 0 0 5
left: 3 3 44
right: 4 4 -2
cross: 3 4 42
left: 3 3 44
right: 5 5 5
cross: 3 5 47
right: 3 5 47
cross: 2 5 48
2 5 48
I mean I guess it's because the sub array has three elements as opposed to two. So there are two pairs as opposed to one. It makes sense when you take it for granted but can't see it visually.
LAST EDIT:
So when I go out to 8, it goes in pairs. First two elements and then return the original call. The next two pairs and return the call. I'm not exactly sure why though in the odd case it won't return the call until both the first and second and first and third pairs have completed.
5 -23 1 44 -2 5 6 -3
left: 0 0 5
right: 1 1 -23
cross: 0 1 -18
left: 0 0 5
left: 2 2 1
right: 3 3 44
cross: 2 3 45
right: 2 3 45
cross: 0 3 27
left: 2 3 45
left: 4 4 -2
right: 5 5 5
cross: 4 5 3
left: 5 5 5
left: 6 6 6
right: 7 7 -3
cross: 6 7 3
right: 6 6 6
cross: 5 6 11
right: 5 6 11
cross: 2 6 54
2 6 54
PROBLEM SOLVED:
The problem I was having in understanding the recursion is that for each recursive step I was using the original high value. I actually wrote it down on paper in blocks using the correct high and everything came together.
As stated above in my problem solved section following the last edit, I realized that in my analysis I was using the wrong value for high. I was not seeing this because although I was using blocks I was going in blocks of sequences and not blocks of blocks.
I went block by block with the updated high for each sub-block. I posted the illustration below. And this agrees with the output I was getting. The return statement accompanies each block.
Four element case:
(0,3)
(0,1)
(0,0) -> left
(1,1) -> right
-> cross
return left
(2,3)
(2,2) -> left
(3,3) -> right
-> cross
return right
return cross
Five element case:
(0,4)
(0,2)
(0,1)
(0,0) -> left
(1,1) -> right
-> cross
return left
(2,2) -> right
-> cross
return left
(3,4)
(3,3) -> left
(4,4) -> right
-> cross
return right
return cross