what's wrong with the counters in sorting functions - c++

in my program there are two sorting functions shaker and shell sorting functions, also in each sorting there are two counters, a count of the number of permutations and count of the number of comparisons, but for some reason they do not work, I just can’t understand why, I will be grateful for any help =)
void ShakerSort(ZKR* M, int N) {
int l, r, i, k, buf;
int q = 0;
int g = 0;
k = l = 0;
r = N - 2;
while(l <= r) {
for(i = l; i <= r; i++)
if(M[i].ACADEMIC_DEGREE > M[i + 1].ACADEMIC_DEGREE) {
q++;
buf = M[i].ACADEMIC_DEGREE;
M[i].ACADEMIC_DEGREE = M[i + 1].ACADEMIC_DEGREE;
M[i + 1].ACADEMIC_DEGREE = buf;
k = i;
}
g++;
r = k - 1;
for(i = r; i >= l; i--)
if(M[i].ACADEMIC_DEGREE > M[i + 1].ACADEMIC_DEGREE) {
q++;
buf = M[i].ACADEMIC_DEGREE;
M[i].ACADEMIC_DEGREE = M[i + 1].ACADEMIC_DEGREE;
M[i + 1].ACADEMIC_DEGREE = buf;
k = i;
}
g++;
l = k + 1;
}
cout << "Number of comparisons = " << q << endl;
cout << "Number of permutations = " << g << endl;
}
// SHELL SORT
void sortShell(ZKR* M, int N) {
int g = 0;
int q = 0;
int t = clock();
int step = N / 2;
while(step > 0) {
for(int i = 0; i < (N - step); ++i) {
q++;
int j = i;
while((j >= 0) && (M[j].ACADEMIC_DEGREE > M[j + step].ACADEMIC_DEGREE)) {
int tmp = M[j].ACADEMIC_DEGREE;
M[j].ACADEMIC_DEGREE = M[j + step].ACADEMIC_DEGREE;
M[j + step].ACADEMIC_DEGREE = tmp;
j -= step;
g++;
}
}
step /= 2;
}
cout << "Number of comparisons = " << q << endl;
cout << "Number of permutations = " << g << endl;
cout << "Время сортировки = " << clock() - t << "мили cекунд" << endl;
}

Related

How to resolve the segmentation fault in this code?

I am trying to make an infix calculator for which I am currently trying to convert numbers entered in a character array to double.
here's my code:
#include <iostream>
#include<cmath>
using namespace std;
int main()
{
char exp[500];
const int SIZE = 100;
char temp[SIZE];
char op;
int strLen = 0, k, l, num = 0, fnum = 0;
double number = 0;
cin.getline(exp, 500,'\n');
int i = 0, j = 0, fpoint=0;
cout << exp;
for (i = 0, j = 0; exp[j] != 0; i++)
{
if (i % 2 == 0)
{
for (int m = 0; exp[m] != ','; m++) //stopped working
temp[m] = exp[m];
cout << temp;
for (k = 0; k < SIZE && temp[k] != 0; k++)
{
strLen = k;
if (temp[k] == '.')
fpoint = k + 1;
}
cout << fpoint<<endl;
cout << "strLen" << strLen;
for (k = 0; k <= fpoint; k++)
{
num = num + ((temp[fpoint - k] - '0') * pow(10, k));
}
for (k = fpoint + 1, l = 0; k <= strLen; k++, l++)
{
fnum = fnum + ((temp[strLen - l] - '0') * pow(10, l));
}
number = num + (fnum / pow(10, strLen - fpoint + 1));
cout << number;
j = j + strLen + 1;
}
else
{
char op = temp[j];
cout << op;
}
}
system("pause");
return 0;
}
sample input
2.5*3
It stops working and gives segmentation fault as an error on the marked position.
This line for (int m = 0; exp[m] != ','; m++) //stopped working will always fail if there are no , characters since exp[m] != ',' will always be equal to true and so will reach beyond the end of the array of exp which triggers the "segmentation fault".

why is the zero changing in c++

