In-place transpose of a 2-d vector passed by reference - c++

I am trying to compute the transpose of a matrix. Now, I have passed the matrix as a 2-d vector, and since I want the function to calculate the transpose in-place, I passed the 2-d vector by reference. But it seems to take no effect.
I tried to use std::swap(mat[i][j], mat[j][i]), it had no effect. Again, I tried to manually swap the integers (using a third variable), still no effect.
#include<iostream>
#include<vector>
#include<algorithm>
#define N 5
void inPlaceTranspose(std::vector<std::vector<int> > &mat) {
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
int temp = mat[i][j];
mat[i][j] = mat[j][i];
mat[j][i] = temp;
//std::swap(mat[i][j], mat[j][i]);
}
}
std::cout << "Transpose:\n";
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
std::cout << mat[i][j] << " ";
}
std::cout << "\n";
}
}
int main() {
std::vector<std::vector<int> > mat(N, std::vector<int>(N));
mat = {
{1, 2, 3, 4, 5},
{7, 8, 9, 10, 11},
{13, 14, 15, 16, 17},
{19, 20, 21, 22, 23},
{25, 26, 27, 28, 29},
};
std::cout << "Original Matrix:\n";
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
std::cout << mat[i][j] << " ";
}
std::cout << "\n";
}
inPlaceTranspose(mat);
return 0;
}
The Original Matrix and Transpose are coming out to be same.

The problem is not in the way you pass the matrix, or in the way you do the swap. The problem is in your logic here:
for(int j = 0; j < N; j++) {
which results in swapping the elements twice, thus cancelling out your attempt to transpose the matrix.
Try looping until i, instead of N, like this:
for(int j = 0; j < i; j++) {
instead.

Related

A program that passes two integer arrays to a function that then copies the values common in both into a third array and displays it in int main()

#include <iostream>
using namespace std;
void myfunction(int array[], int array1[], int array2[], int, int, int);
int main()
{
int array[5], array1[5], array2[5];
cout << "Enter array:";
for (int i = 0; i < 5; i++)
{
cin >> array[i];
cin >> array1[i];
}
myfunction(array, array1, array2, 5, 5, 5);
for (int i = 0; i < 5; i++)
cout << array2[i];
}
void myfunction(int array[], int array1[], int array2[], int n, int m, int o)
{
int k = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (array[i] == array1[j])
array2[k] = array1[j];
k++;
}
for (int i = k + 1; i < o; i++)
array2[i] = 0;
}
This is the logic that I thought of. But it is giving segmentation error which I don't know about. Also, I don't know where I am wrong. Please guide me
I believe you have one major issue here:
if(array[i]==array1[j])
array2[k]=array1[j];
k++;
The k++ part is executed each time but should be done once per array iteration only when a match is found. This is the part that is giving you the seg fault.
You can fix the whole nested for like so:
for (int i = 0; i < n; ++i, ++k)
{
const auto val = array[i];
if (std::any_of(array1, array1+n, [&val](int v){return v == val;}))
array2[k] = array[i];
else
array2[k] = 0;
}
Considering you don't use c++11 you can write an equivalent of the above:
for (int i = 0; i < n; ++i, ++k)
{
bool match = false;
for (int j = 0; j < m; ++j)
{
if (array[i] == array1[j])
{
match = true;
break;
}
}
if (match)
array2[k] = array[i];
else
array2[k] = 0;
}
This way you can also skip the following loop which also had an issue:
for (int i = k + 1; i < o; i++)
In result for input data like {1, 2, 3, 3, 5} and {1, 2, 4, 4, 5} you should get {1, 2, 0, 0, 5} which according to your comment is the expected output.
In general, I'd suggest you use std::vector or std::array since you work with a const sized array. This way you won't have to pass the array sizes as hardcoded values here and there. Additionally you'll be able to use the foreach-like loops and the code will get a bit cleaner.
You problem is in the below for loops:-
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(array[i]==array1[j])
array2[k]=array1[j];
k++;//this is being incremented each iteration
}
for(int i=k+1; i<o; i++)//What are you doing here I = 5 + 1 = 6
array2[i]=0;// what will happened here it will not execute
correct it like below:-
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(array[i]==array1[j])
{
array2[k]=array1[j];
k++;
}
}

When to use bucket sort effectively and how many buckets needed?

