Sorting an array to another array C++ - c++

My program have to sort an array in another array.
When I run the program it prints 1 2 3 -858993460 5 -858993460 7.
I can not understand where the mistake is in the code.
#include <iostream>
using namespace std;
int main()
{
const int N = 7;
int arr[N] = { 3, 17, 2, 9, 1, 5, 7 };
int max = arr[0];
for (int i = 1; i < N; i++)
{
if (max < arr[i])
max = arr[i];
}
int sort_arr[N];
for (int j = 0; j < N; j++)
{
sort_arr[arr[j] - 1] = arr[j];
}
for (int i = 0; i < N; i++)
{
cout << sort_arr[i] << " ";
}
return 0;
}

Okay lets face the problems in your code.
The "weird" numbers you see there, came from the uninitialzied array sort_arr. What do I mean by uninitialized? Well sort_arr is a little chunck somewhere in your memory. Since a program usually does not clear its memory and rather claims the memory it used as free, the chunk of sort_arr may contain bits and bytes set by another program. The numbers occure since these bytes are interpreted as an integer value. So the first thing to do would be to initialize the array before using it.
sort_arr[N] = { 0, 0, 0, 0, 0, 0, 0 };
Now why did these numbers occure? Well you're probably expecting your algorithm to set all values in sort_arr which would result in an sorted array, right? Well but your algorithm isn't working that well. See this line:
sort_arr[arr[j] - 1] = arr[j];
What happens when j is 1? arr[1] is then evaluated to 17 and 17 - 1 equals 16. So sort_arr[arr[1] - 1] is the same as sort_arr[16] which exceeds the bounds of your array.
If you want to program a sorting algorithm by your self than I would recommend to start with an simple bubble sort algorithm. Otherwise, if you only need to sort the array have a look at the algorithm header. It is fairly simple to use:
#include <iostream>
#include <algorithm>
#include <iterator> // << include this to use begin() and end()
using namespace std;
int main()
{
const int N = 7;
int arr[N] = { 3, 17, 2, 9, 1, 5, 7 };
int sort_arr[N] = { 0, 0, 0, 0, 0, 0, 0 };
copy(begin(arr), end(arr), begin(sort_arr));
sort(begin(sort_arr), end(sort_arr));
for (int i = 0; i < N; i++)
{
cout << sort_arr[i] << " ";
}
cout << endl;
}
By the way. You're looking for the biggest value in your array, right? After you have sorted the array sort_arr[N - 1] is the biggest value contained in your array.

If you want to sort a array into another array then one way is you make a copy of the array and then use the sort function in the standard library to sort the second array.
int arr[10];
int b[10];
for(int i=0;i<10;i++)
{
cin>>arr[i];
b[i]=arr[i];
}
sort(b,b+10);
// this sort function will sort the array elements in ascending order and if you want to change the order then just add a comparison function as third arguement to the sort function.

It seems that you think that sort_arr[arr[j] - 1] = arr[j] will sort arr into sort_arr. It won't.
Sorting is already written for you here: http://en.cppreference.com/w/cpp/algorithm/sort You can use that like this:
copy(cbegin(arr), cend(arr), begin(sort_arr));
sort(begin(sort_arr), end(sort_arr));
Live Example

My guess is this is an attempt to implement a type of counting sort. Note that variable length arrays aren't normally allowed in C++ or some versions of C. You could use _alloca() to allocate off the stack to get the equivalent of a variable length array: int * sort_arr = (int *)_alloca(max * sizeof(int)); .
#include <iostream>
using namespace std;
int main()
{
const int N = 7;
// assuming range of values is 1 to ...
int arr[N] = { 3, 17, 2, 9, 1, 5, 7 };
int max = arr[0];
for (int i = 1; i < N; i++)
{
if (max < arr[i])
max = arr[i];
}
int sort_arr[max];
for (int i = 0; i < max; i++)
{
sort_arr[i] = 0;
}
for (int j = 0; j < N; j++)
{
sort_arr[arr[j] - 1]++;
}
for (int i = 0; i < max; i++)
{
while(sort_arr[i])
{
cout << i+1 << " ";
sort_arr[i]--;
}
}
return 0;
}

Related

How to find the minimun of an array?