so i'm new to c++. i have to make a program where you enter a number and it displays the largest possible number and the smallest one, with the same digits as the entered number. But when the entered number has 0 it changes to 4310160
sorry for my english;{
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int m[10], i, l, x, c, ok, r;
cout << "x= ";
cin >> x;
l = 0;
while (x > 0) {
c = x % 10;
m[l] = c;
l++;
x = x / 10;
}
do {
ok = 1;
for (i = 0; i < l; i++)
if (m[i] < m[i + 1]) {
r = m[i];
m[i] = m[i + 1];
m[i + 1] = r;
ok = 0;
}
for (i = 0; i < l; i++) {
cout << m[i] << ", ";
}
cout << endl;
} while (ok != 1);
cout << "largest= ";
for (i = 0; i < l; i++) {
cout << m[i];
}
cout << endl;
do {
ok = 1;
for (i = 0; i < l; i++)
if (m[i] > m[i + 1]) {
r = m[i];
m[i] = m[i + 1];
m[i + 1] = r;
ok = 0;
}
} while (ok != 1);
if (m[0] == 0) {
r = m[0];
m[0] = m[1];
m[1] = r;
}
cout << "smallest= ";
for (i = 0; i < l; i++) {
cout << m[i];
}
return 0;
}
if x == 0, you do
if (m[0] == 0) {
r = m[0];
m[0] = m[1];
m[1] = r;
}
With uninitialized m, leading to undefined behavior.
The int m[10] array in main is stored in the stack and its elements initialized to indeterminate values as explained in array_initialization and initialization.
So if x == 0 , the program should print nothing as l will be 0 and it won't enter in any loop.
If you see 4310160 because you are debugging, it is because m[10] elements are initialized to indeterminate values (normally, the value at the stack in that moment.)
You may see here that local, non static data is stored in the stack.

vector is out of range,but why?

It says my vector is out of range for ArrayD. But I do not understand why. Everything else works. Is says that the vector is out of range after double deez. Therefore, it will not ascend fully.
using namespace std;
void hello();
void Infile();
double x, y, z;
double P, B;
int E = 0;
double V[16];
double C[16];
double D[16];
int m, n;
int main()
{
Infile();
return 0;
}
void Infile()
{
ifstream fileA("P_matrix.txt");
ifstream fileB("b_matrix.txt");
ifstream fileC("d_matrix.txt");
vector<double>ArrayP;
vector<double>ArrayB;
vector<double>ArrayD;
cout << "P Matrix Values \n";
while (fileA.good())
{
fileA >> P;
ArrayP.push_back(P);
}
for (int i = 0; i<ArrayP.size(); i++)
{
cout << ArrayP[i] << ",";
}
system("pause");
cout << "B Matrix Values \n";
while (fileB.good())
{
fileB >> B;
ArrayB.push_back(B);
}
for (int j = 0; j < 16; j++)
{
cout << ArrayB[j] << ",";
}
system("pause");
while (fileC.good())
{
fileC >> D;
ArrayD.push_back(D);
}
for (int k = 0; k <16; k++)
{
cout << ArrayD[k] << ",";
}
system("pause");
for (int m = 0; m < 16; m++)
{
V[m] = ArrayP[m] * ArrayB[m];
cout << V[m] << ",";
}
system("pause");
for (int n = 0; n < 16; n++)
{
C[n] = V[n] * ArrayD[n];
cout << C[n] << ",";
}
//outfile.close();
system("pause");
double deez;
for (int d = 0; d < 16; d++) //acscending
{
for (int q = 0; q < 16; q++)
{
if (ArrayD[q] < ArrayD[q - 1])
{
deez = ArrayD[q];
ArrayD[q] = ArrayD[q - 1];
ArrayD[q - 1] = deez;
}
}
}
for (int q = 0; q < 16; q++)
cout << C[q] << ",";
system("pause");
double nutz;
for (int d = 0; d < 16; d++) //descending
{
for (int q = 0; q < 16; q++)
{
if (V[q] < V[q + 1])
{
nutz = V[q];
V[q] = V[q + 1];
V[q + 1] = nutz;
}
}
}
for (int q = 0; q < 16; q++)
cout << V[q] << ",";
system("pause");
return;
}
Here, q starts at zero, so you are attempting to access index [-1].
ArrayD[q - 1]
When iterating over ArrayP, you correctly do:
for (int i = 0; i<ArrayP.size(); i++)
However for ArrayB and ArrayC, you seem to assume there are only ever 16 elements in those arrays (are you sure?). I can't see any evidence that the arrays are restricted to always having 16 elements in code, so that could also be the issue.
Later still, you then seem to assume all of those arrays have 16 elements?
for (int m = 0; m < 16; m++)
{
V[m] = ArrayP[m] * ArrayB[m];
cout << V[m] << ",";
}
Those are the obvious places that could cause an out of range error.