Hello I wanted to implement a bucket sort. I think it works for me:
#include <iostream>
using namespace std;
#include <vector>
#include <cmath>
#include <algorithm>
void bucket_sort(int[], const int);
int main(){
system("color 1f");
int array[] = {
5, 77, 99, 100, 77, 57, 23, 1, 2, 57,
81, 24, 21
};
cout << "before sorting: " << endl;
for(auto x : array)
cout << x << ", ";
cout << endl;
bucket_sort(array, 13);
cout << "after sorting: " << endl;
for( auto x : array)
cout << x << ", ";
cout << endl << endl;
return 0;
}
void bucket_sort(int array[], const int size){
int bucket = 10, divider;
int min = array[0], max = array[0], j;
for(auto i(0); i != size; ++i){
if(min > array[i])
min = array[i];
if(max < array[i])
max = array[i];
}
divider = (ceil( (double)(max + 1) / bucket) );
std::vector<int>* vi = new vector<int>[bucket];
for(i = 0; i < size; i++){
j = floor(array[i] / divider);
vi[j].push_back(array[i]);
}
for(i = 0; i < bucket; i++)
std::sort(vi[i].begin(), vi[i].end());
int k = 0;
for(i = 0; i < bucket; i++){
for(int j(0); j < vi[i].size(); j++){
array[k] = vi[i][j];
k++;
}
}
delete[]vi;
}
The code works fine. But is this the way I should do? If I have an array with values close to each other but one or two are too much big:
66, 42, 70, 10, 30, 32, 28, 1000, 50000
How to apply this bucket sort algorithm? Also how many buckets should I use?
I am not sure where you get the number 10. You can use the total number of items in the array.
You can declare vector of vector to create a 2-D vector (instead of new)
vector<vector<int>> vec;
Ideally, bucket_sort should not rely on other sort methods. Here is a version which uses recursion. It keeps iterating until there is zero or one element in each bucket (or several elements with the same value)
Example:
void bucket_sort(std::vector<int> &src)
{
if(src.size() <= 1)
return;
int min = *std::min_element(src.begin(), src.end());
int max = *std::max_element(src.begin(), src.end());
if(min == max)
return;
std::vector<std::vector<int>> vec;
vec.resize(src.size());
for(int i = 0; i < src.size(); i++)
{
//edit: double precision required
int v = int(double(src[i] - min) * src.size() / double(max - min + 1));
vec[v].push_back(src[i]);
}
for(size_t i = 0; i < vec.size(); i++)
//std::sort(vec[i].begin(), vec[i].end());
bucket_sort(vec[i]);
int index = 0;
for(size_t i = 0; i < vec.size(); i++)
for(size_t j = 0; j < vec[i].size(); j++)
src[index++] = vec[i][j];
}
int main()
{
std::vector<int> src = {66, 66, 42, 70, 10, 30, 32, 28, 1000, 50000 };
for(auto x : src) cout << x << ", ";
cout << endl;
bucket_sort(src);
for(auto x : src) cout << x << ", ";
cout << endl << endl;
return 0;
}
Testing:
int test()
{
srand((unsigned int)time(NULL));
//add 1 million random numbers for testing
std::vector<int> src;
for(int i = 0; i < 1000000; i++)
src.push_back(rand());
bucket_sort(src);
for(size_t i = 1; i < src.size(); i++)
if(src[i - 1] > src[i])
{
cout << "fail\n";
return 0;
}
cout << "success\n";
return 0;
}
Edit: changed division calculation to double precision, added test for 1 million

Maximum Sub-Array Sum C++

Given an array, I am trying to find the maximum sub-array sum. A sub-array is as follows. For example, I get the following array: [9, -7, 5, 3, 91]. Whilst [9, -7, 5] is a sub-array, [9, 5, 3, 91] is not. My code is below:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int arraylen, subarraylen, subarraysum, itervar1, itervar2, itervar3, incrementvar;
cin >> arraylen;
vector<int> mainarray(arraylen);
vector<int> sumarray(arraylen * (arraylen-1) + 1);
for (itervar1 = 0; itervar1 < arraylen; itervar1++) {
cin >> mainarray[itervar1];
}
sumarray[0] = 0;
for (itervar1 = 0; itervar1 < arraylen; itervar1++) {
for (itervar2 = arraylen; itervar2 > 0; itervar2--) {
subarraylen = itervar2-itervar1;
if (subarraylen < 1) {
continue;
}
vector<int> subarray(subarraylen);
incrementvar = 0;
for (itervar3 = itervar1; itervar3 < itervar2; itervar3++) {
subarray[incrementvar] = mainarray[itervar3];
incrementvar++;
}
subarraysum = 0;
for (itervar3 = 0; itervar3 < subarraylen; itervar3++) {
subarraysum += subarray[itervar3];
}
}
}
return 0;
}
For some reason, it doesn't work; just infinitely loops around. Any help would be appreciated.
First, here is a routine to list all the sub arrays:
vector<int> vec{ 9, -7, 5, 3, 91 };
int sz = vec.size();
for(int start = 0; start < sz; start++)
{
for(int end = start; end < sz; end++)
{
for(int j = start; j <= end; j++)
{
cout << vec[j] << ", ";
}
cout << "\n";
}
}
Now you just have to get the total in loop j, add to a vector sum. You don't need to know the size of sum before hand. Use push_back to add total to sum.
Note, the array itself is included as a sub array, you can exclude that array depending on what the definition is.

