How to counting sort two dimensional array - c++

Hi i have a problem with my code, i try sort array by counting sort (it must be stable sort), but my code doesn't work. I try implemented counting-sort from some wbesite, but it was in c# and I'm not sure s it done correctly. Can you tell me what is wrong with it?
#include <stdio.h>
#include <iostream>
using namespace std;
void sort_with_show(int **a, int rozmiar, int polecenie)
{
int y, d;
for (int i = 0; i< rozmiar - 1; i++)
{
for (int j = 0; j < rozmiar - 1 - i; j++)
{
if (a[j + 1][0] < a[j][0])
{
y = a[j][0];
a[j][0] = a[j + 1][0];
a[j + 1][0] = y;
}
}
}
for (int i = 0; i < rozmiar; i++)
{
//cout << tablica[i].x << " " << tablica[i].y << "\n";
if (polecenie == 0)
{
cout << a[i][0] << '\n';
}
else if (polecenie == 1)
{
cout << a[i][0] << "," << a[i][1] << "\n";
}
}
}
int main()
{
int rozmiar = 0;
int polecenie = 0;
char t[20] = { '\0' };
char *p, *q;
int liczba = 0;
int calaLiczba = 0;
bool isY = false;
cin >> rozmiar;
int ** a = new int *[rozmiar];
for (int i = 0; i < rozmiar; i++)
a[i] = new int[2];
cin.ignore();
int i = 0;
while(i < rozmiar)
{
fgets(t, sizeof t, stdin);
for (p = t, q = t + sizeof t; p < q; p++)
{
if (*p >= 48 && *p <= 57)
{
liczba = *p - 48;
calaLiczba = calaLiczba * 10 + liczba;
}
if (*p == ' ')
{
a[i][0] = calaLiczba;
isY = true;
calaLiczba = 0;
liczba = 0;
}
if (*p == '\n')
{
a[i][1] = calaLiczba;
isY = false;
}
}
for (int j = 0; j < 20; j++)
t[j] = '\0';
liczba = 0;
calaLiczba = 0;
isY = false;
i++;
}
cin >> polecenie;
cin.ignore();
sort_with_show(a, rozmiar, polecenie);
return 0;
}

Related

How to fix signal SIGSEGV, Segmentation fault

