Maximum in a sliding window - c++

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("");
}
}

Related

Extract pair numbers from array

Good evening, folks.
I'm currently experiencing difficulties with extracting pair numbers from an array. I have the following code:
#include <iostream>
using namespace std;
int *paire(int *d, int length) {
int counter = 0;
int position = 0;
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0)
counter++;
}
int *k = new int[counter];
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0) {
k[position] = d[i];
position++;
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int *array1 = paire(b,8);
for (int i=0; i<5; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i];
}
delete[] array1;
return 0;
}
So I think I've got it right with initializing the new array in function paire, but I'm having difficulties to iterate through the array.
P.S. I'm first year in university, so I would really be thankful if you can keep the same simplicity in the answers. Thanks in advance!
It appears that you need to return 2 separate values: the number of even numbers in the array b, and the address of the newly allocated memory that is storing exclusively those even numbers.
Since you can not return multiple variables, one solution that does minimal modification to your code would be as follows.
int *paire(int *d, int length, int& counter) {
counter = 0;
// rest of your function remains unchanged
// ...
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int evenNumbers;
int *array1 = paire(b,8, evenNumbers);
for (int i=0; i<evenNumbers; i++) {
cout<<array1[i];
}
delete [] array1;
return 0;
}
Alternatively, you can return the value in counter and send the reference to the int* variable as an argument to paire function. Or, you can declare paire to have return type void and use references to pass back both the values.
You can further simplify your function by allocating to that of the length and returning the counter by an output parameter.
#include <iostream>
using namespace std;
int *paire(int *d, int length, int &counter) {
counter = 0;
int *k = new int[length]; // allocate for the maximum memory
for (int i = 0; i < length; ++i) {
if (d[i] % 2 == 0) {
k[counter++] = d[i];
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int counter = 0;
int *array1 = paire(b,8, counter);
for (int i=0; i<counter; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i] << " ";
}
delete [] array1;
return 0;
}
But please note that as others have already pointed out this method is quite error prone in the sense that it leaves the responsibility to the client to delete the internal memory used by paire function.

Merging two arrays in ascending order

I know the logic how to merge two arrays but the problem is how to code.
This was my code n it is giving correct ans but my sir told me that do it again,please tell me what I have to add in this code,
#include<iostream>
using namespace std;
int mergeArrays(int array1[],int size1,int array2[],int size2);
int main()
{
const int size1=8;
const int size=12;
int arrayA[size1]={10,25,37,49,50,51,55,60};
int arrayB[size]={2,5,26,27,29,32,40,45,70,80,90,95};
mergeArrays(arrayA,size1,arrayB,size);
}
int mergeArrays(int array1[],int size1,int array2[],int size2)
{
int size3=size1+size2;
int *array3=new int[size3];
int k=0;
for(int i=0;i<size1;i++)
{
array3[k]=array1[i];
cout<<" "<<array3[k];
}
int j=0;
for(int i=size1;i<size2;i++)
{
array3[k]=array2[j];
}
for(int i=size1;i<size2;i++)
{
for(int j=0;j<size2;j++)
{
array3[i]=array2[j];
cout<<" "<<array3[i];
}
cout<<endl;
delete[]array3;
return array3[k++];
}
}
I had searched this in many places but could not corrected my code
I had written this code but it is not giving correct ans.
#include<iostream>
using namespace std;
int merge(int *a,int *b,int aSize,int bSize);
int main()
{
const int aSize={8};
const int bSize={12};
int arrayA[aSize]={10,25,37,49,50,51,55,60};
int arrayB[bSize]={2,5,26,27,29,32,40,45,70,80,90,95};
merge(arrayA,arrayB,aSize,bSize);
return 0;
}
int merge(int *a,int *b,int aSize ,int bSize)
{
int cSize=aSize+bSize;
int *c=new int[cSize];
int j=0,k=0;
int i=0;
while(i<=aSize&&j<=bSize )
{
if(a[aSize ]<=b[bSize])
{
c[k]=a[aSize];
k++;
i++;
}
else
{
c[k]=b[bSize];
k++;
j++;
}
}
for(int i=0;i<k;i++)
{
cout<<c[i]<<endl;
}
delete[]c;
return c[k++];
}
your sir request you do Merging two arrays in ascending order. so i think you should return a new array, fill with array1 and array2's element, and the elements should be ascending order. here is a implement.(suppose your input arraies is already in ascending order.)
#include <iostream>
using namespace std;
int mergeArrays(int array1[],int size1,int array2[],int size2, int outArray[]);
int main()
{
const int size1=8;
const int size=12;
int arrayA[size1]={10,25,37,49,50,51,55,60};
int arrayB[size]={2,5,26,27,29,32,40,45,70,80,90,95};
int outArray[size1+size];
int len = mergeArrays(arrayA,size1,arrayB,size, outArray);
cout <<" "<< len;
for (int i = 0; i< size1+size; ++i){
cout <<" " << outArray[i];
}
}
int mergeArrays(int array1[], int size1, int array2[], int size2, int outArray[])
{
int i=0, j=0, k=0;
int retSize = size1+size2;
while (k<retSize){
if (i==size1){// only left array2, copy it
for (; j<size2; ++j){
outArray[k++] = array2[j];
}
}else if (j == size2) { // only left array1, copy it
for (; i<size1; ++i){
outArray[k++] = array1[i];
}
}
else if (array1[i] > array2[j]){ // copy the min value to outArray
outArray[k++] = array2[j++];
}else{
outArray[k++] = array1[i++];
}
}
return k;
}
now, let's look at your first code:
int mergeArrays(int array1[],int size1,int array2[],int size2)
{
int size3=size1+size2;
int *array3=new int[size3];
int k=0;
for(int i=0;i<size1;i++)
{
array3[k]=array1[i]; // k is not changed, so you just assign array1's each value to array3[0]
cout<<" "<<array3[k];
}
int j=0;
// what's the purpose of this loop?
// and in loop, you don't use i, you just repeat set array3[0] = array2[0]!!
for(int i=size1;i<size2;i++)
{
array3[k]=array2[j];
}
for(int i=size1;i<size2;i++) // if array2's length bigger than array1's, will enter this loop.
{
for(int j=0;j<size2;j++)
{
array3[i]=array2[j]; // this just repeat assign array2's each value to array3[i]!!
cout<<" "<<array3[i];
}
cout<<endl;
delete[]array3;
return array3[k++]; // you delete array3, but at here you access it!! this will crash!
// also, in this for i loop, you have return, so it will only execute once.
}
// reach function end and no return if not enter for loop.
}
I haven't looked at your second code. I think you still need to do more study.

Merge sort throwing index out of bounds exception in Xcode

I am trying to implement a simple merge sort for even number of elements using the following code :
#include <iostream>
using namespace std;
void merge(int arr1[10],int len1,int arr2[10],int len2,int arr3[10],int len3)
{
int i,j,k;
while(i<len1&&j<len2&&k<len3)
{
if(arr1[i]<arr2[j])
{
arr3[k] = arr1[i];
i++;k++;
}
else if(arr1[i]>arr2[j])
{
arr3[k] = arr2[j];
k++;
j++;
}
}
}
void mergeSort(int a[10],int n)
{
int arr1[10],arr2[10];
for(int i=0;i<n/2;i++)
{
arr1[i] = a[i];
}
for(int i=(n/2+1);i<n;i++)
{
arr2[i] = a[i];
}
mergeSort(arr1,n/2);
mergeSort(arr2,n/2);
merge(arr1,n/2,arr2,n/2,a,n);
}
int main() {
int arr[10],n;
cout << "Enter number of elements\n";
cin >> n;
cout<<"Enter elements\n";
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
mergeSort(arr, n);
cout<<"Sorted array is"<<endl;
for(int i=0;i<n;i++)
{
cout<<arr[i]<<endl;
}
return 0;
}
But I am getting a EXC_BAD_ACESS error on the opening brace of the mergeSort() method. I am new to Xcode and not sure on how to fix this. How do I fix this ?
Thanks !
You have forgot to initialize the int variables i, j, k to 0 (zero) in the function definition for merge(...).
void merge(int arr1[10],int len1,int arr2[10],int len2,int arr3[10],int len3)
{
// int i,j,k; // Not initialized.
int i = j = k = 0;
while(i<len1&&j<len2&&k<len3)
{
...
...
}
After Edit:
void mergeSort(int a[10],int n)
{
int arr1[10],arr2[10];
for(int i=0;i<n/2;i++)
{
arr1[i] = a[i];
}
// Here you are skipping the middle index.
// Let's say array is of length 10, then arr1 contains elements on index from 0 to 4 (5 elements),
// whereas arr2 contains elements on index from 6 to 9 (4 elements).
// 5th index element is missing.
// for(int i=(n/2+1);i<n;i++)
for(int i=(n/2);i<n;i++)
{
arr2[i] = a[i];
}
mergeSort(arr1,n/2);
mergeSort(arr2,n/2);
merge(arr1,n/2,arr2,n/2,a,n);
}
Hope it helps!

c++ function that fills array

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;
}

Find all possible arrays of size n constructed with all possible combinations of elements from another array in all possible orders?

For an array A of arbitrary length n, I'd like to fill in a n x m array B with all combination of elements from A that includes all possible orders of those elements. For example, if A = {1, 2, 3} and m = 2, I'd like to get B as:
11
12
13
21
22
23
31
32
33
What is an efficient way to do this in C/C++? Thanks!
EDIT: Here is what I figured out to work (data is within the class combs which is basically a matrix class with some added tricks):
void combs::setCombs (int arr[], int n, int m) {
int z, tmp, repeat;
int max = (int (pow(double (n), double( m ))));
for (int i = 0; i < m; i++) {
z = 0;
repeat = int (pow( double (n), double (i)));
for (int j = 0; j < repeat; j++) {
for (int k = 0; k < n; k ++) {
for (int p = 0; p < max/(n*repeat); p ++) {
cout << arr[k] << endl;
data[z*ROWS + i] = arr[k];
z++;
}
}
}
}
}
As mentioned by #Joachim Pileborg your question lacks a lot in the way of parameters.But lets say you could guarantee that you were passing me a vector of SORTED UNIQUE ints. Then this brute force would be possible:
std::vector< std::string > Combo( const std::vector< char >& source, int m )
{
std::vector< std::vector< char >::const_iterator > digits( length, source.cbegin() );
std::vector< std::string > result( source.size() * m );
for( int i = 0; i < result.size(); i++ )
{
for( int j = 0; j < m; j++ )
{
result[i] += *(digits[j]);
}
for( int j = digits.size() - 1; j >= 0; j-- )
{
++digits[j];
if( digits[j] == source.cend() )
{
digits[j] = source.cbegin();
}
else
{
break;
}
}
}
return result;
}
What you are describing sounds like partial permutations, not combinations.
If you are using c++, then it is recommended to use vectors, because vectors can tell you their size, and they free their own memory. An implementation with vectors would be as follows:
vector<vector<int> > partialPermutations(vector<int> &A,int m){
int i,i2,t,n=A.size(),total=1;
for(i=0;i<m;i++) total*=n;
vector<vector<int> > result;
for(i=0;i<total;i++){
result.push_back(vector<int>());
t=i;
for(i2=0;i2<m;i2++){
result[i].push_back(A[t%n]);
t/=n;
}
}
return result;
}
int main() {
vector<int> A;
int total,i,i2;
for(i=1;i<=4;i++) A.push_back(i);
vector<vector<int> > re=partialPermutations(A,2);
for(i=0;i<re.size();i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
return 0;
}
If you still want to use arrays, then the code would be as follows:
int** partialPermutations(int*A,int n,int m,int &total){
int i,i2,t;
total=1;
for(i=0;i<m;i++) total*=n;
int **result=new int*[total];
for(i=0;i<total;i++){
t=i;
result[i]=new int[m];
for(i2=0;i2<m;i2++){
result[i][i2]=A[t%n];
t/=n;
}
}
return result;
}
int main() {
int A[]={1,2,3,4};
int total,i,i2;
int **re=partialPermutations(A,4,2,total);
for(i=0;i<total;i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
//Cleanup
for(i=0;i<total;i++) delete[] re[i];
delete[] re;
return 0;
}
Notice that by using arrays, we have to recover the size of the resulting array (passing total by reference), and we have to free the memory afterwards. None of this is needed with vectors.
#include<iostream>
using namespace std;
void printStrRec(string s,string ans,int k,int i)
{
if(i==k)
{
cout<<"\nAnswer : "<<ans<<endl;
}
else
{
for(int x=0;x<s.size();++x)
{
ans[i]=s[x];
printStrRec(s,ans,k,i+1);
}
}
}
void printStrings(string s,int k)
{
string ans;
for(int p=0;p<k;++p)
{
ans+="x";
}
printStrRec(s,ans,k,0);
}
int main()
{
int k;
string s;
cout<<"Enter the set : ";
cin>>s;
cout<<"\nEnter k : ";
cin>>k;
printStrings(s,k);
return 0;
}
Hope that helps.