Convert to a recursive function - c++

Describe a recursive function that determines the number of variables
a sign in a non-zero array.
I did it in a non-recursive one, but I need it in a recursive one.
int recur_change_sign(int* arr, int n) {
int count = 0;
for (int i = 0; i < n - 1; i++) {
if ((arr[i] < 0 && arr[i + 1] >= 0) || (arr[i] >= 0 && arr[i + 1] < 0)) {
count++;
}
}
return count;
}

You can implement it very easily like this:
int recur_change_sign(int* arr, int n) {
if (n <= 1) return 0;
return ((arr[0] < 0 && arr[1] >= 0) || (arr[0] >= 0 && arr[1] < 0)) + recur_change_sign(arr + 1, n - 1);
}

It can also be realized by removing it from the tail.
int recur_change_sign(int* arr, int n) {
if (n <= 1) return 0;
return ((arr[n-2] < 0 && arr[n-1] >= 0) || (arr[n-2] >= 0 && arr[n-1] < 0)) + recur_change_sign(arr, n - 1);
}

Related

Both are using Expand Around Center Algorithm for finding longest palindromic substring and why is one faster a lot?

Here is the faster solution A that only perform 6ms on leetcode and it's almost as fast as Manacher Algorithm(6ms on leetcode).
class Solution {
public:
string longestPalindrome(string s) {
if (s.empty()) return "";
if (s.size() == 1) return s;
int min_start = 0, max_len = 1;
for (int i = 0; i < s.size();) {
if (s.size() - i <= max_len / 2) break;
int j = i, k = i;
while (k < s.size()-1 && s[k+1] == s[k]) ++k; // Skip duplicate characters.
i = k+1;
while (k < s.size()-1 && j > 0 && s[k + 1] == s[j - 1]) { ++k; --j; } // Expand.
int new_len = k - j + 1;
if (new_len > max_len) { min_start = j; max_len = new_len; }
}
return s.substr(min_start, max_len);
}
};
And I don't understand why the blow solution B is slow to much compared with solution A, which costs 16ms runtime.
class Solution {
public:
int expandAroundCenter(string s, int left,int right) {
int L = left, R = right;
while(L >=0 && R < s.length() && s[L] == s[R]) {
L--;
R++;
}
return R - L - 1;
}
string longestPalindrome(string s) {
int start = 0, end = 0;
if (s.empty()) return "";
if (s.size() == 1) return s;
for(size_t i = 0; i < s.length(); i++) {
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = std::max(len1, len2);
if(len > end - start + 1) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
if(start + len > s.length()) break;
}
return s.substr(start, end - start + 1);
}
};
Since they are both Expand Around Center Algorithm and get O(N^2) time complexity and O(1) space complexity(Manacher's Algorithm gets O(n) time complexity), I can only speculate the coding method is the most important factor. Well, if it's the case and I really want to know why.
With the optimazation, solution B is still slower 50% than A.
class Solution {
public:
int expandAroundCenter(const string& s, int left,int right) {
int L = left, R = right;
while(L >=0 && R < s.length() && s[L] == s[R]) {
L--;
R++;
}
return R - L - 1;
}
string longestPalindrome(const string& s) {
int max_len = 0;
int min_start = 0;
if (s.empty()) return "";
if (s.size() == 1) return s;
for(size_t i = 0; i < s.length(); i++) {
if (s.size() - i <= max_len / 2)
break;
int j = i, k = i;
while (k < s.size()-1 && s[k+1] == s[k]) ++k;
int len = expandAroundCenter(s, j, k);
if(len > max_len) {
max_len = len;
min_start = j - (len - (k - j + 1)) / 2;
}
}
return s.substr(min_start, max_len);
}
};
Algorithm A skips pumped character sequences first which most likely make up for a significant portion of the benchmark. Algorithm B falls for that trap and iterates over the pumped sequence twice, once for each call of the predicate.
Take the benchmark suite, and replace all single character repetitions by a [Pad][Character][Pad], then this optimization breaks.

Creates A Number Pattern Using Array

So the numbers pattern going like this :
Input : 2
Output :
0 0 0 1 0 0 0
0 0 2 0 12 0 0
0 3 0 0 0 11 0
4 0 0 0 0 0 10
0 5 0 0 0 9 0
0 0 6 0 8 0 0
0 0 0 7 0 0 0
I have solved it using usual method, but when I tried with array, the output is really messed up. Any suggestion how to make this number pattern with array?
This is my code that creates this number pattern :
int input, n, mid, i, j;
cin >> input;
n = (2*input)+3;
mid = (n+1)/2;
for(i = 1; i <= n; i++) {
for (j = 1; j <= mid; j++) {
if (i <= mid && j == mid-i+1) cout << i << " ";
else if (i > mid && j == mid-n+i) cout << i << " ";
else cout << "0 ";
}
for (j = mid+1; j <= n; j++) {
if (i >= mid && j == n+mid-i) cout << (2*n-i) << " ";
else if (i < mid && j == mid+i-1) cout << (2*n-i) << " ";
else cout << "0 ";
}
cout << endl;
}
Thanks in advance.
I think this code(working) might help you.
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main() {
int input, n, mid, i, j;
cin >> input;
n = (2*input)+3;
mid = (n+1)/2;
int arr[n][n];
memset(arr, 0, sizeof(arr));
for(i = 1; i <= n; i++) {
for (j = 1; j <= mid; j++) {
if (i <= mid && j == mid-i+1) arr[i - 1][j - 1] = i;
else if (i > mid && j == mid-n+i) arr[i - 1][j - 1] = i;
}
for (j = mid+1; j <= n; j++) {
if (i >= mid && j == n+mid-i) arr[i - 1][j - 1] = 2 * n - i;
else if (i < mid && j == mid+i-1) arr[i - 1][j - 1] = 2 * n - i;
}
}
}
Supplementing baymaxx, if you desire dynamic memory allocation:
#include <iostream>
#include <stdio.h>
#include <string.h>
int input, n, mid, i, j;
cin >> input;
n = (2*input)+3;
mid = (n+1)/2;
// create array of the specified size.
int** arr = (int**) malloc (n * sizeof(int**));
for (int p = 0; p < n; ++p) {
arr[p] = (int*) malloc(n * sizeof(int));
for (int q = 0; q < n; ++q) {
arr[p][q] = 0;
}
}
// fill array (algorithm attr. baymaxx)
for(i = 1; i <= n; i++) {
for (j = 1; j <= mid; j++) {
if (i <= mid && j == mid-i+1) {
arr[i - 1][j - 1] = i;
}
else if (i > mid && j == mid-n+i) {
arr[i - 1][j - 1] = i;
}
}
for (j = mid+1; j <= n; j++) {
if (i >= mid && j == n+mid-i) {
arr[i - 1][j - 1] = 2 * n - i;
}
else if (i < mid && j == mid+i-1) {
arr[i - 1][j - 1] = 2 * n - i;
}
}
}
// print array
for (int p = 0; p < n; ++p) {
for (int q = 0; q < n; ++q) {
int x = arr[p][q];
std::cout << x << " ";
}
std::cout << endl;
}
// delete array
for (int i = 1; i < n; ++i) {
free(arr[i]);
}
free(arr);

How can I make variables available to my function? [duplicate]

This question already has answers here:
Passing a 2D array to a C++ function
(18 answers)
Closed 9 years ago.
Code in C++:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
void check(int i,int j);
int main()
{
int n;
cin >> n;
int a[n][n];
int b[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
b[i][j] = 0;
}
}
b[0][0] = 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; i++)
{
cin >> a[i][j];
}
}
check(0, 0);
if (b[n - 1][n - 1] == 1)
cout << "yesssss";
else
cout << "no!!!!";
}
void check(int i, int j)
{
if((i - 1) >= 0 &&
(i - 1) <= (n - 1) &&
(abs(a[i][j] - a[i - 1][j]) >= 10) &&
b[i - 1][j] == 0)
{
b[i - 1][j] = 1;
check(i - 1, j);
}
if((i + 1) >= 0 &&
(i + 1) <= (n-1) &&
(abs(a[i][j] - a[i + 1][j]) >= 10) &&
b[i + 1][j] == 0)
{
b[i + 1][j] = 1;
check(i + 1, j);
}
if((j + 1) >= 0 &&
(j + 1) <= (n - 1) &&
(abs(a[i][j] - a[i][j + 1]) >= 10) &&
b[i][j + 1] == 0)
{
b[i][j + 1] = 1;
check(i, j + 1);
}
if((j - 1) >= 0 &&
(j-1) <= (n - 1) &&
(abs(a[i][j] - a[i][j - 1]) >= 10) &&
b[i][j - 1] == 0)
{
b[i][j - 1] = 1;
check(i, j - 1);
}
}
My code has a function named check inside which integer variable n and arrays a and b. I want them to be made available to this function. If i declare global variable, then I can't use cin outside the main function.
How can I make these variables available to my check function?
Since you do not know the size of the array before you pass it into check, you need to use a pointer to a pointer (and not a 2D array). Here's the modified code (you also had a typo in your nested for-loop where you should have had a j instead of an i):
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
void check(int i, int j, int** a, int** b, int n);
int main() {
int n;
cin >> n;
int** a;
int** b;
a = new int* [n];
b = new int* [n];
for (int i = 0; i < n; i++)
a[i] = new int[n];
for (int i = 0; i < n; i++)
b[i] = new int[n];
for (int i=0;i<n;i++) {
for (int j=0;j<n;j++) {
b[i][j]=0;
}
}
b[0][0]=1;
for (int i=0;i<n;i++) {
for (int j=0;j<n;j++) {
cin >> a[i][j];
}
}
check(0,0,a,b,n);
if (b[n-1][n-1] == 1)
cout << "yesssss";
else
cout << "no!!!!";
}
void check(int i, int j, int** a, int** b, int n)
{
if((i-1)>=0 && (i-1)<=(n-1) && (abs(a[i][j]-a[i-1][j])>=10) && b[i-1][j]==0)
{
b[i-1][j]=1;
check(i-1,j,a,b,n);
}
if((i+1)>=0 && (i+1)<=(n-1) && (abs(a[i][j]-a[i+1][j])>=10) && b[i+1][j]==0)
{
b[i+1][j]=1;
check(i+1,j,a,b,n);
}
if((j+1)>=0 && (j+1)<=(n-1) && (abs(a[i][j]-a[i][j+1])>=10) && b[i][j+1]==0)
{
b[i][j+1]=1;
check(i,j+1,a,b,n);
}
if((j-1)>=0 && (j-1)<=(n-1) && (abs(a[i][j]-a[i][j-1])>=10) && b[i][j-1]==0)
{
b[i][j-1]=1;
check(i,j-1,a,b,n);
}
}

