Qsort strange behaviour c++ - c++

here is my code of qsort in c++.
#include <stdio.h>
void partition(int* arr, int start, int pivot, int end){
int i=start+1;
for(int j=start+1; j < end; j++){
if (arr[j]<pivot){
int c=arr[i];
arr[i]=arr[j];
arr[j]=c;
i++;
}
}
int c=arr[start];
arr[start]=arr[i-1];
arr[i-1]=c;
}
void qsort(int *arr, int start, int end, int len){
if (len<=1){
// break;
}
else{
int pivot=arr[start];
partition(arr, start, pivot, end);
qsort(arr, start, pivot-1, len-1);
qsort(arr, pivot+1, end, len-1);
}
}
int main(){
int len;
printf("Vvedite kolvo elementov");
scanf("%d", &len);
int *arr=new int[len];
for(int i=0;i<len; i++){
printf("\n Vvedite %d element", i);
scanf("%d", &arr[i]);
}
qsort(arr, 0, len, len);
for(int i=0; i<len; i++){
printf(" %d, ", arr[i]);
}
delete [] arr;
return 0;
}
But it has very strange output. For example - it works ok on "5 1 2 4 3" and sorts it, but when i for example type "998 603 805 990 900" that in theory absolutly the same for computer, it prints all 0.
Any suggestions on how to identify/fix the problem are greatly appreciated.

Related

fopen() gives me malloc(): corrupted top size