I need this number pyramid to print out a specific sequence of numbers to the console?

I need a Number pyramid identical to this one:
1
121
12321
1234321
123454321
12345654321
I am new to programming and if anyone would't mine running through the code and telling me how each line is being understood by the compiler.
I heard there was a way to do this with embedded while loops. If anyone knows how to do that and can show me, that would be great.
The code I have is partially from the internet and not solely mine.
for (int i = 1; i <= rows; ++i)
{
for (int space = 1; space <= rows - i; ++space)
{
cout << " ";
++count;
}
while (k != 2 * i - 1)
{
if (count <= rows - 1)
{
cout << i << " ";
++count;
}
else
{
++count1;
cout << i + k - 2 * count1 << " ";
}
++k;
}
count1 = count = k = 0;
cout << endl;
}
cout << "\n\n\n";
system("PAUSE");
Try this code:
int main(void) {
int i, j, k, l, n = 6;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n - i; j++) {
cout << " ";
}
for (k = 1; k <= i; k++) {
cout << k;
}
for (l = i - 1; l >= 1; l--) {
cout << l;
}
cout << "\n";
}
return 0;
}

Smith Waterman for C++ (Visual Studio 14.0)

I would like to kill two birds with one stone, as the questions are very similiar:
1:
I followed this code on github Smith Waterman Alignment to create the smith-waterman in C++. After some research I understood that implementing
double H[N_a+1][N_b+1]; is not possible (anymore) for the "newer" C++ versions. So to create a constant variable I changed this line to:
double **H = new double*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
H[i] = new double[nSynth + 1];
and also the same scheme for int I_i[N_a+1][N_b+1], I_j[N_a+1][N_b+1]; and so one (well, everywhere, where a two dimensional array exists). Now I'm getting the exception:
Unhandled exception at 0x00007FFF7B413C58 in Smith-Waterman.exe: Microsoft C
++ exception: std :: bad_alloc at location 0x0000008FF4F9FA50.
What is wrong here? Already debugged, and the program throws the exceptions above the for (int i = 0; i < nReal + 1; i++).
2: This code uses std::strings as parameters. Would it be also possible to create a smith waterman algortihm for cv::Mat?
For maybe more clarification, my full code looks like this:
#include "BinaryAlignment.h"
#include "WallMapping.h"
//using declarations
using namespace cv;
using namespace std;
//global variables
std::string bin;
cv::Mat temp;
std::stringstream sstrMat;
const int maxMismatch = 2;
const float mu = 0.33f;
const float delta = 1.33;
int ind;
BinaryAlignment::BinaryAlignment() { }
BinaryAlignment::~BinaryAlignment() { }
/**
*** Convert matrix to binary sequence
**/
std::string BinaryAlignment::matToBin(cv::Mat src, std::experimental::filesystem::path path) {
cv::Mat linesMat = WallMapping::wallMapping(src, path);
for (int i = 0; i < linesMat.size().height; i++) {
for (int j = 0; j < linesMat.size().width; j++) {
if (linesMat.at<Vec3b>(i, j)[0] == 0
&& linesMat.at<Vec3b>(i, j)[1] == 0
&& linesMat.at<Vec3b>(i, j)[2] == 255) {
src.at<int>(i, j) = 1;
}
else {
src.at<int>(i, j) = 0;
}
sstrMat << src.at<int>(i, j);
}
}
bin = sstrMat.str();
return bin;
}
double BinaryAlignment::similarityScore(char a, char b) {
double result;
if (a == b)
result = 1;
else
result = -mu;
return result;
}
double BinaryAlignment::findArrayMax(double array[], int length) {
double max = array[0];
ind = 0;
for (int i = 1; i < length; i++) {
if (array[i] > max) {
max = array[i];
ind = i;
}
}
return max;
}
/**
*** Smith-Waterman alignment for given sequences
**/
int BinaryAlignment::watermanAlign(std::string seqSynth, std::string seqReal, bool viableAlignment) {
const int nSynth = seqSynth.length(); //length of sequences
const int nReal = seqReal.length();
//H[nSynth + 1][nReal + 1]
double **H = new double*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
H[i] = new double[nSynth + 1];
cout << "passt";
for (int m = 0; m <= nSynth; m++)
for (int n = 0; n <= nReal; n++)
H[m][n] = 0;
double temp[4];
int **Ii = new int*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
Ii[i] = new int[nSynth + 1];
int **Ij = new int*[nReal + 1];
for (int i = 0; i < nReal + 1; i++)
Ij[i] = new int[nSynth + 1];
for (int i = 1; i <= nSynth; i++) {
for (int j = 1; j <= nReal; j++) {
temp[0] = H[i - 1][j - 1] + similarityScore(seqSynth[i - 1], seqReal[j - 1]);
temp[1] = H[i - 1][j] - delta;
temp[2] = H[i][j - 1] - delta;
temp[3] = 0;
H[i][j] = findArrayMax(temp, 4);
switch (ind) {
case 0: // score in (i,j) stems from a match/mismatch
Ii[i][j] = i - 1;
Ij[i][j] = j - 1;
break;
case 1: // score in (i,j) stems from a deletion in sequence A
Ii[i][j] = i - 1;
Ij[i][j] = j;
break;
case 2: // score in (i,j) stems from a deletion in sequence B
Ii[i][j] = i;
Ij[i][j] = j - 1;
break;
case 3: // (i,j) is the beginning of a subsequence
Ii[i][j] = i;
Ij[i][j] = j;
break;
}
}
}
//Print matrix H to console
std::cout << "**********************************************" << std::endl;
std::cout << "The scoring matrix is given by " << std::endl << std::endl;
for (int i = 1; i <= nSynth; i++) {
for (int j = 1; j <= nReal; j++) {
std::cout << H[i][j] << " ";
}
std::cout << std::endl;
}
//search H for the moaximal score
double Hmax = 0;
int imax = 0, jmax = 0;
for (int i = 1; i <= nSynth; i++) {
for (int j = 1; j <= nReal; j++) {
if (H[i][j] > Hmax) {
Hmax = H[i][j];
imax = i;
jmax = j;
}
}
}
std::cout << Hmax << endl;
std::cout << nSynth << ", " << nReal << ", " << imax << ", " << jmax << std::endl;
std::cout << "max score: " << Hmax << std::endl;
std::cout << "alignment index: " << (imax - jmax) << std::endl;
//Backtracing from Hmax
int icurrent = imax, jcurrent = jmax;
int inext = Ii[icurrent][jcurrent];
int jnext = Ij[icurrent][jcurrent];
int tick = 0;
char *consensusSynth = new char[nSynth + nReal + 2];
char *consensusReal = new char[nSynth + nReal + 2];
while (((icurrent != inext) || (jcurrent != jnext)) && (jnext >= 0) && (inext >= 0)) {
if (inext == icurrent)
consensusSynth[tick] = '-'; //deletion in A
else
consensusSynth[tick] = seqSynth[icurrent - 1]; //match / mismatch in A
if (jnext == jcurrent)
consensusReal[tick] = '-'; //deletion in B
else
consensusReal[tick] = seqReal[jcurrent - 1]; //match/mismatch in B
//fix for adding first character of the alignment.
if (inext == 0)
inext = -1;
else if (jnext == 0)
jnext = -1;
else
icurrent = inext;
jcurrent = jnext;
inext = Ii[icurrent][jcurrent];
jnext = Ij[icurrent][jcurrent];
tick++;
}
// Output of the consensus motif to the console
std::cout << std::endl << "***********************************************" << std::endl;
std::cout << "The alignment of the sequences" << std::endl << std::endl;
for (int i = 0; i < nSynth; i++) {
std::cout << seqSynth[i];
};
std::cout << " and" << std::endl;
for (int i = 0; i < nReal; i++) {
std::cout << seqReal[i];
};
std::cout << std::endl << std::endl;
std::cout << "is for the parameters mu = " << mu << " and delta = " << delta << " given by" << std::endl << std::endl;
for (int i = tick - 1; i >= 0; i--)
std::cout << consensusSynth[i];
std::cout << std::endl;
for (int j = tick - 1; j >= 0; j--)
std::cout << consensusReal[j];
std::cout << std::endl;
int numMismatches = 0;
for (int i = tick - 1; i >= 0; i--) {
if (consensusSynth[i] != consensusReal[i]) {
numMismatches++;
}
}
viableAlignment = numMismatches <= maxMismatch;
return imax - jmax;
}
Thanks!