equidivision partition using breadth first search

i was trying to solve a breadth first search problem on spoj.the problem statement is as follows:
An equidivision of an n × n square array of cells is a partition of the n^2 cells in the array in exactly n sets, each one with n contiguous cells. Two cells are contiguous when they have a common side.
the problem link is:http://www.spoj.com/problems/EQDIV/
my code:http://ideone.com/OjluJG
#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<queue>
using namespace std;
#define pii pair< int, int>
int n, m, grid[105][105];
char inp[101 * 101];
bool inRange(int i, int j)
{
m = n;
return (i >= 0 && i < n && j >= 0 && j < m);
}
int main()
{
int i, j, comp;
scanf("%d", &n);
while (n != 0)
{
if (n == 1)
{
printf("good\n");
scanf("%d", &n);
continue;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
grid[i][j] = 0;
}
}
int a, b, start1[n], start2[n], print = 0, c, d;
queue< pii > Q;
pii p;
getchar();
for (i = 1; i <= n - 1; i++)
{
gets(inp);
stringstream ss(inp);
for (j = 1; j <= n; j++)
{
ss >> a >> b;
if (j == 1)
{
start1[i - 1] = a;
start2[i - 1] = b;
//printf("%d %d\n",start1[i-1],start2[i-1]);
}
grid[a - 1][b - 1] = i;
}
}
for (int x = 0; x < n; x++)
{
int count = 1;
if (x == n - 1)
{
comp = 0;
p.first = c;
p.second = d;
Q.push(p);
}
else
{
comp = x + 1;
p.first = start1[x] - 1;
p.second = start2[x] - 1;
Q.push(p);
}
while (!Q.empty())
{
p = Q.front();
i = p.first;
j = p.second;
Q.pop();
grid[i][j] = -1;
if (x != n - 1)
{
if (inRange(i + 1, j) && grid[i + 1][j] == 0)
{
c = i + 1;
d = j;
}
if (inRange(i - 1, j) && grid[i - 1][j] == 0)
{
c = i - 1;
d = j;
}
if (inRange(i, j + 1) && grid[i][j + 1] == 0)
{
c = i;
d = j + 1;
}
if (inRange(i, j - 1) && grid[i][j - 1] == x + 1)
{
c = i;
d = j - 1;
}
}
if (inRange(i + 1, j) && grid[i + 1][j] == comp)
{
p.first = i + 1;
p.second = j;
Q.push(p);
count += 1;
}
if (inRange(i - 1, j) && grid[i - 1][j] == comp)
{
p.first = i - 1;
p.second = j;
Q.push(p);
count += 1;
}
if (inRange(i, j + 1) && grid[i][j + 1] == comp)
{
p.first = i;
p.second = j + 1;
Q.push(p);
count += 1;
}
if (inRange(i, j - 1) && grid[i][j - 1] == comp)
{
p.first = i;
p.second = j - 1;
Q.push(p);
count += 1;
}
}
if (count != n)
{
print = 1;
printf("wrong\n");
break;
}
}
if (print == 0)
printf("good\n");
//printf("%d %d\n",c,d);
scanf("%d", &n);
}
}
i am getting wrong answer ,don't know why?
can someone provide the testcase for which it is wrong?