I am trying to write the contents of an array, to a binary file, but it gives the following errors when I run the file.
malloc(): corrupted top size
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
Here is my code
#include <iostream>
#include <time.h>
#include <fstream>
#include <iostream>
using namespace std;
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4
#define FIVE 5
#define SIX 6
#define SEVEN 7
int getArrayLength();
void initializeArray(int *array, int length);
void printArray(int *array, int length);
void menu(int *array, int length);
void userChoice(int userInput, int *array, int length);
void serialSearch(int *array, int length, int givenNumber);
void quickSort(int *array, int start, int end);
int partition(int *array, int start, int end);
void substitute(int *firstElement, int *secondElement);
int binarySearch(int *array, int start, int end, int userChoice);
void arrayConcatenation(int *firstArray, int *secondArray, int *concatenatedArray, int length, int doubleLength);
int main() {
int arrayLength = getArrayLength();
int *randomNumbersArray = (int *) malloc(arrayLength * sizeof (int));
initializeArray(randomNumbersArray, arrayLength);
printArray(randomNumbersArray, arrayLength);
menu(randomNumbersArray, arrayLength);
return 0;
}
int getArrayLength()
{
int size;
cout<<"Please give the size of the array: ";
cin>>size;
return size;
}
void initializeArray(int *array, int length)
{
srand(time(nullptr));
for(int i = 0; i < length; i++)
*(array + i) = 30 + rand() % 21;
}
void printArray(int *array, int length)
{
for(int i = 0; i < length; i++)
cout<<*(array + i)<<" ";
cout<<endl;
}
void menu(int *array, int length)
{
int userInput;
cout<<" Array Functions"<<"\n"<<endl;
do {
cout<<"1. Serial Search"<<endl;
cout<<"2. Array Classification"<<endl;
cout<<"3. Binary Search (classifies the array automatically)"<<endl;
cout<<"4. Concatenation of classified arrays"<<endl;
cout<<"5. Print"<<endl;
cout<<"6. Save and read array with binary file"<<endl;
cout<<"7. Exit"<<"\n"<<endl;
cout<<"Please enter your choice: ";
cout<<endl;
cin>>userInput;
userChoice(userInput, array, length);
} while (userInput != SEVEN);
}
void userChoice(int userInput, int *array, int length)
{
FILE *myFile;
int mergedLength = 2 * length;
int *secondArray = (int *) malloc(length * sizeof (int));
int *mergedArray = (int *) malloc(length * sizeof (int));
initializeArray(secondArray, length);
initializeArray(mergedArray, mergedLength);
switch(userInput)
{
case ONE:
{
int givenNumber;
serialSearch(array, length, givenNumber);
break;
}
case TWO:
{
quickSort(array, 0, length-ONE);
cout<<"This is the sorted array."<<endl;
printArray(array, length);
break;
}
case THREE:
{
int choice, existence;
cout<<"What number you want?"<<endl;
cin>>choice;
quickSort(array, 0, length-ONE);
existence = binarySearch(array, 0, length-ONE, choice);
if (existence == -ONE)
cout<<"The chosen number is not in the array."<<endl;
else
cout<<"The number is at index "<<existence<<"."<<endl;
break;
}
case FOUR:
{
quickSort(array, 0, length-ONE);
quickSort(secondArray, 0, length-ONE);
arrayConcatenation(array, secondArray, mergedArray, length, mergedLength);
quickSort(mergedArray, 0, mergedLength - ONE);
cout<<"This is the first array in order"<<endl;
printArray(array, length);
cout<<"This is the second array in order."<<endl;
printArray(secondArray, length);
cout<<"This is the merged array in order."<<endl;
printArray(mergedArray, mergedLength);
myFile = fopen("binarydata.dat", "wb");
if(myFile == NULL)
{
cout<<"Error in file opening."<<endl;
exit(0);
}
fwrite(array, sizeof (int ), length, myFile);
fclose(myFile);
break;
}
}
free(secondArray);
free(mergedArray);
}
void serialSearch(int *array, int length, int givenNumber)
{
int flag = -ONE;
cout<<"Please give the number that you want to find in the array: ";
cin>>givenNumber;
for(int i = 0; i < length; i++)
{
if(*(array + i) == givenNumber)
{
cout<<"The number was found at position: "<<i<<"\n"<<endl;
flag = 0;
break;
}
}
if(flag == -1)
cout<<"The number is not in the array."<<"\n"<<endl;
}
void quickSort(int *array, int start, int end)
{
if (start < end)
{
int driver = partition(array, start, end);
quickSort(array, start, driver-ONE);
quickSort(array, driver+ONE, end);
}
}
int partition(int *array, int start, int end)
{
int key = *(array + end);
int i = start - ONE;
for(int j = start; j < end; j++)
{
if(*(array + j) <= key)
{
i++;
substitute((array + i), (array + j));
}
}
substitute((array +i + ONE), (array + end));
return(i + ONE);
}
void substitute(int *firstElement, int *secondElement)
{
int temp = *firstElement;
*firstElement = *secondElement;
*secondElement = temp;
}
int binarySearch(int *array, int start, int end, int userChoice)
{
if(end >= start)
{
int middle = start + (end - start)/2;
if(*(array + middle) == userChoice)
return middle;
if(*(array + middle) > userChoice)
return binarySearch(array, start, middle-1, userChoice);
return binarySearch(array, middle+1, end,userChoice);
}
return -1;
}
void arrayConcatenation(int *firstArray, int *secondArray, int *concatenatedArray, int length, int doubleLength)
{
for(int i = 0; i < length; i++)
*(concatenatedArray + i) = *(firstArray + i);
for(int i = 0; i < length; i++)
*(concatenatedArray + i + length) = *(secondArray + i);
}
The problem is in the case FOUR of the switch case part of the code.

All Strings of {A,C,T,G}