I'm getting an error message in Codeblocks C++ 'Program received signal SIGSEGV, Segmentation fault' in comparison between a vector element and a size of vector of vectors inside for loop (line 133 if (parz_przestrzenie[i] != parz_dystanse[i].size())).
Could anyone tell me why?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int bloki_parz[100000], bloki_nieparz[100000];
int silnia(int n)
{
int liczba = 1;
for (int i = 1; i <= n; i++)
{
liczba *= i;
}
return liczba;
}
int main()
{
int n, czapka, wolne_miejsca = 0, wynik = 1;
vector<int> parz, nieparz, parz_przestrzenie, nieparz_przestrzenie, parz_przestrzenie2, nieparz_przestrzenie2;
vector<vector<int>> parz_dystanse;
vector<vector<int>> nieparz_dystanse;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> czapka;
if (i % 2 == 0)
{
parz.push_back(czapka);
}
else
{
nieparz.push_back(czapka);
}
}
int parz_size = parz.size(), nieparz_size = nieparz.size();
// sprawdzamy czy dane nie sÂą sprzeczne ; gdy zabraknie nam miejsc do rozmieszczania
vector<int> parz_duplicate = parz;
vector<int> nieparz_duplicate = nieparz;
parz_duplicate.erase(unique(parz_duplicate.begin(), parz_duplicate.end()), parz_duplicate.end());
nieparz_duplicate.erase(unique(nieparz_duplicate.begin(), nieparz_duplicate.end()), nieparz_duplicate.end());
int parz_dupl_size = parz_duplicate.size(), nieparz_dupl_size = nieparz_duplicate.size();
if (parz_size < nieparz_dupl_size)
{
cout << 0 << endl;
return 0;
}
if (nieparz_size < parz_dupl_size)
{
cout << 0 << endl;
return 0;
}
for (int i = 0; i < parz_size - 1; i++)
{
if (parz[i] == parz[i + 1])
{
bloki_parz[i + 1] = 1;
}
}
for (int i = 0; i < nieparz_size - 1; i++)
{
if (nieparz[i] == nieparz[i + 1])
{
bloki_nieparz[i] = 1;
}
}
for (int i = 0; i < parz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < parz_size; j++)
{
if (parz[j] != parz[j + 1])
{
bloczek.push_back(parz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
parz_dystanse.push_back(bloczek);
}
}
int parz_dyst_size = parz_dystanse.size();
if (parz[parz_size - 1] != parz[parz_size - 2])
{
parz_dystanse[parz_dyst_size - 1].push_back(parz[parz_size - 1]);
}
for (int i = 0; i < nieparz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < nieparz_size; j++)
{
if (nieparz[j] != nieparz[j + 1])
{
bloczek.push_back(nieparz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
nieparz_dystanse.push_back(bloczek);
}
}
int nieparz_dyst_size = nieparz_dystanse.size();
int current_wynik = 0;
for (int i = 0; i < nieparz_size; i++)
{
if (bloki_parz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
parz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
parz_przestrzenie.push_back(current_wynik);
current_wynik = 0;
for (int i = 0; i < parz_size; i++)
{
if (bloki_nieparz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
nieparz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
nieparz_przestrzenie.push_back(current_wynik);
int parz_przest_size = parz_przestrzenie.size(), nieparz_przest_size = nieparz_przestrzenie.size();
for (int i = 0; i < 1; i++)
{
if (parz_przestrzenie[i] != parz_dystanse[i].size())
{
wynik *= parz_przestrzenie[i];
wolne_miejsca++;
}
}
for (int i = 0; i < nieparz_przest_size; i++)
{
if (nieparz_przestrzenie[i] != nieparz_dystanse[i].size())
{
wynik *= nieparz_przestrzenie[i];
wolne_miejsca++;
}
}
cout << wynik * silnia(wolne_miejsca) << endl;
}
parz_dystanse is a vector of a vector. In this case the return value of parz_dystanse.size() is a long unsigned int, whereas an element of parz_przestrzenie is an int.
You need to make explicit that parz_dystanse.size() returns an int in order to make comparitions between integer expressions of different signedness.
This will fix that problem:
if (parz_przestrzenie[i] != (int)parz_dystanse[i].size())

Why the simple multiplication would result in some garbled characters?

I try to design a program that implements the multiplication between two big integers(Using C++). But after I complete it, I found that if I input the two integers by the command arguments, the results would be sometimes very weird and sometimes right. Please help me figure out the reason and tell me how to fix it. Thanks (The main function that implements the function of multiplication between two big integers is mul() ).
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
void mul(char *c1, char *c2, int len1, int len2);
void printArr(char *c1, char *c2, int len1, int len2);
int main(int argc, char **argv)
{
if (argv[1] != NULL)
{
char cArr1[500], cArr2[500];
for (int i = 0; i < strlen(argv[1]); i++)
{
cArr1[i] = argv[1][i];
}
for (int i = 0; i < strlen(argv[2]); i++)
{
cArr2[i] = argv[2][i];
}
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
exit(100);
}
while (true)
{
cout << "Please input two integers" << endl;
char cArr1[500], cArr2[500];
cin >> cArr1;
if (cArr1[0] == 'q' && cArr1[1] == 'u' && cArr1[2] == 'i' && cArr1[3] == 't')
{
exit(1000);
}
cin >> cArr2;
int parity = 0;
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
if (cArr1[0] == '-')
{
for (int i = 1; i < len1; i++)
{
cArr1[i - 1] = cArr1[i];
}
parity++;
len1--;
}
if (cArr2[0] == '-')
{
for (int i = 1; i < len2; i++)
{
cArr2[i - 1] = cArr2[i];
}
parity++;
len2--;
}
bool isDigit = true;
for (int i = 0; i < len1; i++)
{
if (!isdigit(cArr1[i]))
{
isDigit = false;
}
}
for (int i = 0; i < len2; i++)
{
if (!isdigit(cArr2[i]))
{
isDigit = false;
}
}
if (!isDigit)
{
cout << "\rInvalid input. Try again" << endl;
continue;
}
if (parity % 2 != 0)
{
cout << "-";
}
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
}
}
void mul(char *bigger, char *smaller, int bigLen, int smallLen)
{
int *bigNum = new int[bigLen];
int *smallNum = new int[smallLen];
for (int i = 0; i < bigLen; i++)
{
bigNum[i] = bigger[bigLen - i - 1] - '0';
}
for (int i = 0; i < smallLen; i++)
{
smallNum[i] = smaller[smallLen - i - 1] - '0';
}
int res[30];
for (int i = 0; i < 30; i++)
{
res[i] = 0;
}
for (int i = 0; i < smallLen; i++)
{
for (int j = 0; j < bigLen; j++)
{
res[i + j] += bigNum[j] * smallNum[i];
}
}
for (int i = 0; i < bigLen + smallLen; i++)
{
int digit = res[i] % 10;
int carry = res[i] / 10;
res[i] = digit;
res[i + 1] += carry;
}
bool null = false;
for (int i = bigLen + smallLen - 1; i >= 0; i--)
{
if (res[i] != 0 && res[i + 1] == 0)
{
null = true;
}
if (null)
{
cout << res[i];
}
}
cout << endl;
}
void printArr(char *c1, char *c2, int len1, int len2)
{
for (int i = 0; i < len1; i++)
{
cout << c1[i];
}
cout << " * ";
for (int i = 0; i < len2; i++)
{
cout << c2[i];
}
cout << " = ";
}
Just initialize your char arrays to empty ones:
char cArr1[500] = {};
char cArr2[500] = {};
then, for the sake of clarity, assign the lengths from your arguments to two integers, casting them since the compiler might warn you about incompatibility between size_t and int.
int lenArg1 = 0;
int lenArg2 = 0;
lenArg1 = (int)strlen ( argv[1] );
lenArg2 = (int)strlen ( argv[2] );
Then, printing the lengths len1 and len2 for debugging purposes only:
int len1 = strlen ( cArr1 );
int len2 = strlen ( cArr2 );
cout << "len1 >> " + to_string(len1) <<endl;
cout << "len2 >> " + to_string(len2) <<endl;
In fact, as #Kevin SUN mentioned, it was possible that your argument reading steps were missing the null characters, however, after running some tests it seems to work fine just by initializing the char arrays.
Also, as mentioned in the comments you need to increase the size reserved for res array, I did it to 500
Compiled with g++ -Wall main.cpp -o calc.exe and running: calc 10 100
Without initialization you get problems like:
after initializing, the output works just fine:

compiling in linux using g++

I have following code which is simply tokenizing an array and then deviding on the basis of '<' and '>' characters. It is running fine in VS community 2019 but when I run it in Linux using g++ command it gives
Free(): invalid pointer
and
Aborted (core dumped)
errors. What am I doing wrong.
PS: error seems to be in the instructions where I am deallocating b in rangbrk and langbrk because when I put it in comments it runs fine in Linux too. But it runs fine in VS 2019 anyways.
//#include <sys/types.h>
//#include <sys/wait.h>
//#include <sys/stat.h>
#include <fcntl.h>
//#include <unistd.h>
#include<string.h>
#include<stdio.h>
#include<fstream>
#include<iostream>
#include<stdlib.h>
using namespace std;
//_________________________________________________________
int reads(char str[])
{//a simple function to get input
int s = 1;
char buffer[100];
cout << "enter command" << endl;
cin.getline(buffer, 100);
if (strlen(buffer) == 0)
{
cout << "Couldnt get input\n";
return 0;
}
for (int i = 0; i <= strlen(buffer); i++)
{
str[i] = buffer[i];
if (buffer[i] == 32)
s++;
}
return s;
}
//____________________________________________________________
int tokenizing(char** a, char str[], char buff[50], int x)
{//a function to devide a complete string into smaller parts
//also stores '/bin/command' into buff to pass as first parameter of execvp
int k = 0, m = 0;
bool check = false;
for (int i = 0; i < x; i++)
{
a[i] = new char[50];
for (int j = 0; str[k] != 32; j++)
{
if (str[k] == 0)
{
check = true;
break;
}
a[i][j] = str[k];
if (i == 0)
buff[j + 5] = str[k];
k++;
a[i][j + 1] = 0;
if (i == 0)
buff[j + 6] = 0;
}
m++;
k++;
if (check)
break;
}
return m;
}
//__________________________________________________________
void rangbrk(char**& a, char**& b, int& x, char filename[])
{//saperates the array before and after '>'
for (int i = 0; i < (x - 2); i++)
{
b[i] = new char[50];
for (int j = 0; j < 50; j++)
{
b[i][j] = a[i][j];
}
}
b[x - 2] = NULL;
for (int i = 0; i < 50; i++)
{
filename[i] = a[x - 1][i];
}
char** c;//temprory pointer to swap a and b
c = a;
a = b;
b = c;
x = x - 2;
for(int i=0;i<x-1;i++)
{
delete [] b[i];
}
b=NULL;
}
//__________________________________________________________
void langbrk(char** &a, char** &b, int& x, int index, char filename[])
{//saperates the array before and after '<'
int k = 0;
for (int i = 0; i < x; i++)
{
if ((i != index) && (i != index - 1))
{
b[k] = new char[50];
for (int j = 0; j < 50; j++)
{
b[k][j] = a[i][j];
}
k++;
}
}
b[x - 2] = NULL;
for (int i = 0; i < 50; i++)
{
filename[i] = a[index - 1][i];
}
char** c;//temprory pointer to swap a and b
c = a;
a = b;
b = c;
x = x - 2;
for(int i=0;i<x-1;i++)
{
if(b[i]!=NULL)
delete [] b[i];
}
b=NULL;
}
//__________________________________________________________
int main()
{
char buff[50] = { "/bin/" };
char str[100];
char exit[5] = { 'e','x','i','t',0 };
char outfile[50];
char infile[50];
int x = reads(str);
char** a;
a = new char* [x];
int s = tokenizing(a, str, buff, x);
a[s] = NULL;
bool flag = false;
for (int i = 0; a[i] != NULL; i++)
cout << a[i] << endl;
cout << s << endl;;
for (int i = 0; i < s; i++)
{
if (a[i][0] == '>')//checks if it need to print in a file
{
cout << i;
char** b;
b = new char* [s - 2];
rangbrk(a, b, s, outfile);
flag = true;
cout << "New" << endl;
for (int j = 0; j < s; j++)
cout << a[j] << endl;
i = 0;
}
else if (a[i][0] == '<')
{
cout << i;
char** c;
c = new char * [s - 2];
langbrk(a, c, s, i, infile);
cout << "New" << endl;
for (int j = 0; j < s; j++)
cout << a[j] << endl;
i = 0;
}
}
}
The reads function gets input, tokenizing tokenized the string in form of words. langbrk copies the string having index 1 less than index of '<' in infile and removes them both from main char** a. rangbrk removes '>' and string succeeding it from a and stores it in outfile

Program stops after cin - C++

I know this might be a duplicate to another question on this forum but I couldn't find the solution for my problem, even if I searched for like 1 hour.
The problem is that my program stops after the 4th "cin". I don't know why, I tried everything: "cin.ingore(); cin.clear();", "cin.get();".
Could someone help me please?
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
struct elev
{
char nume[20];
vector<int> note_info;
float medie;
};
int main()
{
int n, e = 0;
vector<elev> elevi;
cout << "n = "; cin >> n;
for (int i = 1; i <= n; i++)
{
int s = 0, nr;
elevi.push_back(elev());
cout << "Nume elev: "; cin >> elevi[i].nume;
cout << "Numar note informatica: "; cin >> nr;
for (int j = 0; j < nr; j++)
{
int temp;
cout << "Nota nr. " << j + 1 << ": "; cin >> temp;
elevi[i].note_info.push_back(temp);
s += temp;
}
elevi[i].medie = (float)(s / nr);
}
for (int i = 1; i <= n; i++)
{
for (int j = i; j <= n; j++)
{
if (elevi[j].medie != elevi[j + 1].medie)
{
e += 1;
}
}
}
if (e)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n - i; j++)
{
if (elevi[j].medie < elevi[j + 1].medie)
{
elev temp = elevi[j];
elevi[j] = elevi[j + 1];
elevi[j + 1] = temp;
}
}
}
}
else
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n - i; j++)
{
if (elevi[j].nume > elevi[j + 1].nume)
{
elev temp = elevi[j];
elevi[j] = elevi[j + 1];
elevi[j + 1] = temp;
}
}
}
}
cout << "Rezultate:";
for (int i = 1; i <= n; i++)
{
cout << '\n' << elevi[i].nume << ' ' << setprecision(2) << fixed << elevi[i].medie;
}
return 0;
}
Replace this line:
for (int i = 1; i <= n; i++)
with
for (int i = 0; i < n; ++i)
The error stems from trying to access the vector elevi at a position it doesn't yet have. Because vectors start indexing at 0, the first access made to elevi should be at index 0.

