Setting Base Cases for Recursive Function - recursion

class Solution {
//given a location on the matrix, this function recursively find the deepest possible depth, which is the length of a side of a found square
private int isSquare(int row_index, int col_index, int depth, char[][] matrix) {
int last_row = row_index + depth;
int last_col = col_index + depth;
if (row_index >= matrix.length || col_index >= matrix[0].length) {
return 0;
}
if (last_row >= matrix.length || last_col >= matrix[0].length) {
return 0;
}
for (int i = col_index; i < last_col; i++) {
if (matrix[row_index][i] != '1') {
return 0;
}
}
for (int i = row_index; i < last_row; i++ ) {
if (matrix[i][col_index] != '1') {
return 0;
}
}
return Math.max(depth, isSquare(row_index, col_index, depth + 1, matrix));
}
public int maximalSquare(char[][] matrix) {
int max = 0;
for (int row = 0; row < matrix.length; row ++) {
for (int col = 0; col <matrix[0].length; col ++) {
int curr_depth = isSquare(row, col, 1, matrix);
if (curr_depth > max) {
max = curr_depth;
}
}
};
return max * max;
}
}
Hi, I was working on LeetCode 221, and it seems like that my solution is not passing test cases with output 1, where the biggest square on the given matrix is just 1 x 1. To me it looks like those depth 1 cases are not passing the two for loops in function isSquare, which is supposed to catch 0s in the square.
I tried LC debugging tool but it did not help much, and my base cases seem fine to me. Please let me know what is going on here. For the problem, https://leetcode.com/problems/maximal-square/
One of the depth 1 test cases that I am failing is below.
Input:
[["0","1"],["1","0"]]
Output:
0
Expected:
1

Related

How would this shell-sort algorithm be coded in recursive?

I understand that any iterative function can be written recursively, but I still don't quite understand how to write it as a recursive function.
This function receives an array (elements) and a int (number of elements), and sorts them from lower to higher, but I don't get how to make it recursive, any help would be appreciated!
void ShellSort(int *arr, int num){
for (int i = num / 2; i > 0; i = i / 2)
{
for (int j = i; j < num; j++)
{
for(int k = j - i; k >= 0; k = k - i)
{
if (arr[k+i] >= arr[k])
{
break;
}
else
{
arr[k]=arr[k] + arr[k+i];
arr[k+i]=arr[k] - arr[k+i];
arr[k]=arr[k] - arr[k+i];
}
}
}
}
return ;
}

What is causing the buffer overrun error in below code

Unable to figure out what is causing the buffer overflow in below code. I reckon it has to do with the vector but I am guarding against out of bounds access. Is there anything else that could be causing the overflow?
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
bool canPartition = true;
vector<vector<int>> dp(nums.size(), vector<int>(sum / 2 + 1, -1));
sum = accumulate(nums.begin(),nums.end(),0);
if (sum % 2 != 0)
{
canPartition = false;
}
if (true == canPartition)
{
canPartition = canPartitionRecursive(nums, 0, sum/2, dp);
}
return canPartition;
}
bool canPartitionRecursive(vector<int>& nums, int index, int sum,
vector<vector<int>>& dp)
{
if (sum == 0)
{
return true;
}
if (index >= nums.size() || sum < 0)
{
return false;
}
if (dp[index][sum] != -1)
{
if (true == canPartitionRecursive(nums, index+1, sum - nums[index],dp))
{
dp[index][sum] = 1;
return true;
}
dp[index][sum] = canPartitionRecursive(nums, index + 1, sum, dp);
}
return dp[index][sum] = 1? true:false;
}
};
This looks like a transpositional error (all subvector will have size 1):
int sum = 0;
vector<vector<int>> dp(nums.size(), vector<int>(sum / 2 + 1, -1));
sum = accumulate(nums.begin(),nums.end(),0);
Perhaps calculation of sum should be moved before dp initialization?

Binary coded GA with NSGA-II in R