I was trying to solve this question
but codechef.com says the answer is wrong.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t, n, diff, mindiff;
cin >> t;
cin >> n;
int val[n];
while(t--)
{
mindiff = 1000000000;
for(int i = 0; i<n; i++)
{
cin >> val[i];
}
int a = 0;
for(a = 0; a<n ; a++)
{
for(int b=a+1; b<n ; b++)
{
diff = abs(val[a] - val[b]);
if(diff <= mindiff)
{
mindiff = diff;
}
}
}
cout << mindiff << endl;
}
return 0;
}
The results are as expected (for at least the tests I did) buts the website says its wrong.
There are a few things in your code that you should change:
Use std::vector<int> and not variable-length arrays (VLA's):
Reasons:
Variable length arrays are not standard C++. A std::vector is standard C++.
Variable length arrays may exhaust stack memory if the number of entries is large. A std::vector gets its memory from the heap, not the stack.
Variable length arrays suffer from the same problem as regular arrays -- going beyond the bounds of the array leads to undefined
behavior. A std::array has an at() function that can check boundary access when desired.
Use the maximum int to get the maximum integer value.
Instead of
mindif = 1000000000;
it should be:
#include <climits>
//...
int mindiff = std::numeric_limits<int>::max();
As to the solution you chose, the comments in the main section about the nested loop should be addressed.
Instead of a nested for loop, you should sort the data first. Thus finding the minimum value between two values is much easier and with less time complexity.
The program can look something like this (using the data provided at the link):
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
int main()
{
int n = 5;
std::vector<int> val = {4, 9, 1, 32, 13};
int mindiff = std::numeric_limits<int>::max();
std::sort(val.begin(), val.end());
for(int a = 0; a < n-1 ; a++)
mindiff = std::min(val[a+1] - val[a], mindiff);
std::cout << mindiff;
}
Output:
3
To do this you can use a simple for():
// you already have an array called "arr" which contains some numbers.
int biggestNumber = 0;
for (int i = 0; i < arr.size(); i++) {
if (arr[i] > biggestNumber) {
biggestNumber = arr[i];
}
}
arr.size will get the array's length so that you can check every value from the position 0 to the last one which is arr.size() - 1 (because arrays are 0 based in c++).
Hope this helps.

C++ array operations

I want from the program to add 3 to elements which are greater than 3 and print them. It takes so much time that I couldn't see the result. Also, when I change n to 8 in loops directly, it gives a result; however, it's not related with what I want. How can I correct this code and improve that?
#include <iostream>
using namespace std;
int main()
{
int a[8] = {-5, 7, 1, 0, 3, 0, 5, -10};
int b[8];
int n= sizeof(a);
for( int i=1; i<=n; i++) {
if (a[i]>3) {
b[i] = a[i] + 3;
}
else {
b[i]= a[i];
}
}
for (int i = 1; i <= n; i++)
cout << b[i];
return 0;
}
The sizeof() function (int n = sizeof(a)) gives 32 because array 'a' contains 8 elements & each element is of 'int' type whose size is 4 byte in memory thats why it returns 32 in 'n' variable.so you must divide the value of 'n' with the size of integer.
Secondly the index of array starts with the zero '0' to one less than the length of array not with the 1 to length of array .
Try the below code ! I am also attach the output of the code .
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
int a[8] = { -5, 7, 1, 0, 3, 0, 5, -10 };
int b[8];
int n = sizeof(a)/sizeof(int);
for (int i = 0; i < n; i++) {
if (a[i]>3) {
b[i] = a[i] + 3;
}
else {
b[i] = a[i];
}
}
for (int i = 0; i < n; i++)
cout << b[i]<<endl;
return 0;
}
The statement in your program int n=size(a) returns the total bytes occupied in memory for a. i.e int occupies 4 bytes and a is an array contains 8 elements so 8X4 = 32 .but while accessing the array elements using loop you are specifying i<=n meains i<=32 but there is only 8 elements but you are trying to access 32 elements which indicates that you are trying to access the elements more than 8.
exeutes the following code
#include <iostream>
using namespace std;
int main()
{
int a[8] = {-5, 7, 1, 0, 3, 0, 5, -10};
int b[8];
int n=sizeof(a);
cout<<"\n Value of n is : "<<n;
return 0;
}
Output
Value of n is : 32
if you specify the exact number of array size your program will work properly.
#include <iostream>
using namespace std;
int main()
{
int a[8] = {-5, 7, 1, 0, 6, 0, 8, -10};
int b[8];
for( int i=1; i<8; i++)
{
if (a[i]>3)
{
b[i] = a[i] + 3;
}
else
{
b[i]= a[i];
}
}
cout<<"\n Values in a array";
cout<<"\n -----------------\n";
for (int i = 1; i <8; i++)
cout << "\t"<<a[i];
cout<<"\n Values in b array";
cout<<"\n -----------------\n";
for (int i = 1; i <8; i++)
cout << "\t"<<b[i];
return 0;
}
OUTPUT
Values in a array
-----------------
7 1 0 6 0 8 -10
Values in b array
---------------
10 1 0 9 0 11 -10
I hope that you understand the concept.Thank you
Your int n = sizeof(a); doesn't works as you intend.
I think you want to get the size of array (i.e. 8).
But you gets the size in bytes of elements (e.g. 32, integer size or could be different depending of your system's architecture).
Change to int n = 8, will solve your problem.
Also note that for( int i=1; i<=n; i++) will get an "out of array" element.
Sizeof function gives the value of the total bits of memory the variable occupy
Here in array it stores 8 integer value that has 2bit size for each thus it returns 32

Regarding pointers and arrays and how they are assigned in memory in C++

So I am trying to solve this question:
Data is fed in the following input format. The first line contains two space-separated integers denoting the number of variable-length arrays, n, and the number of queries, q. Each line of the subsequent lines contains a space-separated sequence in the format
k Ai[0] Ai[1] … Ai[k-1]
where k is the length of the array, Ai, and is followed by the k elements of Ai. Each of the subsequent lines contains two space-separated integers describing the respective values of array number (ranging from 0 to n-1) and index in that particular array (ranging from 0 to ki) for a query. i.e, Given the following input:
3 3
3 1 2 3
5 4 5 6 7 8
4 9 10 11 12
0 1
1 3
2 0
This output is expected
2
7
9
I am basically a beginner in C++. This is the code I have tried but I feel the address at which each subsequent array is stored is giving me some problems
int main(){
int n, q;
scanf("%d %d", &n, &q);
printf("n,q = %d, %d\n", n, q);
int* row[n];
for (int i = 0; i < n; i++){
int k;
scanf("%d", &k);
printf("k = %d\n", k);
int col[k];
row[i] = col;
for (int j = 0; j < k; j++){
int elem;
scanf("%d", &elem);
printf("i,j,elem = %d, %d, %d\n", i, j, elem);
col[j] = elem;
cout << "address is " << &(col[j]) << "\n";
}
}
for (int query = 1; query <= q; query++){
int i, j;
scanf("%d %d", &i, &j);
int answer;
answer = *(row[i] + j);
printf("row[%d][%d] is %d\n", i, j, answer);
cout << "address is " << &answer << "\n";
}
return 0;
}
And this is the output produced:
n,q = 3, 3
k = 3
i,j,elem = 0, 0, 1
address is 0x7ffe236edb70
i,j,elem = 0, 1, 2
address is 0x7ffe236edb74
i,j,elem = 0, 2, 3
address is 0x7ffe236edb78
k = 5
i,j,elem = 1, 0, 4
address is 0x7ffe236edb60
i,j,elem = 1, 1, 5
address is 0x7ffe236edb64
i,j,elem = 1, 2, 6
address is 0x7ffe236edb68
i,j,elem = 1, 3, 7
address is 0x7ffe236edb6c
i,j,elem = 1, 4, 8
address is 0x7ffe236edb70
k = 4
i,j,elem = 2, 0, 9
address is 0x7ffe236edb60
i,j,elem = 2, 1, 10
address is 0x7ffe236edb64
i,j,elem = 2, 2, 11
address is 0x7ffe236edb68
i,j,elem = 2, 3, 12
address is 0x7ffe236edb6c
row[0][1] is 32766
address is 0x7ffe236edbcc
row[1][3] is 32766
address is 0x7ffe236edbcc
row[2][0] is 3
address is 0x7ffe236edbcc
Basically, I find that the array addresses are overlapping. Also, The answer computation by dereferencing is resulting in unexpected outputs. Any explanation to the mistakes made here would be appreciated.
Here is a major problem:
for (int i = 0; i < n; i++){
...
int col[k];
row[i] = col;
...
}
The variable col has its scope only inside the loop. Once the loop iterates the variable cease to exist. Storing a pointer to it will lead to undefined behavior when you try to dereference the pointer.
The simple solution is probably to dynamically allocate memory for col using malloc.
Missed that the question was tagged C++, and confused because the source doesn't actually use any C++-specific code. This kind of makes it worse since variable-length arrays are not part of C++. Some compilers have it as an extension, but you should not use it when programming in C++.
Instead you should be using std::vector and then you can easily solve your problem without your own dynamic allocation. Then you can make row a vector of vectors of int and col a vector of int, and then the assignment will work fine (if row have been set to the correct size of course).
An easy way to use C++ without getting too many memory management bugs is to use standard library types. Leave the bare metal stuff to the poor C guys who do not have that ;)
So instead of meddling with new[] and delete[], use types like std::vector<> instead.
The "modern C++" version below uses iostream for no good reason. Old stdio.h is sometimes the preferred choice and so is sometimes iostream. And sometimes it is just a matter of style and taste.
#include <vector>
#include <iostream>
#include <fstream>
typedef struct Q
{
int iArray;
int iIndex;
} Q_t;
typedef std::vector<std::vector<int> > Data_t;
typedef std::vector<Q_t> Query_t;
bool Load(Data_t& data, Query_t &queries, std::istream& is)
{
size_t ndata = 0;
size_t nqueries = 0;
is >> ndata;
is >> nqueries;
data.resize(ndata);
queries.resize(nqueries);
for (size_t d = 0; d < ndata; d++)
{
size_t l = 0;
is >> l;
data[d].resize(l);
for (size_t i = 0; i < l; i++)
{
is >> data[d][i];
}
}
for (size_t q = 0; q < nqueries; q++)
{
is >> queries[q].iArray;
is >> queries[q].iIndex;
}
return true;
}
int main(int argc, const char * argv[])
{
std::ifstream input("E:\\temp\\input.txt");
Data_t data;
Query_t queries;
if (Load(data, queries, input))
{
for (auto &q : queries)
{
std::cout << data[q.iArray][q.iIndex] << std::endl;
}
}
return 0;
}
The mistake is, you have used 'col' array which loses its scope after completion of for loop. The way you can fix this is by either using dynamic memory allocation or by declaring it outside the for loop
Hope the below code will help you get an idea :)
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n, q;
cin >> n;
cin >> q;
int* row[n];
int* col;
for(int i=0; i<n; i++)
{
int k;
cin >> k;
col = new int[k];
row[i] = col;
for(int j=0; j<k; j++)
{
cin >> col[j];
}
}
for(int query=0; query<q; query++)
{
int i,j;
cin >> i;
cin >> j;
cout << row[i][j] << endl;
}
delete[] col;
return 0;
}