access violation writing location c++ for Gaussian Elimination

I am working on a code for gaussian reduction, but for some reason I am getting the error:
Exception thrown at 0x00A9F6DF in Excersise-7-3.exe: 0xC0000005: Access violation writing location 0xFDFDFDFD.
at S[h][0] = i; (line 147)
I cant seem to resolve this. What should I do? How can I prevent this from happening in the future?
#include "stdafx.h"
#include "Gauss.h"
#include <fstream>
Gauss::Gauss()
{
x.resize(v.size());
vector<double>::iterator it;
for (it = x.begin(); it != x.end(); it++)
{
v[*it] = 0;
}
S = new double*[m];
for (int i = 0; i < m; i++)
{
S[i] = new double[3];
for (int j = 0; j < 3; j++)
{
S[i][j] = 0;
}
}
}
Gauss::~Gauss()
{
}
bool Gauss::read_vector(string filename)
{
ifstream in;
in.open(filename);
if (in.fail())
{
cout << "File could not be opened." << endl;
return false;
}
in >> size;
for (int i = 0; i < size; i++)
{
int y;
in >> y;
v.push_back(y);
}
in.close();
return true;
}
bool Gauss::read_matrix(string filename)
{
ifstream in;
in.open(filename);
if (in.fail())
{
cout << "File could not be opened." << endl;
return false;
}
in >> m;
in >> n;
A = new double *[m];
for (int i = 0; i < m; i++)
{
A[i] = new double[n];
for (int k = 0; k < n; k++)
{
in >> A[i][k];
}
}
in.close();
return true;
}
void Gauss::print_vector()
{
for (int i = 0; i < size; i++)
cout << v[i] << endl;
}
void Gauss::print_matrix()
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cout << A[i][j] << " ";
}
cout << endl;
}
}
void Gauss::elimination(int &i, int &k)
for (int j = 0; j < m - 1; j++)
{
if(j != i)
{
double fraction = A[j][k] / A[i][k];
for (int l = 0; l < n; l++)
{
A[j][l] = A[j][l] - fraction*A[i][l];
v[j] = v[j] - fraction*v[i];
}
}
}
}
void Gauss::row_swap(int &i, int &k)
{
double sub;
for (int j = 0; j < n; j++)
{
sub = A[i][j];
A[i][j] = A[k][j];
A[k][j] = sub;
}
{
sub = v[i];
v[i] = v[k];
v[k] = sub;
}
}
void Gauss::reduction()
{
int h = 0;
int i = 0;
int k = 0;
while (i != m || k != n)
{
if (A[i][k] != 0)
{
elimination(i, k);
S[h][0] = i;
S[h][1] = k;
S[h][2] = A[i][k];
h++;
cout << h;
}
else
{
for (int j = i + 1; j < m; j++)
{
if (A[j][k] > 0)
{
row_swap(i, k);
elimination(i, k);
S[h][0] = i;
S[h][1] = k;
S[h][2] = A[i][k];
h++;
}
else
{
k++;
}
}
}
i++;
k++;
}
}
void Gauss::solution()
{
for (int j = 0; j < m; j++)
{
x[S[j][1]] = v[S[j][0]] / S[j][2];
}
}