I have a multiobjective minimization function. I want to use NSGA-II in R. There are packages for this: nsga2R and mco. But these packages do not support binary coded chromosomes. In my fitness function I need binary chromosomes to achive best solution because of my problem's structure. Is there any way to use binary coded chromosome in nsga2 (or maybe with different algorithm) for R? Thanks.
I got the same problem so I decided to fix it on my own. But no guarentee if it's the right way.
The following part is for the package 'mco'
I copied parts out of the offical nsga2 implementation into the 'mco' package.
This workaround is only for binary (0-1) variables.
1. In /src/nsga2.c rewrite the functions as follows:
static void mutate_ind (nsga2_ctx *ctx, individual *ind) {
int j;
double prob;
GetRNGstate();
for (j = 0; j < ctx->input_dim; j++)
{
//for (k=0; k < ctx[j]->input_dim; k++)
//{
//prob = randomperc();
prob = unif_rand();
if (prob <= ctx->mutation_probability) {
if (ind->input[j] == 0)
{
ind->input[j] = 1;
}
else
{
ind->input[j] = 0;
}
ctx->input_mutations+=1;
}
//}
}
PutRNGstate();
then
static void crossover (nsga2_ctx *ctx,
individual *parent1, individual *parent2,
individual *child1, individual *child2) {
int i;
int nbits=1;
double rand;
int temp, site1, site2, temp2, temp3;
GetRNGstate();
rand=unif_rand();
if (rand <= ctx->crossing_probability)
{
ctx->input_crossings++;
//site1 = rnd(0,ctx->input_dim);
//site2 = rnd(0,ctx->input_dim);
if(unif_rand()<=0.5){
temp2=0;
}else{
temp2=1;
}
if(unif_rand()<=0.5){
temp3=0;
}else{
temp3=1;
}
site1=temp2;
site2=temp3;
if (site1 > site2)
{
temp = site1;
site1 = site2;
site2 = temp;
}
for (i=0; i<site1; i++)
{
child1->input[i] = parent1->input[i];
child2->input[i] = parent2->input[i];
}
for (i=site1; i<site2; i++)
{
child1->input[i] = parent2->input[i];
child2->input[i] = parent1->input[i];
}
for (i=site2; i<nbits; i++)
{
child1->input[i] = parent1->input[i];
child2->input[i] = parent2->input[i];
}
}
else
{
for (i=0; i<nbits; i++)
{
child1->input[i] = parent1->input[i];
child2->input[i] = parent2->input[i];
}
}
PutRNGstate();
}
and
static void population_initialize(nsga2_ctx *ctx, population *pop) {
GetRNGstate();
int i, j;
for (i = 0; i < pop->size; ++i) {
for (j=0; j<ctx->input_dim; ++j) {
/* Generate random value between lower and upper bound */
//double delta = ctx->upper_input_bound[j] - ctx->lower_input_bound[j];
//pop->ind[i].input[j] = ctx->lower_input_bound[j] + delta*unif_rand();
if(unif_rand() <= 0.5){
pop->ind[i].input[j] = 0;
}
else{
pop->ind[i].input[j] = 1;
}
}
}
PutRNGstate();
}
2. define the function randomperc() as follows
double seed;
double oldrand[55];
int jrand;
/* Create next batch of 55 random numbers */
void advance_random ()
{
int j1;
double new_random;
for(j1=0; j1<24; j1++)
{
new_random = oldrand[j1]-oldrand[j1+31];
if(new_random<0.0)
{
new_random = new_random+1.0;
}
oldrand[j1] = new_random;
}
for(j1=24; j1<55; j1++)
{
new_random = oldrand[j1]-oldrand[j1-24];
if(new_random<0.0)
{
new_random = new_random+1.0;
}
oldrand[j1] = new_random;
}
}
/* Fetch a single random number between 0.0 and 1.0 */
double randomperc()
{
jrand++;
if(jrand>=55)
{
jrand = 1;
advance_random();
}
return((double)oldrand[jrand]);
}
3. replace every unif_rand() with randomperc() in 'nsga2.c'
4. build the package in R

How to count how many different vowels are in one word from text file in C?

I am confused about counting how many differents vowels are in one word? This is were i got so far... I am saving word by word in the variable word[] and then check char by char whether is vowel or not... but i don't know how to count how many different vowels are in the word? Please help. Thanks in advance.
int i,j,words = 0;
while(fgets(row,MAX,f) != NULL)
{
int flag = 0;
int n = 0;
for(i = 0; i < strlen(row); i++)
{
if(isalpha(row[i]))
{
if(!flag)
{
flag = 1;
}
word[n++] = row[i];
}
else if(flag)
{
flag = 0;
word[n] = '\0';
for(j = 0; j < strlen(word);j++)
{
if(isvowel(word[i]))
{
c = word[i];
}
// i stopped here cause i donno how to check whether the char is different from all the others
}
}
}
}
As you find each vowel, simple set a flag of an array to note the vowel was found. Then count the number of flags. The trick is to effectively convert c (the vowel) into an index - that is where you are stuck.
char *strchr(const char *s, int c) is useful. It locates the first occurrence of (char) c in the string pointed to by s. Converting the result to an index for the flag array is then easy.
Let's say 'A' is the same as 'a' for vowel counting.
int DifferentVowelCount(const char *s) {
static const char *Vowels = "AaEeIiOoUu";
bool VowelExist[5] = { 0 };
while (*s) {
char *p = strchr(Vowels, *s);
if (p != NULL) {
int index = (int) (p - Vowels); // index is 0 to 9
index /= 2;
VowelExist[index] = 1;
}
s++;
}
int sum = 0;
int i;
for (i = 0; i < 5; i++) {
if (VowelExist[i]) {
sum++;
}
}
return sum;
}
Okay it seems like the function for counting the different vowels in one word is created manually, but this solution really works and here it is:
int diff_vowels(char *word)
{
char a = 'a',b = 'e', c = 'i', d = 'o', e = 'u';
int a1 = 0,b1 = 0,c1 = 0,d1 = 0,e1 = 0;
while(*word)
{
if(isalpha(*word))
{
if(tolower(*word) == 'a') a1 = 1;
else if(tolower(*word) == 'e') b1 = 1;
else if(tolower(*word) == 'i') c1 = 1;
else if(tolower(*word) == 'o') d1 = 1;
else if(tolower(*word) == 'u') e1 = 1;
}
word++;
}
return a1 + b1 + c1 + d1 + e1;
}

Inside boundaries

I'm using this article to write a fluid simulation application.
I can't manage to implement the inside boundaries. As far as i know when I'm setting the boundaries (in the set_bnd function) for each cell that is inside the boundary I should calculate the average value from the adjacent non-boundary cells like this:
for (i = 0 ; i < n ; i++)
{
for (j = 0 ; j < n ; j++)
{
if (isBoundary(i,j)
{
sum = 0;
count = 0;
if (!isBoundary(i+1,j) {
sum += x[i+1][j];
}
if (!isBoundary(i-1,j) {
sum += x[i-1][j];
}
if (!isBoundary(i,j+1) {
sum += x[i][j+1];
}
if (!isBoundary(i,j-1) {
sum += x[i-1][j];
}
x[i][j] = sum / 4;
}
}
}
Unfortunately the smoke is absorbed and disappears in contact with boundary surface.
My math background is not sufficient to understand every part of the calculation, so I'll be very grateful if someone points me the right direction.
Here is some code to explain further.
insideBound is array (1 - boundary, 0 - empty, the fluid can pass trough)
#define FOR_EACH_CELL for ( i=1 ; i<=N ; i++ ) { for ( j=1 ; j<=N ; j++ ) {
void set_bnd ( int N, int b, float * x, int * insideBound )
{
int i, j;
float sum;
int count;
for ( i=1 ; i<=N ; i++ ) {
x[IX(0 ,i)] = b==1 ? -x[IX(1,i)] : x[IX(1,i)];
x[IX(N+1,i)] = b==1 ? -x[IX(N,i)] : x[IX(N,i)];
x[IX(i,0 )] = b==2 ? -x[IX(i,1)] : x[IX(i,1)];
x[IX(i,N+1)] = b==2 ? -x[IX(i,N)] : x[IX(i,N)];
}
x[IX(0 ,0 )] = 0.5f*(x[IX(1,0 )]+x[IX(0 ,1)]);
x[IX(0 ,N+1)] = 0.5f*(x[IX(1,N+1)]+x[IX(0 ,N)]);
x[IX(N+1,0 )] = 0.5f*(x[IX(N,0 )]+x[IX(N+1,1)]);
x[IX(N+1,N+1)] = 0.5f*(x[IX(N,N+1)]+x[IX(N+1,N)]);
if (!b) return;
FOR_EACH_CELL
sum = 0.0f;
count = 0;
if (insideBound[IX(i,j)] == 1)
{
if (insideBound[IX(i-1,j)] != 1)
{
count++;
sum = sum + x[IX(i-1,j)];
}
if (insideBound[IX(i+1,j)] != 1)
{
count++;
sum = sum + x[IX(i+1,j)];
}
if (insideBound[IX(i,j-1)] != 1)
{
count++;
sum = sum + x[IX(i, j-1)];
}
if (insideBound[IX(i,j+1)] != 1)
{
count++;
sum = sum + x[IX(i, j+1)];
}
if (count > 0)
{
x[IX(i,j)] = -sum / count;
} else {
x[IX(i,j)] = 0;
}
}
END_FOR
}
Per book (working):
In the first loop are set top, right, bottom and left boundary cells.
Since for them there is only one adjacent cell that is not bound the cell get its value. (I don't know why its opposite for U and the same value for V)
After the first loop, the corner boundary values are set. Here they get average values from their adjacent cells (i guess since there is no adjacent cell that is not boundary they use boundary cells).
Mine, not working properly:
if (!b) return - ignores calculations for density and updates only velocity.
The loop calculates the values for all boundary cells (again, average values from the adjacent cells that are not boundaries themselves).
I get almost realistic result from this methods, but there is big loses in the density and some bugs with too big boundaries where the fluid disappears completely.
I've managed to find a solution, here it is for potential people with the same problem
void set_bnd ( int N, int b, float * x, int * insideBound )
{
int i, j;
float sum, tmp;
int count;
for ( i=1 ; i<=N ; i++ ) {
x[IX(0 ,i)] = b==1 ? -x[IX(1,i)] : x[IX(1,i)];
x[IX(N+1,i)] = b==1 ? -x[IX(N,i)] : x[IX(N,i)];
x[IX(i,0 )] = b==2 ? -x[IX(i,1)] : x[IX(i,1)];
x[IX(i,N+1)] = b==2 ? -x[IX(i,N)] : x[IX(i,N)];
}
x[IX(0 ,0 )] = 0.5f*(x[IX(1,0 )]+x[IX(0 ,1)]);
x[IX(0 ,N+1)] = 0.5f*(x[IX(1,N+1)]+x[IX(0 ,N)]);
x[IX(N+1,0 )] = 0.5f*(x[IX(N,0 )]+x[IX(N+1,1)]);
x[IX(N+1,N+1)] = 0.5f*(x[IX(N,N+1)]+x[IX(N+1,N)]);
if (!b) return;
for ( i=1 ; i<=N ; i++ ) {
for ( j=1 ; j<=N ; j++ ) {
sum = 0.0f;
count = 0;
if (insideBound[IX(i,j)] == 1)
{
if (insideBound[IX(i-1,j)] != 1)
{
count++;
if (b == 2)
tmp = -x[IX(i-1,j)];
else
tmp = x[IX(i-1,j)];
sum = sum + tmp;
}
if (insideBound[IX(i+1,j)] != 1)
{
count++;
if (b == 2)
tmp = -x[IX(i+1,j)];
else
tmp = x[IX(i+1,j)];
sum = sum + tmp;
}
if (insideBound[IX(i,j-1)] != 1)
{
count++;
if (b == 1)
tmp = - x[IX(i, j-1)];
else
tmp = x[IX(i, j-1)];
sum = sum + tmp;
}
if (insideBound[IX(i,j+1)] != 1)
{
count++;
if (b == 1)
tmp = -x[IX(i, j+1)];
else
tmp = x[IX(i, j+1)];
sum = sum + tmp;
}
if (count > 0)
{
x[IX(i,j)] = -sum / count;
} else {
x[IX(i,j)] = 0;
}
}
}
}
}
insideBound is boolean array (0,1) which indicates the cells that are boundaries. Works with one or more boundary areas, but they should be at least 3 cells wide and high.

Resources