Multiplying 3x3 matrices in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm working on a program to multiply two 3X3 matrices together. I have hit a few problems and I can't figure out the problems. Any help would be appreciated :D
#include <iostream>
using namespace std;
int main(){
int matrix1[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int matrix2[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int results[3][3];
int product = 0;
int i;
int j;
for (i = 1; i <= 3; i++){
for (j = 1; j <= 3; j++){
product += matrix1[i][j] * matrix2[j][i];
cout << product << endl;
}
results[i][j] = product;
product = 0;
}
cout << endl << "Output Matrix: " << endl;
for (int i = 1; i < 4; i++){
for (int j = 1; j < 4; j++){
cout << results[i][j];
}
cout << endl;
}
system("pause");
return 0;
}
And this is the result I get out of it:
25
73
-1717986851
48
129
-858993331
-1867771963
1566576709
1595991863
Output Matrix:
-858993460-858993460-858993460
-1717986851-858993460-858993460
-85899333112
Press any key to continue . . .
Thanks again in advance! :D
So to begin with you don't need the int i, j; lines at the beginning. If you didn't have them there the compiler would correctly told you that results[i][j] = product; is in the wrong place. Also arrays' first value isn't at A[1] but at A[0]. And for the matrix multiplication I suggest you to read this.
Therefore the solution should look like this:
int matrix1[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int matrix2[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int results[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
for (int u = 0; u < 3; u++)
results[i][j] += matrix1[i][u] * matrix2[u][j];
}
cout << endl << "Output Matrix: " << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << results[i][j] << ".";
}
cout << endl;
}
Your code for matrix multiplication is wrong. Look at this literal implementation:
for (i = 0; i < 3; i++){
for (j = 0; j < 3; j++){
product = 0;
for (k = 0; k < 3; k++){
product += matrix1[i][k] * matrix2[k][j];
}
matrix3[i][j] = product;
}
}
Matrix multiplication is implemented the following way (for 2 N x N matrices):
for i = 1..N
for j = 1..N
result[i][j] = 0.
for k = 1..N
result[i][j] += matrix1[i][k] * matrix2[j][k] // "row times column"
end for
end for
end for
This will return you the product result = matrix1 * matrix2. In C++ you have to use e.g.
for (int i = 0; i < N; i++)
for a loop. You have to start with 0 and end with N-1 (that's why you use < and not <=). In your example set int N = 3.
You only use a delete for every new. So you do not need to delete arrays if you do not allocate the matrix dynamically.

Why is my selection sort returning a value that is not in the original vector?

I've been tinkering around with it for a while now and I'm so close! Now the output seems to be continuously printing a zero as the first value of the "sorted" vector. This is homework on how to create a selection sort in C++.
Example Output
Vector: 6, 2, 11, 1, 12, 4
Sorted Vector: 0, 2, 11, 6, 12, 4
Code
void selectionSort (vector<int>& data)
{
int min, temp, n=data.size(), i, j;
for (i=0; i<n; i++)
{
min = i;
for (j=i+1; j<n; j++)
{
if (data[min]>data[j])
{
min=j;
}
temp=data[min];
data[min]=data[i];
data[i]=temp;
}
return;
}
}
int main()
{
int n;
vector<int> data;
cout<<"Vector length?: "<<endl;
cin>>n;
srand(time(0));
for (int i=0; i<n; i++)
{
data.push_back(rand()%20+1);
}
cout<<"Vector: "<<endl;
for (int i=0; i<n; i++)
{
cout<<data[i]<<" "<<endl;
}
selectionSort(data);
cout<<"Selection Sorted Vector: "<<endl;
for (int i=0; i<data.size(); i++)
{
cout<<data[i]<<" "<<endl;
}
system("Pause");
return 0;
}
Consider the following correct implementation of a selection sort and compare it to yours:
#include <iostream>
#include <vector>
void selection_sort(std::vector<int> &numbers)
{
// Iterate through all possible start indices.
for (int i = 0; i < numbers.size(); ++i)
{
// Determine the index of the minimum for this iteration.
int index_of_min = i;
for (int j = i; j < numbers.size(); ++j)
{
if (numbers[j] < numbers[index_of_min])
{
index_of_min = j;
}
}
// Swap the minimum element with the element at the start index.
int temp = numbers[i];
numbers[i] = numbers[index_of_min];
numbers[index_of_min] = temp;
}
}
int main()
{
std::vector<int> numbers = { 20, 17, 13, 12, 25 };
selection_sort(numbers);
for (size_t i = 0; i < numbers.size(); ++i)
{
std::cout << numbers[i] << " ";
}
}
Given an array of n elements, a selection sort performs n swaps.
You're performing far more swaps than that.
You also have an unexpectedly early call to return.
Let's look at a proper implementation of the sort:
#include <iostream>
#include <vector>
using namespace std;
void selectionSort (vector<int>& data)
{
const int n = data.size();
for (int i=0; i<n; i++)
{
int min = i;
for (int j=i+1; j<n; j++)
if (data[min]>data[j])
min = j;
swap(data[min], data[i]);
}
}
int main() {
vector<int> data = {6, 2, 11, 1, 12, 4};
selectionSort(data);
for (auto element : data)
cout << element << " ";
cout << "\n";
}
Which outputs:
1 2 4 6 11 12