I'm currently working on a problem of solving the combination of the different length of {A,C,T,G}, from 1 letter to 6 letters.
For example:
------#=1------
1:A
2:C
3:G
4:T
------#=2------
1:AA
2:AC
3:AG
4:AT
5:CA
6:CC
7:CG
8:CT
9:GA
10:GC
11:GG
12:GT
13:TA
14:TC
15:TG
16:TT
------#=3------
1:AAA
2:AAC
3:AAG
4:AAT
5:ACA
.
.
.
Now I can only solve the combinations from 1 to 4 letters, and I have no idea how to solve the combination of {A,C,T,G} of 5 letters and 6 letters, which the length of the combination(5 and 6) is greater than the length of all the strings(4)....
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
void combinationUtil(char arr[], char data[], int start, int end, int index, int r);
void printCombination(char arr[], int n, int r)
{
char data[100];
combinationUtil(arr, data, 0, n-1, 0, r);
}
void combinationUtil(char arr[], char data[], int start, int end, int index, int r)
{
if (index == r) {
for (int j=0; j<r; j++)
cout << data[j];
cout << endl;
return;
}
for (int i=start; i<=end && end-i+1 >= r-index; i++)
{
data[index] = arr[i];
combinationUtil(arr, data, i+1, end, index+1, r);
}
}
int main()
{
char arr[] = {'A','T','C','G'};
int n = sizeof(arr)/sizeof(arr[0]);
printCombination(arr, n, 1);
printCombination(arr, n, 2);
printCombination(arr, n, 3);
printCombination(arr, n, 4);
printCombination(arr, n, 5);
system("pause");
}
At least assuming I understand what you want, this is pretty easy to solve by treating it as counting from 0 to some limit in base 4, with the "digits" displayed as "A", "C", "G" and "T".
#include <string>
#include <iostream>
std::string cvt(unsigned input, unsigned len) {
std::string ret;
static const char letters[] = "ACGT";
for (int i=0; i<len; i++) {
ret.push_back(letters[input%4]);
input /= 4;
}
return ret;
}
int main() {
unsigned limit = 1;
unsigned length = 4;
for (int i=0; i<4; i++)
limit *= 4;
for (int i=0; i<limit; i++)
std::cout << cvt(i, length) << "\n";
}
Your code assumes each letter can only be used once. That's why you are getting no results for both sequences of length 5 and 6. Rewrite your function as the following and do not pass as start or end value to it:
void combinationUtil(char arr[], char data[], int index, int r)
{
if (index == r)
{
for (int j=0; j<r; ++j)
cout << data[j];
cout << endl;
return;
}
for (int i=0; i<r; ++i)
{
data[index] = arr[i];
combinationUtil(arr, data, index+1, r);
}
}

Infinite computation of qsort

