I am working on a program that reads integers from file, stores it in vector and use count sort to sort the integers and write them in new file. My problem ocurs when i run Countsort function, the breakpoint happens at this for loop:
for (int i = 0; i < C.size(); i++) {
C[A[i]] = C[A[i]] + 1;
}
my code looks like this:
//COUNT SORT
void countsort() {
int max = A[0];
for (int i = 1; i < A.size(); i++) {
if (A[i] > max) {
max = A[i];
}
}
//cout << "NAJVECJE STEVILO JE: " << max << endl; SAMO ZA TEST
vector<int> C(max + 1);
vector<int> B(A.size());
for (int i = 0; i < C.size(); i++) {
C[A[i]] = C[A[i]] + 1;
}
for (int i = 1; i < C.size(); i++) {
C[i] = C[i] + C[i + 1];
}
for (int i = C.size() - 1; i >= 0; i--) {
B[C[A[i]] - 1] = A[i];
C[A[i]] = C[A[i]] - 1;
}
for (int i = 0; i < A.size(); i++) {
A[i] = B[i];
}
}
First you zero whole C vector
for (int i = 0; i < C.size(); i++)
{
C[i] = 0;
}
In second loop you may not change C[0] so it will remain 0
for (int i = 0; i < A.size(); i++)
{
C[A[i]] = C[A[i]] + 1;
}
In third loop in my analysis you never change C[0]
for (int i = C.size() - 1; i > 0; i-- )
{
C[i] = C[i] + C[i - 1];
}
In last loop
for (int i = A.size() - 1; i >= 0; i--)
{
B[C[A[i]] - 1] = A[i];
C[A[i]] = C[A[i]] - 1;
cout << B[i] << " ";
}
A[i] may equal 0, so C[A[i]] is C[0] and it might equal 0 from analysis of previous loops. When you subtract 1 from it, you'll end up with B[-1] which breaks your code.
Before you write something to B vector you should probably initialize it firt like you did with C.
B = vector<int>(A.size());
Also I don't see any point of printing B[i] as it may not be assigned any value when you print it.
Edit #1
Your loop is not correct. Take a look at this:
for (int i = 1; i < C.size(); i++) {
C[i] = C[i] + C[i - 1];
}
Edit #2
Try this code.
vector<int> A, B;
//COUNT SORT
void countsort() {
int max = A[0];
for (int i = 1; i < A.size(); i++) {
if (A[i] > max) {
max = A[i];
}
}
vector<int> C(max + 1);
B = vector<int>(A.size());
for (int i = 0; i < C.size(); i++) C[i] = 0;
for (int i = 0; i < A.size(); i++) C[A[i]] = C[A[i]] + 1;
for (int i = 1; i < C.size(); i++) C[i] = C[i] + C[i - 1];
for (int i = A.size() - 1; i >= 0; i--) {
B[C[A[i]] - 1] = A[i];
C[A[i]] = C[A[i]] - 1;
}
for (int i = 0; i < B.size(); i++) cout << B[i];
}
int main(void) {
A.push_back(1);
A.push_back(2);
A.push_back(3);
A.push_back(4);
A.push_back(2);
A.push_back(2);
A.push_back(1);
countsort();
}
Related
when I run the following code written to implement the suffix array algorithm, I get a segmentation fault. Can anyone please help me in solving it? I think the issue is with the while since cout in all other places work properly
Following is the code is used
vector<int> suffixArray(string s, int n)
{
vector<int> p(n); // Indexes
vector<int> c(n); // Classes
{
vector<pair<char, int>> a(n);
for (int i = 0; i < n; i++)
{
a[i] = {s[i], i};
}
sort(a.begin(), a.end());
for (int i = 0; i < n; i++)
p[i] = a[i].second;
c[p[0]] = 0;
for (int i = 1; i < n; i++)
{
if (a[i].first == a[i - 1].first)
{
c[p[i]] = c[p[i - 1]];
}
else
{
c[p[i]] = c[p[i - 1]] + 1;
}
}
}
int k = 0;
while (pow(2, k) < n)
{
vector<pair<pair<int, int>, int>> a;
for (int i = 0; i < n; i++)
{
a[i] = {{c[i], c[(int)(i + pow(2, k)) % n]}, i};
}
sort(a.begin(), a.end());
for (int i = 0; i < n; i++)
p[i] = a[i].second;
c[p[0]] = 0;
for (int i = 1; i < n; i++)
{
if (a[i].first == a[i - 1].first)
{
c[p[i]] = c[p[i - 1]];
}
else
{
c[p[i]] = c[p[i - 1]] + 1;
}
}
k++;
}
return p;
}
Thank You
I can't figure out where the error is.
vector<int> subVector(const vector<int>& a, const vector<int>& b) {
vector<int> res;
res = a;
for (int i = 0; i < res.size() && i < b.size(); i++)
{
if (res[i] < b[i])
{
int k = 1;
while (res[i + k] == 0)
k++;
for (int j = 0; j < k; j++)
{
res[i + j + 1]--;
res[i + j] += 10;
}
}
res[i] -= b[i];
}
return res;
}
vector<int> addVector(const vector<int>& a, const vector<int>& b) {
vector<int> ans;
ans.resize(max(a.size(), b.size()) + 1);
for (int i = 0; i < a.size(); i++)
ans[i] = a[i];
for (int i = 0; i < b.size(); i++)
{
ans[i] += b[i];
ans[i + 1] += ans[i] / 10;
ans[i] = ans[i] % 10;
int k = i + 1;
while (ans[k] >= 10)
{
ans[k + 1] += ans[k] / 10;
ans[k] %= 10;
k++;
}
}
return ans;
}
vector subscript out of range line 1475 and error debug.
I tried to fix it but couldn't. I can't understand how this error works.
Wherever you are accessing a vector with the [] operator, and inside it, you are doing some arithmetic operation, you need to make sure that the result is not exceeding the vector boundaries.
For example:
vector<int> subVector(const vector<int>& a, const vector<int>& b) {
vector<int> res;
res = a;
for (int i = 0; i < res.size() && i < b.size(); i++) <--- 'i' is promised to be in 'res' boundry
{
if (res[i] < b[i])
{
int k = 1;
while (res[i + k] == 0) <--- 'i+1' can exceeds the 'res' boundry
// Rest of the code ...
This is just one example. You are doing it all over your code.
void Counting_Sort(vector<int>& A)
{
const int size = A.size();
int max = A[0];
for (int i = 1; i < size; i++)
if (max > A[i])
max = A[i];
int* C = new int[max + 1]{ 0 };
for (int i = 0; i < max + 1; i++)
C[A[i]] = C[A[i]] + 1;
for (int i = 1; i < max + 1; i++)
C[i] = C[i] + C[i - 1];
int* B = new int[size];
for (int i = size-1; i >= 0; i--)
B[C[A[i]] - 1] = A[i]; // <-- Warning here
}
I'm not really sure why I get the warning or what exactly it means. Setting size-1 in for loop to size-2 removes the warning, but I don't uderstand why.
I notice four separate issues with your sample code:
The computation of maximum is incorrect. Your condition should be testing if (A[i] > max)
The Counting Sort algorithm's "accumulation step" should be iterating over the input data. That is, the loop should be the following (up to size, not up to max + 1):
for (int i = 0; i < size; i++)
C[A[i]] = C[A[i]] + 1;
The algorithm's final loop forgot to update the destination of each "Counting Sort bin". That is, the final loop should be the following:
for (int i = size - 1; i >= 0; i--) {
B[C[A[i]] - 1] = A[i];
C[A[i]] = C[A[i]] - 1;
}
Don't forget to use delete[] on B and C when you are done with them.
Here is the fully edited result:
#include <iostream>
#include <vector>
void Counting_Sort(std::vector<int>& A) {
const int size = A.size();
int max = A[0];
for (int i = 1; i < size; i++)
if (A[i] > max)
max = A[i];
int* C = new int[max + 1]{ 0 };
for (int i = 0; i < size; i++)
C[A[i]] = C[A[i]] + 1;
for (int i = 1; i < max + 1; i++)
C[i] = C[i] + C[i - 1];
int* B = new int[size];
for (int i = size-1; i >= 0; i--) {
B[C[A[i]] - 1] = A[i];
C[A[i]] = C[A[i]] - 1;
}
for (int i = 0; i < size; i++)
std::cout << "B[" << i << "] is " << B[i] << "\n";
delete[] B;
delete[] C;
}
int main() {
std::vector<int> A = {6, 1, 3, 3, 6, 9};
Counting_Sort(A);
return 0;
}
The compliler says that the size of B is 4xsize bytes long but in some cases, 8 bytes might be written, which might overpass the 4xsize bytes length.
Take the example of A = {10} for instance.
I have written this counting sort algorithm, but am not sure why it isn't working... Could anyone check and give me a few pointers on what to fix? Thanks!
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 10; k > 0; --k) {
C[k] = C[k] + C[k + 1];
}
int B[10];
for (int l = 0; l < 10; ++l) {
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}
The problem is in the third loop. You iterate only through 10 elements of the array C.
You had created small mistake in the code.....
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 1; k < 4219; ++k) { // mistake
C[k] = C[k] + C[k - 1];
}
int B[10];
for (int l = 9; l >=0; --l) { // suggestion
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}
Beside that I would like to give you one suggestion that in the loop traverse from right to left as it will maintain the stability of the sort..
Stability means suppose if array has two or more same element then in the stable sort,element which is before in unsorted array will occur first in sorted array.
all the arrays in this code are complex type in this code and the running time for this for loop is about 1 min. Ktemp is an array with size 141*1202*141. could anyone help me to optimize this code and save the running time?
complex<double> ***P1;
P1 = new complex<double>**[141];
for (i = 0; i < num_y; i++)
{
P1[i] = new complex<double> *[1202];
for (j = 0; j < tsize; j++)
{
P1[i][j] = new complex<double>[141];
}
}
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = excit_pfft[i][j][k] * expn[i][j][k];
}
}
}
}
excit_pfft = P1;
}
my second question is about rewriting matlab function 'fftshift' with C++. I have finished the code, but it seems not that efficient. could anyone help me rewrite this code? my code is attached below:
complex<double> ***fftw_shift(complex<double> ***te, int a, int b, int c)
{
complex<double> ***tempa;
tempa = new complex<double> **[a];
for (i = 0; i < a; i++)
{
tempa[i] = new complex<double> *[b];
for (j = 0; j < b; j++)
{
tempa[i][j] = new complex<double>[c];
}
}
/*for the row*/
if (c % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c / 2; k++)
{
tempa[i][j][k] = te[i][j][k + c / 2 + 1];
tempa[i][j][k + c / 2] = te[i][j][k];
tempa[i][j][c - 1] = te[i][j][c / 2];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c / 2; k++)
{
tempa[i][j][k] = te[i][j][k + c / 2];
tempa[i][j][k + c / 2] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the column*/
if (b % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b / 2; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + b / 2 + 1][k];
tempa[i][j + b / 2][k] = te[i][j][k];
tempa[i][b - 1][k] = te[i][b / 2][k];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b / 2; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + b / 2][k];
tempa[i][j + b / 2][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the third dimension*/
if (a % 2 == 1)
{
for (i = 0; i < a / 2; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + a / 2 + 1][j][k];
tempa[i + a / 2][j][k] = te[i][j][k];
tempa[a - 1][j][k] = te[a / 2][j][k];
}
}
}
}
else
{
for (i = 0; i < a / 2; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + a / 2][j][k];
tempa[i + a / 2][j][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
return (te);
}
Since you are repeatedly multiplying by the values in expn (i.e. calculating an exponent) you can do this more efficiently using the pow function and get rid of the zz loop:
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
excit_pfft[i][j][k] = 0;
}
else
{
excit_pfft[i][j][k] = excit_pfft[i][j][k] * pow(expn[i][j][k], 20);
}
}
}
}
Your code also seems to have a memory leak because you assign P1 to excit_pfft, but never free the previous contents of excit_pfft. You don't need to have the P1 temporary array in any case once you get rid of the outer loop.
I'm not sure of the internals of the complex pow() function, but you can calculate the (scalar) exponent of a complex number geometrically by converting it to polar co-ordinates (angle + distance scalar), then multiplying the angle by the power and raising the distance to the power, then converting back. So it's a lot faster than repeated multiplication.
First (will probably give you a big performance boost), get rid of the pointer arrays if you know beforehand the size of your arrays and simply allocate them in the stack:
complex<double> P1[141][1202][141];
Instead of :
complex<double> ***P1;
P1 = new complex<double>**[141];
for (i = 0; i < num_y; i++)
{
P1[i] = new complex<double> *[1202];
for (j = 0; j < tsize; j++)
{
P1[i][j] = new complex<double>[141];
}
}
And since I don't know exactly what this does, I'm assuming this:
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = excit_pfft[i][j][k] * expn[i][j][k];
}
}
}
}
excit_pfft = P1;
}
Could become this:
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = P1[i][j][k] * expn[i][j][k];
}
}
}
}
}
If this cannot be done than I'll need a more broad chunk of this code to analyze excit_pfft, etc.
A huge performance boost you could have is to use Worker Threads and run this last code multithreaded.
The same goes for our second question, Worker Threads should do it.
EDIT:
On second though, the stack won't be able to handle that much variables.
I'd recommend using vector<vector<vector<complex<double> > > > instead.