Remove and shift array c++

I want to locate a specific item from an array and then shift the array to remove that item. I have a list of integers {1, 2, 3, 4, 5, 6, 7, 8, 9} and want to remove the integer 2.
Currently I am getting an error: storage size of ‘new_ints’ isn’t known on the line:
int new_ints[];
Not sure what this means or how can I fix this?
Here is my code:
int main() {
int tmp = 2;
int valid_ints[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int new_ints[];
new_ints = stripList(tmp, valid_ints);
for (int i = 0; i < sizeof(new_ints); i++)
cout << new_ints[i] << endl;
return 0;
}
int *stripList (int tmp, int valid_ints[]){
for (int i = 0; i < sizeof(valid_ints); i++){
for (int j = tmp; j < sizeof(valid_ints); j++){
valid_ints[j] = valid_ints[j+1];
}
}
return valid_ints;
}
Like what Ben said, it is highly recommended to use an vector if you would like to resize your array to fit in new elements.
http://www.cplusplus.com/reference/vector/vector/vector/
Here's my example: (note alternatively you can use vector::erase to erase undesired elements)
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> valid_ints;
vector<int> new_ints;
int tmp = 2;
//read in elements
for(int i = 1; i <= 9; i++)
{
valid_ints.push_back(i);
}
//valid_ints will hold {1,2,3,4,5,6,7,8,9}
for(int i = 0; i < valid_ints.size(); i++)
{
//We will add an element to new_ints from valid_ints everytime the valid_ints[i] is NOT tmp. (or 2.)
if(valid_ints[i] != tmp)
{
new_ints.push_back(valid_ints[i]);
}
}
//Print out the new ints
for(int i = 0; i < new_ints.size(); i++)
{
cout << new_ints[i] << ' ';
}
return 0;
}
The resulting vector will be filled in this order:
{1}
{1,3} (skip 2!)
{1,3,4}
{1,3,4,5}
so on... until
{1,3,4,5,6,7,8,9}
So, the output would be:
1 3 4 5 6 7 8 9
In c++ size of an array must be known at compile time. Ie int new_ints[] is illegal. You will need to have a defined size ie new_ints[10]. (See here for more details) Or better yet, utilize the fantastic advantages of c++ and use a std::vector.

