I have started to learn c++. (I learn applied maths at school) And I must learn programming. I have just wrote a max choosing sort in c++. It should print the elements of a predefined array in decreasing order, but it is not working. Can you tell me where did I go wrong?
int* max(int *array)
{
int *max = array++;
while(*array)
{
if (*max<*array) *max = *array;
array++;
}
return max;
}
void change (int *what, int *to)
{
int *temp = what;
what =to;
to = temp;
}
void sort(int *array)
{
while(*array) change(array,max(array));
array++;
}
int _tmain(int argc, _TCHAR* argv[])
{
int A[] ={7,5,6,9,2,5,3,1,4,10,6,7,2,8};
sort (A);
int i =0;
while (A[i]) cout<<A[i++];
getchar();
return 0;
}
The first problem I see is that while (*array) { ... } won't terminate where you want it to because what is beyond the last element of your array is not certain to be 0 or NULL, or it may terminate in the middle of your array if you are sorting an array that includes 0.
Instead you want to say something like:
int A[] = { ... };
int element_count = sizeof(a)/sizeof(a[0]);
for (int i = 0; i < element_count; ++i) { ... }
You seem to have the concepts of pointers and values reversed. For example, your change function, as it is now, is
void change (int *what, int *to)
{
int *temp = what;
what =to;
to = temp;
}
when it should be
void change (int *what, int *to)
{
int temp = *what;
*what = *to;
*to = temp;
}
Which is almost exactly the opposite.
There are also several misuses of pointers in the max function that I can see as well as the sort function, and that is what I see after only a very brief glance at the code. You need to go back and learn pointers, and then try this again.
The second problem is that the array++; in the sort() function is not part of the while loop. I wouldn't be suprised if this never exits.
I would try to explicitly show what you're trying to do by using the right type; for example:
while (*array)
{
...
}
would be a lot easier for you to debug if it said something more like
while (array != NULL)
or even
for (int k=0; k<n; k++)
{
// do something with array[k]
}
Also, your change function seems like it should swap two values that the pointers point to, but it doesn't.
Just in case it helps, I think the technical name of what you're doing is called "Selection Sort". This might help if you need to ask anyone else for advice!
Good luck!
Related
I have a class array inside which I have declared an array its size and length. I am trying to merge two sorted arrays by creating the third array on the heap and both the sorted array will be merged on the third array. But whenever I create a new arr on heap the compiler gives me this error: request for member '..' in '..' which is of non-class type
class Array
{
public:
int A[10];
int length;
int Size;
};
void display(Array arr)
{
int i;
for(i=0;i<arr.length;i++)
{
cout<<arr.A[i]<<" ";
}
}
void Merge(Array *arr1,Array *arr2)
{
int i,j,k;
i=j=k=0;
int *arr3;
arr3=new int[10];
while(i<arr1->length && j<arr2->length)
{
if(arr1->A[i]<arr2->A[j])
arr3->A[k++]=arr1->A[i++];
else
arr3->A[k++]=arr2->A[j++];
}
for(;i<arr1->length;i++)
{
arr3->A[k++]=arr1->A[i];
}
for(;j<arr2->length;j++)
{
arr3->A[k++]=arr1->A[j];
}
}
int main()
{
Array arr1{{1,3,5,7},4,4};
Array arr2{{2,4,6,8},4,4};
Array *arr3;
arr3=Merge(&arr1,&arr2);
display(*arr3);
return 0;
}
The root cause of all your problems is that you use C-Style array with a magical size 10. Like in int A[10];. This is a major problem and should be avoided in C++.
Additionally, and the same, In C++ we usually do not use raw pointer for owned memories or newand such stuff.
Anyway. The design will never work, if the number of elements in both Array classes is greater then 5. Because then you will definitely get an out of bounds problem.
You must use a std::vector.
So, all bad. But I know that I will hear now, that the teacher said, no vector but new. The teacher should be fired or begin to teach C instead of C++.
Anyway again, I will fix the major bugs for you. But the sorting algorithm will work neither.
So,
If you want to return an Array, then change the signature of your function aand return an Array.
You do want to have a new Array, not new intes. So, please allocate a new Array instead.
Do not forget to release the newed Arrary at then end.
Set size and length of the new array.
Refactor your complete code.
Code example with some fixes:
#include <iostream>
class Array
{
public:
int A[10];
int length;
int Size;
};
void display(Array arr)
{
int i;
for (i = 0; i < arr.length; i++)
{
std::cout << arr.A[i] << " ";
}
}
Array* Merge(Array* arr1, Array* arr2)
{
int i, j, k;
i = j = k = 0;
Array *arr3 = new Array;
while (i < arr1->length && j < arr2->length)
{
if (arr1->A[i] < arr2->A[j])
arr3->A[k++] = arr1->A[i++];
else
arr3->A[k++] = arr2->A[j++];
}
for (; i < arr1->length; i++)
{
arr3->A[k++] = arr1->A[i];
}
for (; j < arr2->length; j++)
{
arr3->A[k++] = arr1->A[j];
}
arr3->length = arr1->length + arr2->length;
return arr3;
}
int main()
{
Array arr1{ {1,3,5,7},4,4 };
Array arr2{ {2,4,6,8},4,4 };
Array* arr3;
arr3 = Merge(&arr1, &arr2);
display(*arr3);
delete[]arr3;
return 0;
}
I am currently working on a project where we have to create an array of 1000 elements then pass it to another function to sort it. Everything I have seen online shows you how to pass it from main to another function, but not the other way around.
Please take a look at my code and help me pass Ar[1000] from Array() to ISort and ultimately main
#include <iostream>
#include <time.h>
using namespace std;
void Array()//function to make array
{
int Ar[1000];//creating array
int i = 0;//random variable to be element #
int counter = 0;// counter variable
int randnum;//variable to old random number
srand(time(NULL));//seeding rand with time
while (counter != 1000)
{
randnum = rand();
Ar[i] = randnum;
cout << Ar[i]<<endl;
counter++;
}
}
void ISort(int Ar[1000])//Iterative sort
{
int count = 0;//another counter variable
int count2 = 0;//counter variable # 3 because nested loops
int j=0;//Temp index # similar to i
int temp; //Temp variable to help switch elements
while (count != 1000)
{
if (Ar[count] < Ar[j])
{
temp = Ar[count];
Ar[count] = Ar[j];
Ar[j] = temp;
}
}
}
/*void RSort(int Ar)//Recursive sort
{
}
*/
int main()
{
Array();
ISort();
system("Pause");
return 0;
}
Ar in your Array function will be destroyed once this function finishes, you need to have a way to prevent this, one way is to pass an array by parameter instead of making it function local variable:
void Array(int* Ar, int count)//function to make array
{
I would also change Your current ISort definition to:
void ISort(int* Ar, int acount)//Iterative sort
where acount is number of elements in Ar. This is because it makes no difference whether you use void ISort(int Ar[1000]) or void ISort(int* Ar) (read here for more on this). If you want to preserve array type then you must pass it by reference using: void ISort(int (&Ar)[1000]).
Finally changes in main:
int Ar[1000];//creating array
Array(Ar, 1000);
ISort(Ar, 1000);
system("Pause");
return 0;
working code is here: http://coliru.stacked-crooked.com/a/678f581f802da85b
You also forgot to increment count inside your sorting loop.
Your array int Ar[1000] variable inside an Array() function is a local variable. Make it a global variable by moving it out of the function scope:
int Ar[1000]; //creating array
// your functions here
int main()
{
Array();
ISort(Ar);
return 0;
}
You should also modify the Array() function to accept array as parameter as pointed out in the comments below. Please note that I am omitting the array size part as it seems the number of the elements is set to 1000:
void Array(int Ar[]){
//...
};
in which case the above code would be:
int Ar[1000]; //creating array
// your functions here
int main()
{
Array(Ar);
ISort(Ar);
return 0;
}
Change the Array function declaration to:
int* Array() and make it return the array Ar. And in main get the returned value from Array function like this:
int* Ar = Array();
and pass it to the function ISort like this : ISort(Ar);.
Here is an example on SO passing an array to a function.
The easiest solution would be to change Array function a bit:
int* Array() { // change return type to be able to return array you create
int Ar[1000];
for (int i = 0; i < 1000; i++) { // much better to use for loop than while
Ar[i] = rand(); // no need to hold another variable for random number
cout << Ar[i] << endl;
}
return Ar; // return the Ar
}
int main() {
int* array = Array();
ISort(array);
}
Hope that helps. Also there are many other solutions to this but I don't know what exact restrictions your task has. If you have any questions feel free to ask.
EDIT: So I totally forgot about that C arrays are just a plain old pointers... Well then the solution would be like this:
void Array(Ar[1000]& array) { // pass array to the function with reference
for (int i = 0; i < 1000; i++) { // much better to use for loop than while
array[i] = rand(); // no need to hold another variable for random number
cout << array[i] << endl;
}
}
int main() {
int[1000] array = Array();
ISort(array);
}
Sorry for the error but using C style arrays really isn't common in C++ when you can use vectors and maps.
This is my structure which has two integer pointers aV and aT.
struct ADJP
{
int *aV;
int eV;
int nV;
int *aT;
int nT;
};
ADJP *Umb = NULL;
The allocation process of aV and aT is like this..
for(int i=0; i<nb; i++)
{
Umb[i].aV = new int[N];
for(int j=0; j<n; j++)
Umb[i].aV[j] = pIn[i].aV[j];
}
I want to remove one specific element from Umb array. for example I want to remove Umb[5], then how can I remove. I have tried with various mathods but got error due to allocated pointers I think. I have tried with follow method but its not working with this kind of struct array. It is working with struct array having no pointers.
int DeleteStructElement(int Index, ADJP *b, int N, int at)
{
for(int i=Index; i<N-1; i++)
memmove(&b[i], &b[i+1], (N-at-1)*sizeof*b); // moving the terms of array
N--; // updating new size
return N;
}
Have any idea how to remove an element from my struct array?
You will want to delete the arrays in the deleted element to release their memory:
delete[] b[Index].aV;
delete[] b[Index].aT;
Then, you only have to do a single memmove to remove the element.
memmove(&b[Index], &b[Index+1], (N-Index-1) * sizeof(b[Index])
EDIT: as Mahmoud points out, this doesn't use the at parameter in DeleteStructElement; I'm not sure what you intended that parameter to do.
int DeleteStructElement (int index, ADJP * b, int nb) {
delete [] (b[index].aV);
for (int i = index; i < nb - 1; ++i) {
b[i] = b[i+1];
}
return nb - 1;
}
Assuming you're really using C++, a destructor in ADJP would be much more straightforward than DeleteStructElement.
But if you're doing some interesting "C" with new/delete (perhaps a well-confined subset of C++?), then I'd suggest calling delete from within DeleteStructElement.
but got error due to allocated pointers I think
Answering this question might be much more important than others. I'm assuming this was a runtime error? Use a debugger to suss out just exactly where the fault was.
I am learning about pointers and the new operator in class.
In my readArray function I am to read in a size. Use the size to dynamically create an integer array. Then assign the array to a pointer, fill it, and return the size and array.
I believe I've gotten that part corrected and fixed but when I try to sort the array, i get the error "uninitialized local variable temp used."
The problem is though I get that error when I am trying to intialize it.
Any help appreciated thank you. Seeing my errors is very helpful for me.
#include <iostream>
using namespace std;
int* readArray(int&);
void sortArray(int *, const int * );
int main ()
{
int size = 0;
int *arrPTR = readArray(size);
const int *sizePTR = &size;
sortArray(arrPTR, sizePTR);
cout<<arrPTR[1]<<arrPTR[2]<<arrPTR[3]<<arrPTR[4];
system("pause");
return 0;
}
int* readArray(int &size)
{
cout<<"Enter a number for size of array.\n";
cin>>size;
int *arrPTR = new int[size];
for(int count = 0; count < (size-1); count++)
{
cout<<"Enter positive numbers to completely fill the array.\n";
cin>>*(arrPTR+count);
}
return arrPTR;
}
void sortArray(int *arrPTR, const int *sizePTR)
{
int *temp;
bool *swap;
do
{
swap = false;
for(int count = 0; count < (*sizePTR - 1); count++)
{
if(arrPTR[count] > arrPTR[count+1])
{
*temp = arrPTR[count];
arrPTR[count] = arrPTR[count+1];
arrPTR[count+1] = *temp;
*swap = true;
}
}
}while (swap);
}
You make temp an int pointer (uninitiialized), and then set the thing it points at (anything/nothing) to arrPTR[ccount]. Since you are using temp only to swap, it should be the same type as those being swapped, in this case: an int.
If it absolutely must be a pointer (there is no good reason for this, it's slow, confusing, adds potential for errors, and adds potential for memory leaks):
int *temp = new int; //make an int for the pointer to point at
bool *swap = new bool; //make an bool for the pointer to point at
do
{
//your code
}while (swap);
delete temp;
delete swap;
You declared temp as a pointer. You need to allocate it on the heap before dereferencing and assigning to it later. However perhaps a variable on the stack would be preferable?
FYI: You should be aware of the memory leak in readArray as well which is leaving callers responsible for calling delete []
Edit: I hope this will help clear up some of the other problems.
#include <iostream>
int* readArray(int&);
void sortArray(int*, int);
int main ()
{
int size(0); // use stack when possible
int *arrPTR = readArray(size);
sortArray(arrPTR, size);
// arrays are zero based index so loop from 0 to size
for (int index(0); index < size; ++index)
std::cout << arrPTR[index];
delete [] arrPTR; // remember to delete array or we have a memory leak!
// note: because we did new[] for an array we match it with delete[]
// if we just did new we would match it with delete
system("pause");
return 0;
}
int* readArray(int& size)
{
std::cout << "Enter a number for size of array.\n";
std::cin >> size;
int *arrPTR = new int[size]; // all news must be deleted!
// prefer pre-increment to post-increment where you can
for(int count(0); count < size; ++count)
{
std::cout << "Enter positive numbers to completely fill the array.\n";
std::cin >> arrPTR[count];
}
return arrPTR;
}
// passing size by value is fine (it may be smaller than pointer on some architectures)
void sortArray(int *arrPTR, int size)
{
// you may want to check if size >= 2 for sanity
// we do the two loops to avoid going out of bounds of array on last iteration
for(int i(0); i < size-1; ++i) // the first to compare (all except last)
{
for(int j(i+1); j < size; ++j) // the second to compare (all except first)
{
// do comparison
if (arrPTR[i] > arrPTR[j]) // from smallest to biggest (use < to go from biggest to smallest)
{
// swap if needed
int temp(arrPTR[i]); // put this on stack
arrPTR[i] = arrPTR[j];
arrPTR[j] = temp;
}
}
}
}
temp is a "pointer to int, which you're not initializing. When you say *temp = ... you're actually assigning to whatever temp happens to be pointing, but since you haven't told it what to point to, it can write pretty much anywhere in the address space of your program.
Because of the way you're using them, it seems that temp and swap shouldn't be pointers at all, just a plain int and bool.
You didn't initialize the temp pointer do when you dereference it you are writing to a random part of memory. Temp doesn't need to be a pointer, it can just be an int. Just replace EVERY instance of *temp with temp.
Can you tell me what's wrong with my method? I ends up putting the same thing everywhre and it's actually not sorting.
void sortArrays(){
int i, j;
for(i=0; i<counter; i++){
for( j=0; j<i; j++){
if( strcmp(title_arr[i], title_arr[j]) < 0){
char* title_temp = title_arr[i];
title_arr[j] = title_temp;
}
}
}
This:
char* title_temp = title_arr[i];
title_arr[j] = title_temp;
Is equivalent to:
title_arr[j] = title_arr[i];
You never swap them, you just copy one to the other. You should add this line:
title_arr[i] = title_arr[j];
In between the two. That way, you'll overwrite [i] with [j], but _temp still holds the old value of [i], so you can copy that value into [j], thus swapping them.
I suppose it's also a time for a lesson on algorithms. Your algorithm is known as a "bubble sort" algorithm. It is known for it's simplicity, but in a realistic setting it is known for it's inefficiency (the technical term is "teh sux", and the real technical term is O(n^2) ("N squared") performance). Some more common (and more efficient) algorithms include Quicksort, merge sort, and Heapsort, among many others. For more about measuring algorithmic scalability, see the article on Big Oh notation.*
But, as vava pointed out in a comment, unless your assignment is to write your own sorting function, you're going to get better performance with qsort (in C) or std::sort (in C++).
int mystrsort(const void *a, const void *b)
{
return strcmp(*(const char **)a, *(const char **)b);
}
// later:
qsort(title_arr, sizeof title_arr / sizeof(char *), sizeof(char *), mystrsort);
I'm not going to stab at std::sort, but it's going to work about the same (perhaps easier).**
*Note that anyone who likes is free to change these Wikipedia links to Stack Overflow links. It would be better to link to SO, I just linked to Wikipedia because I knew how to find the info I needed faster.
**Note that anyone who likes is free to add a std::sort example. I'm just not sufficiently familiar with C++.
You didn't swap properly, that's why it didn't work.
#include <iostream>
#include <algorithm>
int const counter = 4;
char * title_arr[counter] = {
"d", "c", "b", "a"
};
void sortArrays(){
for(int i = 0; i < counter; i++){
for(int j = 0; j < i; j++){
if(strcmp(title_arr[i], title_arr[j]) < 0){
char* title_temp = title_arr[i];
title_arr[i] = title_arr[j];
title_arr[j] = title_temp;
//you wouldn't have made that stupid mistake this way.
//std::swap(title_arr[i], title_arr[j]);
}
}
}
}
int compare(void const * a, void const * b) {
return strcmp(static_cast<char const *>(a), static_cast<char const *>(b));
}
struct StringLess : public std::binary_function<char const *, char const *, bool> {
bool operator() (char const * a, char const * b) const {
return strcmp(a, b) < 0;
}
};
int main(int argc, char * argv[])
{
sortArrays();
//those ones better
// qsort(title_arr, counter, sizeof(char *), compare);
// std::sort(title_arr, title_arr + counter, StringLess());
for (int i = 0; i < counter; i++) {
std::cout << title_arr[i] << ", ";
}
return 0;
}
Bad coding style:
1. Don't use global variables. It's better to pass your array and length as arguments into sort function. Why? Your function is not reusable. What if you will need to sort another array? Yes, you will need to write another sort function...
2. More advanced tip: use emulation of higher-order function. What if you will need to sort not only characters? Integer, floats, strings or your own types. In this case you can also pass compare() function into your sort function which can compare objects of your array.