i am realsing qsort algorithm, according on Korman. But there is infinite computation, when i trying to start it. I suppose, that problem is in partition. My programms reads from file, first number in file-line is counting of numbers to sort, and next go all numbers
#include <stdio.h>
#include <stdlib.h>
int swap(int &a, int &b);
int sorting(int *array, int &b, int &l);
int partition(int *array ,int &begin, int &last);
int main()
{
FILE* pFile=fopen("input.txt", "r");
//fopen("input.txt", "r");
//fopen("output.txt", "w");
int n;
int begin=0;
fscanf(pFile, "%d", &n);
int* array=(int*)malloc(n*sizeof(int));
for (int i=0; i<n; ++i)
fscanf(pFile,"%d", &array[i]);
int n1=n-1;
sorting(array, begin, n1);
printf("JJJJ");
for (int i=0; i<n; ++i)
printf("%d ", array[i]);
printf("\n");
fclose(pFile);
free(array);
return 0;
}
int sorting(int* array, int &b, int &l)
{
int pivot,pivot1;
if(b<l)
{
pivot=partition(array, b, l);
printf("MAXMAX321");
int a=pivot-1;
sorting(array, b, a);
printf("MAXMAX123");
pivot1=pivot+1;
sorting(array, pivot1, l);
printf("MAXMAX");
}
return 0;
}
int partition(int* array, int &b, int &l)
{
int x=array[b];
int i=b;
int j=l;
while(true)
{
while(array[j]>x){
printf("AHAH");
--j;
}
while(array[i]<x){
printf("AZAZA");
++i;
}
if(i<j)
swap(array[i],array[j]);
else
return j;
}
}
int swap(int &x, int &y)
{
x=x+y;
y=x-y;
x=x-y;
return 0;
}
Thank you in advance.
This part is very dangerous code:
while(true)
{
while(array[j]>x){
printf("AHAH");
--j;
}
while(array[i]<x){
printf("AZAZA");
++i;
}
if(i<j)
swap(array[i],array[j]);
else
return j;
}
Avoid while (true) as much as possible, except on very special case you should have a clear condition stated in the loop. Here it is the one that leads to `return. It will clarify the goal of the loop.
When testing array value like while(array[i]<x) compare i to the array size before ! You're never sure that you condition will always be met in the array, ensure you have a safety belt.
I cannot understand what you are doing in function partition but doing it like this should work:
int partition(int* array, int &b, int &l)
{
int pivot_index = l;//You can take here everything between b and l
//swap(array[l], array[pivot_index]); decomment this if your pivot is between b and l
int current_pos = b;
for(int i = b;i < l - 1; ++i)
if(array[i] <= array[pivot_index])
swap(array[i], array[current_pos++]);
swap(array[l], array[current_pos]);
return current_pos;
}

Multiplying matrices using pointers

Hey guys I am trying practice learning pointers in c++. So I am trying to multiply these arrays and am getting all 0's in my resulting matrix. if anybody could just hint to me what to look at or some advice on what is causing this that would be amazing.
Here is the code:
#include <stdio.h>
#include<conio.h>
#include <stdlib.h>
#include <iostream>
/* Routines called. */
int loadMatrixFromFile(char *filename, int *data);
void showMatrix(int *data, int len);
int makeIdent(int matrixB[5][5], int length);
int matrixA[5][5];
int matrixB[5][5];
int matrixC[5][5];
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]);
int main(){
int len, data[1000];
len = loadMatrixFromFile("Numbers.txt", data);
showMatrix(data, len);
makeIdent(matrixB, len);
multiplyMatrices(matrixA, matrixB, matrixC);
}
int makeIdent(int matrixB[5][5], int len){
int i,j;
int *ptr;
ptr = &matrixB[5][5];
printf("Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==j){
*ptr=1;
printf("%d ", *ptr);
}
else{
*ptr=0;
printf("%d ",*ptr);
}
}
printf("\n");
}
return *ptr;
printf("\n");
}
int loadMatrixFromFile(char *filename, int *data){
FILE *in;
int len;
int j;
in = fopen(filename, "r");
if (in == NULL) {
printf("Could not find file: %s \n", filename);
}
else {
printf("Reading numbers...\n");
fscanf(in, "%d", &len);
printf("reading %d numbers from file %s ....\n", len, filename);
for(j=0;j<len;j++) {
fscanf(in, "%d", data + j);
}
fclose(in);
}
for(int i = 0; i<5; i++){
for(int j = 0; j < 5; j++){
matrixA[i][j] = *(data + i*5 + j);
}
}
return len;
}
void showMatrix(int *data, int len){
int j;
int count = 0;
printf("Showing %d numbers from data array....\n", len);
printf("Matrix A is: \n");
for(j=0;j<len;j++) {
printf("%d ", *(data + j));
count++;
if(count % 5 == 0){
printf("\n");
}
}
printf("\n");
}
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
int i, n, j;
int *ptr1, *ptr2, *ptr3;
ptr1 = &matrixA[5][5];
ptr2 = &matrixB[5][5];
ptr3 = &matrixC[5][5];
printf("\n");
printf("Matrix A x Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
*ptr3=0;
}
}
for (i = 0; i<5; i++){
for (j = 0; j<5; j++){
for(n=0;n<5;n++){
*ptr3 += (*ptr1**ptr2);
}
printf("%d ",*ptr3);
}
printf("\n");
}
}
In makeIdent you need to increment ptr after each element. To
initialize ptr you need to point it to the first element in the array, not the last element.
int makeIdent(int matrixB[5][5], int len){
int i,j;
int *ptr;
ptr = &matrixB[0][0]; // note the 0 instead of the 5
printf("Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==j){
*ptr=1;
printf("%d ", *ptr);
}
else{
*ptr=0;
printf("%d ",*ptr);
}
ptr++; // this is new
}
printf("\n");
}
return 0;
}
This is closer to what you want for multiplyMatrices:
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
int i, n, j;
int *ptr1, *ptr2, *ptr3;
ptr1 = &matrixA[0][0];
ptr2 = &matrixB[0][0];
ptr3 = &matrixC[0][0];
for (i = 0; i<5; i++) {
for (j = 0; j<5; j++) {
*ptr3 = (*ptr1 * *ptr2);
ptr1++; ptr2++; ptr3++;
}
}
}
You could say this instead:
*ptr3++ = *ptr1++ * *ptr2++;
But I don't want to confuse the issue.

Multiplying 2 matrices using pointers

so I am trying to figure out how to multiply 2 matrices using pointers. It successfully works the way it is now, but instead of using conventional array access methods, I would like to learn the use of pointers.
Here is my code:
#include <stdio.h>
#include<conio.h>
#include <stdlib.h>
#include <iostream>
/* Routines called. */
int loadMatrixFromFile(char *filename, int *data);
void showMatrix(int *data, int len);
int makeIdent(int matrixB[5][5], int length);
int matrixA[5][5];
int matrixB[5][5];
int matrixC[5][5];
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]);
int main(){
int len, data[1000];
len = loadMatrixFromFile("Numbers.txt", data);
showMatrix(data, len);
makeIdent(matrixB,len);
multiplyMatrices(matrixA, matrixB, matrixC);
}
int makeIdent(int matrixB[5][5], int len){
int i,j;
printf("Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==j){
matrixB[i][j]=1;
printf("%d ",matrixB[i][j]);
}
else{
matrixB[i][j]=0;
printf("%d ",matrixB[i][j]);
}
}
printf("\n");
}
return matrixB[i][j];
printf("\n");
}
int loadMatrixFromFile(char *filename, int *data){
FILE *in;
int len;
int j;
in = fopen(filename, "r");
if (in == NULL) {
printf("Could not find file: %s \n", filename);
}
else {
printf("Reading numbers...\n");
fscanf(in, "%d", &len);
printf("reading %d numbers from file %s ....\n", len, filename);
for(j=0;j<len;j++) {
fscanf(in, "%d", data + j);
}
fclose(in);
}
for(int i = 0; i<5; i++){
for(int j = 0; j < 5; j++){
matrixA[i][j] = *(data + i*5 + j);
}
}
return len;
}
void showMatrix(int *data, int len){
int j;
int count = 0;
printf("Showing %d numbers from data array....\n", len);
printf("Matrix A is: \n");
for(j=0;j<len;j++) {
printf("%d ", *(data + j));
count++;
if(count % 5 == 0){
printf("\n");
}
}
printf("\n");
}
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
int i, n, j;
int count = 0;
printf("\n");
printf("Matrix A x Matrix B is: \n");
for (i = 0; i<5; i++){
for (j = 0; j<5; j++){
matrixC[i][j] = 0;
matrixC[i][j] += matrixA[i][j]*matrixB[i][j];
printf("%d ",matrixC[i][j]);
count++;
if(count % 5 == 0){
printf("\n");
}
}
}
}
Well your algorithm for matrix multiplication is completely wrong.
You say 'I want to learn how to do it with pointers', but here's the thing, you're already are doing it with pointers.
In this code
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
the variables matrixA, matrixB and matrixC are pointers. In C++ it's impossible to have an array for a function parameter. It automatically gets converted to a pointer. It's also true that the syntax for accessing an array is identical to the syntax for accessing a pointer.
If you want to make it explicit that you are using pointers then rewrite your code like this
void multiplyMatrices(int (*matrixA)[5], int (*matrixB)[5],int (*matrixC)[5]){
Now you can see that matrixA, matrixB and matrixC pointers to arrays of 5 integers. You don't have to make any other changes. And in fact this change is exactly what the compiler does when you try to use an array as a function parameter.
Here's a good looking link that explains how pointers and arrays compare. The link talks about C, but the rules are the same in C++. Have a read it will probably help you understand better than I can.