pass a single row from 2d vector to function

With the help of SO members, the following program successfully converts a static 1D array into a 2D vector by considering below criteria:
Each time an element with value = 0 is encountered, a new row is created. Basically when a 0 is encountered, row value is increased and column value is reset to 0. If a non-zero value is encountered, the row value is maintained and column value is increased.
// declarations
int givenArray[9] = {1, 2, 3, 0, 4, 0, 1, 2, 1};
std::vector<int>::size_type j;
std::vector<int>::size_type i;
vector<vector<int>> my2dArray;
vector<int> dArray;
void calc(vector<int>&, int);
int task;
int sum = 0;
int main() {
for (int i = 0; i < 9;
i++) // iterate through all elements of the given array
{
if (i == 0) // adding the first element
{
my2dArray.resize(my2dArray.size() + 1);
my2dArray.back().push_back(givenArray[i]);
continue;
}
if (givenArray[i] == 0) // re-size if 0 is encountered
{
my2dArray.resize(my2dArray.size() + 1);
}
my2dArray.back().push_back(givenArray[i]);
}
for (std::vector<std::vector<int>>::size_type i = 0; i < my2dArray.size();
i++) {
for (std::vector<int>::size_type j = 0; j < my2dArray[i].size(); j++) {
std::cout << my2dArray[i][j] << ' ';
if (my2dArray[i].size() > 2) {
task = my2dArray[i].size();
calc(my2dArray[i], task);
}
}
std::cout << std::endl;
}
}
void calc(vector<int>& dArray, int task) {
int max = 0;
for (unsigned int j = 0; j < task; j++) {
if (dArray[i] > max)
dArray[i] = max;
}
cout << "\nMax is" << max;
}
However, I want to pass a single row of 2D vector 2dArray to function calc if the number of columns for each row exceeds 2. Function calc aims to find maximum value of all the elements in the passed row. The above program doesn't yield the desired output.
Some improvements:
i and j global variables are not needed, you are declaring the variables of the loops in the loop initialization (ex: for (int i = 0; i < 9; i++), the same for the other loops).
It's better not to used global variables, only when strictly necessary (with careful analysis of why). In this case it's not necessary.
The typedef are for more easy access to inner typedef of the type (ex: size_type).
You were doing the call to calc method in every iteration of the inner loop, and iterating over the same row multiple times, this call should be executed once per row.
Using the size of array givenArray as constant in the code is not recommended, later you could add some elements to the array and forgot to update that constant, it's better to declare a variable and calculated generally (with sizeof).
There is no need to pass the size of the vector to method calc if you are passing the vector.
As recommended earlier it's better to use std::max_element of algorithm header.
If you could use C++11 the givenArray could be converted to an std::vector<int> and maintain the easy initialization.
Code (Tested in GCC 4.9.0)
#include <vector>
#include <iostream>
using namespace std;
typedef std::vector<int> list_t;
typedef std::vector<list_t> list2d_t;
void calc(list_t& dArray, long& actual_max) {
for (unsigned int j = 0; j < dArray.size(); j++) {
if (dArray[j] > actual_max) {
actual_max = dArray[j];
}
}
cout << "Max is " << actual_max << "\n";
}
void calc(list_t& dArray) {
long actual_max = 0;
for (unsigned int j = 0; j < dArray.size(); j++) {
if (dArray[j] > actual_max) {
actual_max = dArray[j];
}
}
cout << "Max is " << actual_max << "\n";
}
int main() {
int givenArray[9] = {1, 2, 3, 0, 4, 0, 1, 2, 1};
int givenArraySize = sizeof(givenArray) / sizeof(givenArray[0]);
list2d_t my2dArray(1);
list_t dArray;
for (int i = 0; i < givenArraySize; i++) {
if (givenArray[i] == 0) {
my2dArray.push_back(list_t());
} else {
my2dArray.back().push_back(givenArray[i]);
}
}
long max = 0;
for (list2d_t::size_type i = 0; i < my2dArray.size(); i++) {
for (list_t::size_type j = 0; j < my2dArray[i].size(); j++) {
std::cout << my2dArray[i][j] << ' ';
}
std::cout << "\n";
if (my2dArray[i].size() > 2) {
// if you need the max of all the elements in rows with size > 2 uncoment bellow and comment other call
// calc(my2dArray[i], max);
calc(my2dArray[i]);
}
}
}
Obtained Output:
1 2 3
Max is 3
4
1 2 1
Max is 2
You have a few problems:
You don't need to loop over j in the main function - your calc function already does this.
Your calc function loops over j, but uses the global variable i when accessing the array.
Your calc function assigns the current max value to the array, rather than assigning the array value to max
Function calc aims to find maximum value of all the elements in the passed row. The above program doesn't yield the desired output.
Instead of writing a function, you could have used std::max_element.
#include <algorithm>
//...
int maxVal = *std::max_element(my2dArray[i].begin(), my2dArray[i].begin() + task);
cout << "\Max is " << maxVal;