How does a 2D array within another array work? - c++

I am looking at my homework for c++ and having some trouble understanding a part of the code. The code is creating a 2d array and wants to know how many times the elements from 1-9 are repeated.
#include <iostream>
using namespace std;
const int r = 3;
const int c = 4;
void frequency (int a[r][c]);
int main() {
int elems [r][c] = {{1, 1, 3, 4}, {2, 3, 4, 5}, {6, 9, 9, 9}};
frequency(elems);
return 0;
}
void frequency(int a[r][c]){
int arr[10] = {};
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
arr[a[i][j]]++;
}
}
for(int i = 1; i < 10; i++){
cout << i << " is repeated " << arr[i] << " times." << endl;
}
}
I don't understand how the line arr[a[i][j]]++; works -- how does it act as a counter for elements that are repeated?

I don't understand how the line arr[a[i][j]]++; works -- how does it act as a counter for elements that are repeated?
int arr[10] = {}; is creating an int-array with 10 elements (indexed 0-9) all initialized to 0.
arr[a[i][j]]++; is (post-)incrementing an element of arr.
The element at which index? The one at index a[i][j].
You loop through every row in a (i.e. in elems) using i and through every column within that row using j; in essence looping through every element in the order they are spelled in the source code. You are using the numbers in array a to index into the array arr: The first two elements of elems are 1, thus you increment arr[1]. The third number in elems is 3, thus you increment arr[3], ...

Related

make an array where the number that i insert gets deleted and is replaced by a 0 at end of array using pointers

I'm making it in a 3x4 matrix form
Also I'm not sure how to use a pointer since the number that I want to change and replace is an arr[3][4] and not the usual arr[5]
using namespace std;
#include <iomanip>
int main(){
int i;
int j;
int *change;
int number; // not sure how to use the pointer to reference a [3][4] array //
int arr[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < 3; i++) // not sure if there is a way where i dont have to write every number and just have it go from 1 to 12 //
{
for (int j = 0; j < 4; j++)
{
cout << setw(8)<<arr[i][j] << ' '; // to make it look organized and aligned//
}
cout <<endl;
}
cout << "number" << ' ';
cin >> number; // i woud insert the number here//
cout << arr[3][4];
return 0;
}
and should appear like this (say i chose 6)
1 2 3 4
5 7 8 9
10 11 12 0
The operation that you want to do is natural for single dimensional ranges, and not for multi dimensional ones. There are standard algorithms to achieve your goal with a single dimensional range.
With range views, it's fairly simply to get a single dimensional view of the elements:
// flat view of the array
auto flat_arr = arr | std::ranges::views::join;
// move elements to overwrite the removed elements
auto remaining = std::ranges::remove(flat_arr, number);
// fill the ramaining space with zeroes
std::ranges::fill(remaining, 0);
Without using ranges, you could achieve the same by defining a custom iterator. Alternatively, you could use a single dimensional array, and transform two dimensional indices with a bit of math. Example:
constexpr std::size_t rows = 3, cols = 4;
int arr[rows*cols] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// move elements to overwrite the removed elements
auto last_it = std::remove(std::begin(arr), std::end(arr), number);
// fill the ramaining space with zeroes
std::fill(last_it, std::end(arr), 0);
for (std::size_t i = 0; i < rows; i++)
{
for (std::size_t j = 0; j < cols; j++)
{
std::cout
<< std::setw(8)
// transform 2D to 1D
<< arr[i * cols + j]
<< ' '
;
}
std::cout << '\n';
}

Difficulty understanding code to count the number of inversions using BIT

Here is the code:
#include<iostream>
using namespace std;
const int MX = 100;
int n,a[MX*2],bit[MX];
void add(int x, int y){
for(;x<=n; x+=-x&x) bit[x]+=y;
}
int query(int x){
int s= 0;
for(;x>0; x-=-x&x) s+=bit[x];
return s;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ans = 0;
cin >> n; n*=2;
for(int i = 0; i<n; i++){
cin >> a[i];
}
for(int i = n-1; ~i; i--){
ans+=query(a[i]-1);
add(a[i],1);
}
cout << ans;
}
I dont understand how the query and add contribute to finding the number of inversions in an array. If someone can help explain this to me that would be great. Thanks.
Firstly, I hope you understand how add and query work in BIT. If not, think of BIT like a blackbox which stores prefix sums for count of elements 1, 2, ..., n in array A. For example, A[3] = count(1) + count(2) + count(3). add(x, y) increments count(x) by y and query(x) returns the sum count(1) + count(2) + ... + count(x) i.e., the prefix sum till element x.
Elements at index i and j form an inversion if i < j and arr[i] > arr[j]. But the above code reads it the other way; j > i and arr[j] < arr[i] (this save an extra call to query).
Now suppose the array is {3, 4, 1, 5, 2} and {2, 5, 1} have already been inserted in the BIT. Then query(1) = 1, query(2) = 2, query(3) = 2, query(4) = 2 and query(5) = 3 (remember to think of BIT as a blackbox that stores prefix sums). Notice when index i is pointing at element 4, all the elements that have already been inserted having indices j1, j2, ..., jk are all > i so now we only need to count the number of elements < 4 which is the prefix sum till 3 which we get by calling query(3).

Rotate array to right instead of left

I have some code that rotates a number array to the left but instead, I need it to rotate it to the right. There is other code online that rotates array to the right but that code lets you only rotate numbers in the middle of the array.
I have tried decrementing the loops differently & and changing where its initialized but doesn't seem to rotate the correct way.
Expected output: if array is this {1, 2, 3, 4, 5, 6, 7}. Then it should look like: {7, 1, 2, 3, 4, 5, 6}
Current output: {2, 3, 4, 5, 6, 7, 1}
#include <iostream>
using namespace std;
/*Function to left Rotate arr[] of size n by 1*/
void leftRotatebyOne(int arr[], int n);
/*Function to left rotate arr[] of size n by d*/
void leftRotate(int arr[], int d, int n)
{
int i;
for (i = 0; i < d; i++)
leftRotatebyOne(arr, n);
}
void leftRotatebyOne(int arr[], int n)
{
int i, temp;
temp = arr[0];
for (i = 0; i < n-1; i++)
arr[i] = arr[i+1];
arr[i] = temp;
}
/* utility function to print an array */
void printArray(int arr[], int size)
{
int i;
for(i = 0; i < size; i++)
cout << arr[i] << " ";
}
/* Driver program to test above functions */
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7};
printArray(arr, 7);
leftRotate(arr, 1, 7);
cout << "___" << endl;
printArray(arr, 7);
getchar();
return 0;
}
leftRotateByOne is the key function here. The others can stay the same. Have a look at what it is doing, preferably with a pen and paper to keep track of the operations:
Keeps a copy of the first element.
Moves all elements to the "left" (that is, to the element with index
one less), being careful not to overwrite anything you need later.
Puts the first element in the last place.
So you need to do the opposite:
Keep a copy of the last element.
Moves all elements to the "right" (that is, to the element with index
one more), being careful not to overwrite anything you need later.
Puts the last element in the first place.
For example:
void rightRotatebyOne(int arr[], int n)
{
int i, last;
last = arr[n-1];
for (i = n-1; i > 0; i--)
arr[i] = arr[i-1];
arr[0] = last;
}

Sorting an array to another array 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;
}

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.