c++ function that fills array - c++

What I'm trying to do:
User inputs two numbers.
Array is declared using those numbers as dimensions.
Function outside main() is filling the array.
Array is accessed in main() for further thingies.
What I have problem with:
Function + array combination doesn't seem to work as I think.
What I did:
void tablica1(int h, int w)
{
int m,n;
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
}
What happens:
array arr is inaccessible in tablica1() because it has not been declared in that function.
Of course, when I declare the array in tablica1() it becomes inaccessible in main().
Possible solutions:
Passing arr to tablica1() as a reference - no idea how to do that
Declaring arr in tablica1() and somehow passing it to main() - no idea how to do that
Other possible solutions?

You can declare the array outside of both, at compilation unit level:
int arr[10][10];
void func() {
for (int i=0; i<10; i++) {
for (int j=0; j<10; j++) {
arr[i][j] = i + j;
}
}
}
int main(int argc, const char *argv[]) {
func();
std::cout << arr[3][4] << "\n"; // Output will be 7
return 0;
}
If you want handle a dynamically-sized matrix the most common pattern is to use an std::vector of std::vectors (it's a little more general and therefore a little less efficient than a 2d matrix because each row can have a different length, but in most cases the cost difference is not a big issue)
#include <vector>
std::vector< std::vector< int > > arr;
void func() {
int height = arr.size();
int width = arr[0].size();
for (int i=0; i<height; i++) {
for (int j=0; j<width; j++) {
arr[i][j] = i + j;
}
}
}
int main() {
int height = 13;
int width = 7;
arr = std::vector< std::vector<int> >(height, std::vector<int>(width));
func();
...
}

the two solutions you mentioned
1、Passing arr to tablica1() as a reference
void tablica1(int h, int w,int **arr)
{
int m,n;
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
}
void main()
{
const int h=100,w=100;
int arr[h][w];
tablica1(h,w,arr);
}
2、Declaring arr in tablica1() and somehow passing it to main()
int **tablica1(int h, int w)
{
int m,n;
int **arr=new int*[h];
for(int i=0;i<h;i++)
{
arr[i]=new int[w];
}
//it is best to initialize arr by setting each element 0
for(m=0; m<h; m++)
for(n=0; n<w; n++)
{
arr[h][w]=1;
}
return arr;
}
void main()
{
const int h=100,w=100;
int **arr=tablica1(h,w);
//do somting
//delete arr
for(int i=0;i<h;i++)
{
delete []arr[i];
}
delete []arr;
}

If you want to declare a dynamic multidimensional array you can do that with the template give below.
#include<iostream.
#include <vector>
using namespace std;
typedef vector<int> vi;
vector<vi> arr; // arr is a dynamic two dimensional array.
vi.assign(10,vi());//10 rows of type vi .
If you want to enter values in arr you can do that by
vi[0].push_back(a);
vi[0].push_back(b); // a,b,c are some example values..
vi[1].push_back(c);

You can understand using this code
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef vector <int> vi;
vector<vi> arr;// dynamic multidimensional array
int main(){
cout<<"enter array size\n";
int h,w,temp;;
cin>>h>>w;
arr.assign(h,vi());
int i, j;
for(i=0; i < h ;i++)
for(j=0; j < w; j++)
{
cin>>temp;
arr[i].push_back(temp);
}
// for printing
for(i=0; i < h ;i++){
for(j=0; j < w; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
return 0;
}

Related

how to pass dynamic 2d array to a function without using the pointers?

I tried this but it is not working !
can any one help me please this is very important :(
#include <iostream>
using namespace std;
int a[100][100];
void read(int a[][100],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>a[i][j];
}
int main ()
{
int n;
cin>>n;
int a[n][n];
read(a,n);
}
The unclear syntax to pass array by reference is:
void read(int (&a)[100][100], int n)
resulting in
#include <iostream>
void read(int (&a)[100][100], int n)
{
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
std::cin >> a[i][j];
}
int main ()
{
int n;
std::cin >> n;
int a[100][100];
read(a, n);
}
but you might prefer std::vector:
#include <iostream>
#include <vector>
void read(std::vector<std::vector<int>> &mat)
{
for (auto& v : mat) {
for (auto& e : v) {
std::cin >> e;
}
}
}
int main ()
{
int n;
std::cin >> n;
std::vector<std::vector<int>> mat(n, std::vector<int>(n));
read(mat);
}
Since this is tagged C++. I'd like to suggest usage of std::vector. It's dynamic container which is very useful. You can resize it, clear it fill it with ease. Once you understand it's basic usage, they would come really handy in your future C++ development. I modified your code slightly:
#include <iostream>
#include <vector>
using namespace std;
void read(vector<vector<int> >& arr,int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>arr[i][j];
}
int main ()
{
int N;
cin>>N;
vector<vector<int> > arr(N, vector<int>(N));
read(arr, N);
}
They have many advantages over the primitive arrays like they can be initialized easily, suppose you want to initialize all to zero :
vector<vector<int> > arr(N, vector<int>(N, 0));
You don't have to worry about adding the array size whenever passing in functions. vector can easily handle this:
for(i = 0; i < arr.size(); i++) {
for(j = 0; j < arr[i].size(); j++) {
// do stuff
}
}
Moreover with the added methods of the Standard template library like fill, swap. Many operations can be handled easily.

Maximum in a sliding window

i am unable to detect why i am getting wrong answer in the problem subarrays given on spoj .The problem is to determine the maximum element in k sized window .
i have applied sliding window algorithm which uses deque and maintains the index of the maximum element always at the front.
here is my code :
#include<iostream>
#include<deque>
using namespace std;
int main()
{
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
int k;
cin>>k;
deque<int>q;
int ans[n-k+1];
for(int i=0;i<k;i++)
{
while(!q.empty()&&arr[i]>=arr[q.back()])
q.pop_back();
q.push_back(i);
}
for(int i=k;i<n;i++)
{
ans[i-k]=arr[q.front()];
while(!q.empty()&&arr[i]>=arr[q.back()])
q.pop_back();
while(!q.empty()&&q.front()<=i-k)
q.pop_front();
q.push_back(i);
}
ans[n-k]=arr[q.front()];
for(int i=0;i<=n-k;i++)
{
cout<<ans[i];
}
cout<<"\n";
return 0;
}
Simple C++ logic would be...
#include <iostream>
#include<stdio.h>
int main() {
int temp;
int A[] = {1,2,-1,7,8,-3,-4};
int max = A[0];
printf("%d\n",max);
int n = 7;
for(int i = 1 ; i <= n; i++)
{
for(int j = 0; j <= n-i ; j++)
{
temp = 0;
for(int k = 0; k < i; k++)
{
temp+=A[j+k];
}
if(temp > max)
max = temp;
//printf("%d\n",max);
}
}
printf("%d\n",max);
return 0;
}
You can do it using a simple array. I am writing the Java solution which you can change into your preferred language.
public class SlidingWindowMaximum {
public static void main(String[] args) {
int[] arr={1,3,-1,-3,5,3,6, 7};
int winSize=3;
int[] arrMax=getMax(arr,winSize);
display(arrMax);
}
// This method gives you the array of the mx value for SlidingWindow problem.
private static int[] getMax(int[] A,int B){
List<Integer> list=new ArrayList<>();
int[] tempA=new int[B];
for(int i=0;i<A.length-B+1;i++){
int tempi=0;
for(int j=i;j<i+B;j++){
tempA[tempi]=A[j];
tempi++;
}
int retMax=getMaxValueFromSortedArray(tempA);
list.add(retMax);
}
int[] array = list.stream().mapToInt(i->i).toArray();
return array;
}
// This method gives you the maxValue from the window of size required.
private static int getMaxValueFromSortedArray(int[] tempA){
int maxValue=0;
for(int j=0;j<tempA.length;j++){
Arrays.sort(tempA);
maxValue=tempA[tempA.length-1];
}
return maxValue;
}
// Display metod to print array elements.
private static void display(int[] arr){
for (int i=0;i<arr.length;i++){
System.out.print(" "+arr[i]);
}
System.out.println("");
}
}

C++ void reverse function

We are converting base 10 to a number in a different base(B). I am having trouble with the void reverse function it will not reverse the order of the numbers.
string convertToBaseB(int num, int b){
int digit;
stringstream answer;
string x="";
while(num>0){
digit=num%b;
num/=b;
answer<<digit;
}
return answer.str();}
void reverse(int x[],int size){//reversing the
for(int k=0; k<size/2; k++){
int temp=x[k];
x[k]=x[size-k-1];
x[size-k-1]=temp;}
}
Your reverse function works fine. However it doesn't looks like C++ to me... In C++ I would have a vector and do:
std::vector<int> arr;
//... fill arr
std::swap_ranges(&arr[0], &arr[arr.size()/2], arr.rbegin());
If you want to stick with your for loop, at least use std::swap like this
void reverse(int x[],int size) {
for(int k=0; k<size/2; k++)
std::swap(x[k], x[size-k-1]);
}
Works for me:
#include <iostream>
using namespace std;
void reverse(int x[],int size)
{
for(int k=0; k<size/2; k++)
{
int temp=x[k];
x[k]=x[size-k-1];
x[size-k-1]=temp;
}
}
int main()
{
const int sz = 9;
int* digits;
digits = new int[sz];
for (int i=0; i < sz; ++i)
{
digits[i] = i;
}
reverse(digits, sz);
for (int i=0; i < sz; ++i)
{
cout<<digits[i]<<" ";
}
cout<<endl;
}

Why I can manipulate dynamic matrix without reference

Let it be a create function for a dynamical allocated array:
void create(int *&a, int dim){
a=new int[dim];
for(int i=0;i<dim;i++){
a[i]=i+1;
}
Here, I need reference (&).
Now, I have a create function for a dynamical allocated matrix:
void create(int **&a,/* int**a, */ int lines,int rows){
...
}
I saw that reference is optional for dynamical allocated matrix create function. Why?
You need reference if you want to allocate the "outer" array - lines. Without it, you can allocate only "inner" arrays - rows (if "outer" array has been already allocated). So in your case, reference is mandatory.
void create(int **a, int lines, int rows)
{
a = new int*[lines]; // passed pointer to 'a' will point to an old address
for(int i = 0; i < lines; i++)
a[i] = new int[rows];
}
If you want to modify the pointer passed to a function inside the function, it needs to be passed by reference.
So no, the reference is not optional in your case. Wherever you saw that it's optional, was wrong.
My bad. I'm sorry.
I saw that refference in assignValues function isn't necessary so I thought that it is unnecessary for the create function, too.
Thank you all for replies.
Again, I'm sorry.
Here is my code:
#include <iostream>
#include <conio.h>
using namespace std;
void create(int **&a, int lines, int rows){
int i;
a = new int*[lines];
for (i = 0; i < lines; i++){
a[i] = new int[rows];
}
}
void assignValues(int **a, int lines, int rows){
int i,j,k = 1;
for (i = 0; i < lines; i++){
for (j = 0; j < rows; j++){
a[i][j] = k;
k++;
}
}
}
void print(int **a, int lines, int rows){
int i, j;
cout << "Matrix is: "<<endl;
for (i = 0; i < lines; i++){
for (j = 0; j < rows; j++){
printf("%3d",a[i][j]);
}
cout << endl;
}
}
int main()
{
int lines = 5;
int rows = 4;
int **a = 0;
create(a, lines, rows);
assignValues(a, lines, rows);
print(a, lines,rows);
_getch();
return 0;
}

How to pass and return 3d array to a function in c++?

I have created a 3d array into main function because one of its size came from used input. I am using C++
std::cin >> size;
typedef int T[8][3];
T* tables = new T[size];
It is basically tables[size][8][3]
Now I have to use this 3d table in different functions and have to store values into it. The best way to do it by make this table as a global variable. But I am not sure that I can do it after main function. The other option I have, that I have to pass this table as a parameter and have to return that at the end of the function.
I have tried both the approach but I am having error. Please help me about this issue. I don't know which approach to choose and how to do it.
Thank you in advance.
**Example:**This an example what I really want to do. Here I create a 3d array in main function and through another function I gave some input into that array and again print that in main function.
#include <iostream>
#include <conio.h>
using namespace std;
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
int M:: pass(int (*table)[8][3],int s)
{
for (i=0;i<s;i++)
{
//int a = tables[i][2][1];
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
table[i][j][k]=i;
}
}
}
return (*table)[8][3]; // not sure about this
}
int main()
{
int size,i,j,k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx;
mx.pass(tables,size); // not sure
for (i=0;i<size;i++)
{
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
cout<<tables[i][j][k];
cout<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"..........." << i <<endl;
}
getch();
}
I don't know if I completely understand your problem. But you can definitely store the pointer locally in your object and reference it elsewhere. Something like this:
class M
{
public:
M(int(*tbl)[8][3]) : table(tbl) { }
int(*table)[8][3];
int i, j, k;
public:
void pass(int size);
};
void M::pass(int s)
{
for (i = 0; i<s; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
table[i][j][k] = i;
}
}
}
}
int main()
{
int size, i, j, k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx(tables);
mx.pass(size); // not sure
for (i = 0; i<size; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
cout << tables[i][j][k];
// or you can also:
// cout << mx.table[i][j][k];
cout << " ";
}
cout << endl;
}
cout << endl;
cout << "..........." << i << endl;
}
_getch();
}
Since you are creating a dynamic 3D array whose two dimensions are fixed, Use a std::array<std::array<int, 3>, 8> as your 2D array. Use a std::vector<__2D_ARRAY_TYPE> to create the 3D array.
#include <iostream>
#include <array>
#include <vector>
int main() {
std::array<std::array<int, 3>, 8> array_2d ;
std::vector<decltype(array_2d)> array_3d ;
int size = 4 ;
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < 8; ++j)
for(int k = 0; k < 3; ++k)
array_2d[j][k] = j + k ;
array_3d.push_back(array_2d);
}
return 0;
}
Something like this you can use easily which does the job more easily without any manual memory management.
You can pass it to a function. The signature would be :
return_type function_name(const std::vector<std::array<std::array<int, 3>, 8>>& array_3d)
{ .... }
In
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
you don't have to write public twice. You can simply put all of the public member data under the keyword public.
Also, you seem to be re-writing your function over again at the very end. Instead of
cout<<tables[i][j][k];
You can write
cout<<*tables