Shortest distance using BFS

I am trying to solve this SPOJ problem. The question asks to find the shortest path for each black(1) pixel.
Since it is a unweighted graph I used BFS.
for input:
3 3
010
000
000
it's giving:
323
434
343
instead of:
101
212
323
This is my code
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
typedef pair < int, int >ii;
int R, C, i, j;
queue < ii > myQueue;
int visit[100][100];
int dist[100][100];
void bfs(ii s)
{
int i, j;
int count = 0;
ii node;
memset(visit, 0, sizeof(visit));
memset(dist, 0, sizeof(dist));
myQueue.push(s);
dist[node.first][node.second] = 0;
while (!myQueue.empty()) {
node = myQueue.front();
myQueue.pop();
if (visit[node.first][node.second])
continue;
visit[node.first][node.second] = 1;
//cout << node.first << " " << node.second << "\n";
i = node.first;
j = node.second;
if (j - 1 < R && j - 1 >= 0) {
myQueue.push(make_pair(i, j - 1));
if(dist[i][j - 1] == 0)
dist[i][j - 1] = dist[i][j] + 1;
}
if (j + 1 < R && j + 1 >= 0) {
myQueue.push(make_pair(i, j + 1));
if(dist[i][j+1] == 0)
dist[i][j + 1] = dist[i][j] + 1;
}
if (i - 1 < C && i - 1 >= 0) {
myQueue.push(make_pair(i - 1, j));
if(dist[i-1][j] == 0)
dist[i - 1][j] = dist[i][j] + 1;
}
if (i + 1 < C && i + 1 >= 0) {
myQueue.push(make_pair(i + 1, j));
if(dist[i+1][j] == 0)
dist[i + 1][j] = dist[i][j] + 1;
}
}
}
int main()
{
char input[100][100];
scanf("%d %d", &R, &C);
for (i = 0; i < R; i++)
scanf("%s", &input[i]);
int GRID[R][C];
for (i = 0; i < R; i++)
for (j = 0; j < C; j++)
GRID[i][j] = input[i][j] - '0';
for (i = 0; i < R; i++)
for (j = 0; j < C; j++) {
if (GRID[i][j] == 1)
bfs(make_pair(i, j));
}
for (i = 0; i < R; i++) {
for (j = 0; j < C; j++) {
printf("%d", dist[i][j]);
}
printf("\n");
}
}
ideone
Try this:
if (j - 1 < R && j - 1 >= 0) {
myQueue.push(make_pair(i, j - 1));
if(dist[i][j - 1] == 0)
dist[i][j - 1] = dist[i][j] + 1;
}
do this for all dist[][].
You have doubled result may be because you run your BFS twice between paired vertices.
But I'm not sure.