Mex compiled function, used to compute set intersection and difference, keeps crashing - c

[This question has been solved]
(This question has already been posted on the Matlab forum, here : http://www.mathworks.com/matlabcentral/answers/223415-mex-compiled-function-used-to-compute-set-intersection-and-difference-keeps-crashing)
Hi Guys,
I'm trying to build a very simple function that is supposed to computed the "intersection" and "difference" of two sets, returning the corresponding indices.
For instance, if we have
in1 = [1 2 4 5 9]
in2 = [2 3 4 8]
it should return
common1 = [2 3] % since all(in1(common1) == in2(common2))
common2 = [1 3]
only1 = [1 4 5] % the remaining indices, not in common1
only2 = [2 4] % the ones not in common2
I could do that using intersect and setdiff, but because I have small sets and since I call this function thousands of times, I think doing it using a compiled C-mex file should be the fastest way. It really is the bottleneck of my algorithm at the moment.
I coded this function
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
mexPrintf("Starting ...\n") ;
/* Check nbr of inputs and outputs */
if (nrhs != 2 || nlhs != 4)
mexErrMsgTxt("intersectFast needs 4 outputs and 2 inputs") ;
const mxArray* pin1 = prhs[0] ;
const mxArray* pin2 = prhs[1] ;
/* Inputs should be column vectors */
if (mxGetN(pin1) != 1 || mxGetN(pin2) != 1)
mexErrMsgTxt("inputs arguments should be column vectors") ;
mwSize dims1 = mxGetM(pin1) ;
mwSize dims2 = mxGetM(pin2) ;
double* in1 = mxGetPr(pin1) ;
double* in2 = mxGetPr(pin2) ;
mexPrintf("Checks passed\n") ;
mwIndex* idCommon1 = mxCalloc(dims1, sizeof(mwIndex)) ; // At most dims1 elements
mwIndex* idCommon2 = mxCalloc(dims2, sizeof(mwIndex)) ; /* AT MOST dims2 and NOT dims1 ... this was the error. Damn I feel so stupid right now. */
mwIndex* idOnly1 = mxCalloc(dims1, sizeof(mwIndex)) ; /* Same error here */
mwIndex* idOnly2 = mxCalloc(dims2, sizeof(mwIndex)) ;
mwSize sizeCommon1, sizeCommon2, sizeOnly1, sizeOnly2 ;
mwIndex i, j ;
mwIndex k, l ;
int match ;
/* Intersect fast */
/* in1 */
k = 0 ; l = 0 ;
for(i = 0 ; i < dims1 ; i++) {
match = 0 ;
for(j = 0 ; j < dims2 ; j++) {
if (in1[i] == in2[j]) {
idCommon1[k++] = (i+1) ; /* Matlab <-> C convention */
match = 1 ;
break ;
}
}
if (! match) {
idOnly1[l++] = (i+1) ;
}
}
sizeCommon1 = k ;
sizeOnly1 = l ;
/* in2 */
k = 0 ; l = 0 ;
for(i = 0 ; i < dims2 ; i++) {
match = 0 ;
for(j = 0 ; j < dims1 ; j++) {
if (in2[i] == in1[j]) {
idCommon2[k++] = (i+1) ;
match = 1 ;
break ;
}
}
if (! match)
idOnly2[l++] = (i+1) ;
}
sizeCommon2 = k ;
sizeOnly2 = l ;
/* Return results */
mexPrintf("Sizes = %d, %d, %d, %d\n", sizeCommon1, sizeCommon2, sizeOnly1, sizeOnly2) ;
plhs[0] = mxCreateNumericMatrix(sizeCommon1, 1, mxUINT32_CLASS, mxREAL);
plhs[1] = mxCreateNumericMatrix(sizeCommon2, 1, mxUINT32_CLASS, mxREAL);
plhs[2] = mxCreateNumericMatrix(sizeOnly1, 1, mxUINT32_CLASS, mxREAL);
plhs[3] = mxCreateNumericMatrix(sizeOnly2, 1, mxUINT32_CLASS, mxREAL);
if (plhs[0] == NULL || plhs[1] == NULL || plhs[2] == NULL || plhs[3] == NULL)
mexErrMsgTxt("Could not create mxArray.\n");
mxSetData(plhs[0], idCommon1);
mxSetData(plhs[1], idCommon2);
mxSetData(plhs[2], idOnly1);
mxSetData(plhs[3], idOnly2);
mexPrintf("Done.\n") ;
}
When I test it, it often works, but it always eventually crashes ... For instance, using
% Test intersect fast
clc ; close all ; clear all ;
while true
clc ;
id1 = unique(randi(10, 8, 1)) ;
id2 = unique(randi(12, 6, 1)) ;
[idCommon1, idCommon2, idOnly1, idOnly2] = intersectFast(id1, id2) ;
pause(0.1)
end
it always crashes at some point, after the mex function is done. What I mean is that I get an error like "Matlab has encountered an internal problem and needs to close". So I guess there is some problem with either the mxCreateNumericMatrix or the mxSetData, but I can't figure out what is the problem exactly. I tried changing the index types (uint32, uint64, int, ...) but it did not really change anything.
I am using R2015a on OSX 10.10.3 and the compiled is the default one (Clang).
Thanks a lot for your help !
=================
EDIT : let me be more specific about how it crashes.
Sometimes, MATLAB just start to freeze (and I get the rotating colored mouse pointer ...), and eventually crashes. I need to force MATLAB to quit in this case.
Some other times, I get an error message from MATLAB, saying it encountered an internal error and needs to quit. In this case I can find a Matlab crash file. I uploaded one crash report here : http://pastebin.com/ry7MN7yw

It would be better if you can supply the error message from OS X, which can be obtained by clicking the Crashed notification on the upper-right corner of the screen. For questions involving some low-level (compared to Matlab itself) stuffs like C, the crash report from the Operating System is often useful, since you can see what crashed the program. You can paste it in full to a pastebin or whatever.
If you really find that it crashed inside your code, add the -g flag to clang so you can get some line number in the crash report.
Sorry for not writing this as a comment — I don't have 50 rep yet.

Related

Rotate a matrix by one element: is there an easier/simpler implementation?

I was written this code to rotate the matrix elements one by one.
I wanted to do this on my own but I am stuck in this position someone please find what is the problem in my code and suggest me there is any easy implementation other than this.
#include<iostream>
using namespace std;
void rotate(int a[][10],int r,int c)
{
int b[10][10];
// Copying the input matrix 2d array to temp array
for (int x = 0; x < r; x++)
{
for (int y = 0; y < c; y++)
{
b[x][y] = a[x][y];
}
}
//Rotation process
int i = 0;
int j = 0;
int flag = 0;
while (flag == 0)
{
if (i == 0 && j < c-1)
{
b[i][j+1] = a[i][j];
j++;
}
else if (j == c-1 && i < r-1)
{
b[i+1][j] = a[i][j];
i++;
}
else if (i == r-1 && j <= c-1 && j > 0)
{
b[i][j-1]=a[i][j];
j--;
}
else if (j == 0 && i <= r-1)
{
if (i==0 && j==0)
{
//to break the loop
flag = 1;
}
b[i-1][j] = a[i][j];
i--;
}
}
for (int k = 0; k < r; k++)
{
for (int l = 0; l < c; l++)
{
cout<<"\t"<<b[k][l];
}
cout<<endl;
}
}
int main()
{
int a[10][10],row,col;
cout<<"Enter no of rows : ";
cin>>row;
cout<<"Enter no of columns : ";
cin>>col;
// Getting array elements
cout<<"Enter "<<row<<"X"<<col<<" matrix elements : ";
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
cin>>a[i][j];
}
}
rotate(a,row,col);
cout<<endl;
system("pause");
return 0;
}
This code is not working. Someone help me to find what wrong with this code or suggest me another way.
Thank you.
If I were solving this, I might use 4 independent loops and a single variable to hold the value to carry forward (can be read from the original or matrix copy). While perhaps more repetitive than some approaches, it also removes needing to track 'which direction' state or delta movement variables.
In pseudo-code, it might look like this:
carry = m[0][0]
x, y = 1, 0 # start at (1,0) so we end on (0,0)
# go right from (1,0) to (cols-1,0)
while x < cols:
temp = m[x][y] # hold value of this cell
m[x][y] = carry # replace it with the carried-over value
carry = temp # and forward the previous value as the next carry
x += 1 # update position
# reset back to valid index (avoid additional check in loop)
x -= 1
# do same for other directions around
# the movement is thus:
# (1,0) -> (cols-1,0) NW -> NE
# (cols-1,0) -> (cols-1,rows-1) NE -> SE
# (cols-1,rows-1) -> (0,rows-1) SE -> SW
# (0,rows-1) -> (0,0) SW -> NW
A 1xN or Nx1 matrix might need additional consideration depending on expectations.
Another approach is to use delta variables to move. Think of a little turtle that walks straight and turns right when walking into a wall. The terminal condition is once again set as (0,0) which can be checked at the end of the logic - in this case when the turtle attempts to walk North into a wall, we know it was from (0,0) and the path is completed.
This approach feels less repetitive while maintaining simple state transitions.
carry = m[0][0]
x, y = 1, 0 # start at (1,0)
dx, dy = 1, 0 # and facing East
while true:
# could also use prev_x and prev_y instead of a carry
temp = m[x][y]
m[x][y] = carry
carry = temp
# move / walk
x += dx
y += dy
# turn right when running into a wall
# at most one bound can be violated at a time
if x >= cols:
dx, dy = 0, 1 # face South (was facing East)
x = cols - 1
else if y >= rows:
dx, dy = -1, 0 # face West (was facing South)
y = rows - 1
else if x < 0:
dx, dy = 0, -1 # face North (was facing West)
x = 0
else if y < 0:
# at (0,0) walking North - finished!
break

Maximum binary number a binary string will result to if only one operation is allowed i.e. Right-Rotate By K-Bits where K = [0, Length of String]

Suppose you have a binary string S and you are only allowed to do one operation i.e. Right-Rotate by K-bits where K = [0, Length of the string]. Write an algorithm that will print the maximum binary-number you can create by the defined process.
For Example:
S = [00101] then maximum value I can get from the process is 10100 i.e. 20.
S = [011010] then maximum value I can get from the process is 110100 i.e. 52.
S = [1100] then maximum value I can get from the process is 1100 i.e. 12.
The length of the string S has an upper-limit i.e. 5*(10^5).
The idea which I thought of is kind of very naive which is: as we know that when you right-rotate any binary number by 1-bit, you get the same binary number after m rotations where m = number of bits required to represent that number.
So, I right-rotate by 1 until I get to the number with which I started with and during the process, I keep track of the max-value I encountered and in last I print the max-value.
Is there an efficient approach to solve the problem?
UPD1: This the source of the problem One-Zero, it all boils down to the statement I have described above.
UPD2: As the answer can be huge, the program will print the answer modulo 10^9 + 7.
You want to find the largest number expressed in a binary encoded string with wrap around.
Here are steps for a solution:
let len be the length of the string
allocate an array of size 2 * len and duplicate the string to it.
using linear search, find the position pos of the largest substring of length len in this array (lexicographical order can be used for that).
compute res, the converted number modulo 109+7, reading len bits starting at pos.
free the array and return res.
Here is a simple implementation as a function:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long max_bin(const char *S) {
size_t i, pos, len;
char *a;
// long has at least 31 value bits, enough for numbers upto 2 * 1000000007
long res;
if ((len = strlen(S)) == 0)
return 0;
if ((a = malloc(len + len)) == NULL)
return -1;
memcpy(a, S, len);
memcpy(a + len, S, len);
// find the smallest right rotation for the greatest substring
for (pos = i = len; --i > 0;) {
if (memcmp(a + i, a + pos, len) > 0)
pos = i;
}
res = 0;
for (i = 0; i < len; i++) {
res = res + res + a[pos + i] - '0';
if (res >= 1000000007)
res -= 1000000007;
}
free(a);
return res;
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
printf("[%s] -> %ld\n", argv[i], max_bin(argv[i]));
}
return 0;
}
It is feasible to avoid memory allocation if it is a requirement.
It's me again.
I got to thinking a bit more about your problem in the shower this morning, and it occurred to me that you could do a QuickSelect (if you're familiar with that) over an array of the start indexes of the input string and determine the index of the most "valuable" rotate based on that.
What I show here does not concern itself with presenting the result the way you are required to, only with determining what the best offset for rotation is.
This is not a textbook QuickSelect implementation but rather a simplified method that does the same thing while taking into account that it's a string of zeros and ones that we are dealing with.
Main driver logic:
static void Main(string[] args)
{
Console.WriteLine(FindBestIndex("")); // exp -1
Console.WriteLine(FindBestIndex("1")); // exp 0
Console.WriteLine(FindBestIndex("0")); // exp 0
Console.WriteLine(FindBestIndex("110100")); // exp 0
Console.WriteLine(FindBestIndex("100110")); // exp 3
Console.WriteLine(FindBestIndex("01101110")); // exp 4
Console.WriteLine(FindBestIndex("11001110011")); // exp 9
Console.WriteLine(FindBestIndex("1110100111110000011")); // exp 17
}
Set up the index array that we'll be sorting, then call FindHighest to do the actual work:
static int FindBestIndex(string input)
{
if (string.IsNullOrEmpty(input))
return -1;
int[] indexes = new int[input.Length];
for (int i = 0; i < indexes.Length; i++)
{
indexes[i] = i;
}
return FindHighest(input, indexes, 0, input.Length);
}
Partition the index array into two halves depending on whether each index points to a string that starts with zero or one at this offset within the string.
Once that's done, if we have just one element that started with one, we have the best string, else if we have more, partition those based on the next index. If none started with one, proceed with zero in the same way.
static int FindHighest(string s, int[] p, int index, int len)
{
// allocate two new arrays,
// one for the elements of p that have zero at this index, and
// one for the elements of p that have one at this index
int[] zero = new int[len];
int[] one = new int[len];
int count_zero = 0;
int count_one = 0;
// run through p and distribute its elements to 'zero' and 'one'
for (int i = 0; i < len; i++)
{
int ix = p[i]; // index into string
int pos = (ix + index) % s.Length; // wrap for string length
if (s[pos] == '0')
{
zero[count_zero++] = ix;
}
else
{
one[count_one++] = ix;
}
}
// if we have a one in this position, use that, else proceed with zero (below)
if (count_one > 1)
{
// if we have more than one, sort on the next position (index)
return FindHighest(s, one, index + 1, count_one);
} else if (count_one == 1)
{
// we have exactly one entry left in ones, so that's the best one we have overall
return one[0];
}
if (count_zero > 1)
{
// if we have more than one, sort on the next position (index)
return FindHighest(s, zero, index + 1, count_zero);
}
else if (count_zero == 1)
{
// we have exactly one entry left in zeroes, and we didn't have any in ones,
// so this is the best one we have overall
return zero[0];
}
return -1;
}
Note that this can be optimized further by expanding the logic: If the input string has any ones at all, there's no point in adding indexes where the string starts with zero to the index array in FindBestIndex since those will be inferior. Also, if an index does start with a one but the previous index also did, you can omit the current one as well because the previous index will always be better since that string flows into this character.
If you like, you can also refactor to remove the recursion in favor of a loop.
If I were tackling this I would do so as follows.
I think it's all to do with counting alternating runs of '1' and runs of '0', treating a run of '1's followed by a run of '0's as a pair, then bashing a list of those pairs.
Let us start by scanning to the first '1', and setting start position s. Then count each run of '1's c1 and the following run of '0's c0, creating pairs (c1,c0).
The scan then proceeds forwards to the end, wrapping round as required. If we represent runs of one or more '1' and '0' as single digits, and '|' as the start and end of the string, then we have cases:
|10101010|
^ initial start position s -- the string ends neatly with a run of '0's
|1010101|
^ new start position s -- the string starts and ends in a '1', so the first
run of '1's and run of '0's are rotated (left),
to be appended to the last run of '1's
Note that this changes our start position.
|01010101|
^ initial start position s -- the first run of '0's is rotated (left),
to follow the last run of '1's.
|010101010|
^ initial start position s -- the first run of '0's is rotated (left),
to be appended to the last run of '0's.
NB: if the string both starts and ends with a '1', there are, initially, n runs of '0's and n+1 runs of '1's, but the rotation reduces that to n runs of '1's. And similarly, but conversely, if the string both starts and ends with a '0'.
Let us use A as shorthand for the pair (a1,a0). Suppose we have another pair, X -- (x1,x0) -- then can compare the two pairs, thus:
if a1 > x1 or (a1 = x1 and (a0 < x0) => A > X -- A is better start
if a1 = x1 and a0 = x0 => A = X
if a1 < x1 or (a1 = x1 and (a0 > x0) => A < X -- X is better start
The trick is probably to pack each pair into an integer -- say (x1 * N) - x0, where N is at least the maximum allowed length of the string -- for ease of comparison.
During the scan of the string (described above) let us construct a vector of pairs. During that process, collect the largest pair value A, and a list of the positions, s, of each appearance of A. Each s on the list is a potential best start position. (The recorded s needs to be the index in the vector of pairs and the offset in the original string.)
[If the input string is truly vast, then constructing the entire vector of all pairs will eat memory. In which case the vector would need to be handled as a "virtual" vector, and when an item in that vector is required, it would have to be created by reading the respective portion of the actual string.]
Now:
let us simplify groups of two or more contiguous A. Clearly the second and subsequent A's in such a group cannot be the best start, since there is a better one immediately to the left. So, in the scan we need to record only the s for the first A of such groups.
if the string starts with one or more A's and ends with one or more A's, need to "rotate" to collect those as a single group, and record the s only for the leftmost A in that group (in the usual way).
If there is only one s on the list, our work is done. If the string is end-to-end A, that will be spotted here.
Otherwise, we need to consider the pairs which follow each of the s for our (initial) A's -- where when we say 'follow' we include wrapping round from the end to the start of the string (and, equivalently, the list of pairs).
NB: at this point we know that all the (initial) A's on our list are followed by zero or more A's and then at least one x, where x < A.
So, set i = 1, and consider all the pairs at s+i for our list of s. Keep only the s for the instances of the largest pair found. So for i = 1, in this example we are considering pairs x, y and z:
...Ax....Az...Az..Ax...Ay...
And if x is the largest, this pass discards Ay and both Az. If only one s remains -- in the example, y is the largest -- our work is done. Otherwise, repeat for i = i+1.
There is one last (I think) wrinkle. Suppose after finding z to be the largest of the ith pairs, we have:
...A===zA===z...
where the two runs === are the same as each other. By the same logic that told us to ignore second and subsequent A's in runs of same, we can now discard the second A===z. Indeed we can discard third, fourth, etc. contiguous A===z. Happily that deals with the extreme case of (say):
=zA===zA===zA==
where the string is a sequence of A===z !
I dunno, that all seems more complicated than I expected when I set out with my pencil and paper :-(
I imagine someone much cleverer than I can reduce this to some standard greatest prefix-string problem.
I was bored today, so I knocked out some code (and revised it on 10-Apr-2020).
typedef unsigned int uint ; // assume that's uint32_t or similar
enum { max_string_len = 5 * 100000 } ; // 5 * 10^5
typedef uint64_t pair_t ;
static uint
one_zero(const char* str, uint N)
{
enum { debug = false } ;
void* mem ;
size_t nmx ;
uint s1, s0 ; // initial run of '1'/'0's to be rotated
uint s ;
pair_t* pv ; // pair vector
uint* psi ; // pair string index
uint* spv ; // starts vector -- pair indexes
uint pn ; // count of pairs
uint sn ; // count of starts
pair_t bp ; // current best start pair value
uint bpi ; // current best start pair index
uint bsc ; // count of further best starts
char ch ;
if (N > max_string_len)
{
printf("*** N = %u > max_string_len (%u)\n", N, max_string_len) ;
return UINT_MAX ;
} ;
if (N < 1)
{
printf("*** N = 0 !!\n") ;
return UINT_MAX ;
} ;
// Decide on initial start position.
s = s1 = s0 = 0 ;
if (str[0] == '0')
{
// Start at first '1' after initial run of '0's
do
{
s += 1 ;
if (s == N)
return 0 ; // String is all '0's !!
}
while (str[s] == '0') ;
s0 = s ; // rotate initial run of '0's
}
else
{
// First digit is '1', but if last digit is also '1', need to rotate.
if (str[N-1] == '1')
{
// Step past the leading run of '1's and set length s1.
// This run will be appended to the last run of '1's in the string
do
{
s += 1 ;
if (s == N)
return 0 ; // String is all '1's !!
}
while (str[s] == '1') ;
s1 = s ; // rotate initial run of '1's
// Step past the (now) leading run of '0's and set length s0.
// This run will be appended to the last run of '1's in the string
//
// NB: we know there is at least one '0' and at least one '1' before
// the end of the string
do { s += 1 ; } while (str[s] == '0') ;
s0 = s - s1 ;
} ;
} ;
// Scan the string to construct the vector of pairs and the list of potential
// starts.
nmx = (((N / 2) + 64) / 64) * 64 ;
mem = malloc(nmx * (sizeof(pair_t) + sizeof(uint) + sizeof(uint))) ;
pv = (pair_t*)mem ;
spv = (uint*)(pv + nmx) ;
psi = (uint*)(spv + nmx) ;
pn = 0 ;
bp = 0 ; // no pair is 0 !
bpi = 0 ;
bsc = 0 ; // no best yet
do
{
uint x1, x0 ;
pair_t xp ;
psi[pn] = s ;
x1 = x0 = 0 ;
do
{
x1 += 1 ;
s += 1 ;
ch = (s < N) ? str[s] : '\0' ;
}
while (ch == '1') ;
if (ch == '\0')
{
x1 += s1 ;
x0 = s0 ;
}
else
{
do
{
x0 += 1 ;
s += 1 ;
ch = (s < N) ? str[s] : '\0' ;
}
while (str[s] == '0') ;
if (ch == '\0')
x0 += s0 ;
} ;
// Register pair (x1,x0)
reg:
pv[pn] = xp = ((uint64_t)x1 << 32) - x0 ;
if (debug && (N == 264))
printf("si=%u, sn=%u, pn=%u, xp=%lx bp=%lx\n", psi[sn], sn, pn, xp, bp) ;
if (xp > bp)
{
// New best start.
bpi = pn ;
bsc = 0 ;
bp = xp ;
}
else
bsc += (xp == bp) ;
pn += 1 ;
}
while (ch != '\0') ;
// If there are 2 or more best starts, need to find them all, but discard
// second and subsequent contiguous ones.
spv[0] = bpi ;
sn = 1 ;
if (bsc != 0)
{
uint pi ;
bool rp ;
pi = bpi ;
rp = true ;
do
{
pi += 1 ;
if (pv[pi] != bp)
rp = false ;
else
{
bsc -= 1 ;
if (!rp)
{
spv[sn++] = pi ;
rp = true ;
} ;
} ;
}
while (bsc != 0) ;
} ;
// We have: pn pairs in pv[]
// sn start positions in sv[]
for (uint i = 1 ; sn > 1 ; ++i)
{
uint sc ;
uint pi ;
pair_t bp ;
if (debug && (N == 264))
{
printf("i=%u, sn=%u, pv:", i, sn) ;
for (uint s = 0 ; s < sn ; ++s)
printf(" %u", psi[spv[s]]) ;
printf("\n") ;
} ;
pi = spv[0] + i ; // index of first s+i pair
if (pi >= pn) { pi -= pn ; } ;
bp = pv[pi] ; // best value, so far.
sc = 1 ; // new count of best starts
for (uint sj = 1 ; sj < sn ; ++sj)
{
// Consider the ith pair ahead of sj -- compare with best so far.
uint pb, pj ;
pair_t xp ;
pb = spv[sj] ;
pj = pb + i ; // index of next s+i pair
if (pj >= pn) { pj -= pn ; } ;
xp = pv[pj] ;
if (xp == bp)
{
// sj is equal to the best so far
//
// So we keep both, unless we have the 'A==zA==z' case,
// where 'z == xp == sp', the current 'ith' position.
uint pa ;
pa = pi + 1 ;
if (pa == pn) { pa = 0 ; } ; // position after first 'z'
// If this is not an A==zA==z case, keep sj
// Otherwise, drop sj (by not putting it back into the list),
// but update pi so can spot A==zA==zA===z etc. cases.
if (pa != pb)
spv[sc++] = spv[sj] ; // keep sj
else
pi = pj ; // for further repeats
}
else if (xp < bp)
{
// sj is less than best -- do not put it back into the list
}
else
{
// sj is better than best -- discard everything so far, and
// set new best.
sc = 1 ; // back to one start
spv[0] = spv[sj] ; // new best
pi = pj ; // new index of ith pair
bp = xp ; // new best pair
} ;
} ;
sn = sc ;
} ;
s = psi[spv[0]] ;
free(mem) ;
return s ;
}
I have tested this against the brute force method given elsewhere, and as far as I can see this is (now, on 10-Apr-2020) working code.
When I timed this on my machine, for 100,000 random strings of 400,000..500,000 characters (at random) I got:
Brute Force: 281.8 secs CPU
My method: 130.3 secs CPU
and that's excluding the 8.3 secs to construct the random string and run an empty test. (That may sound a lot, but for 100,000 strings of 450,000 characters, on average, that's a touch less than 1 CPU cycle per character.)
So for random strings, my complicated method is a little over twice as fast as brute-force. But it uses ~N*16 bytes of memory, where the brute-force method uses N*2 bytes. Given the effort involved, the result is not hugely gratifying.
However, I also tried two pathological cases, (1) repeated "10" and (2) repeated "10100010" and for just 1000 (not 100000) strings of 400,000..500,000 characters (at random) I got:
Brute Force: (1) 1730.9 (2) 319.0 secs CPU
My method: 0.7 0.7 secs CPU
That O(n^2) will kill you every time !
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int convt(int N,string S)
{
int sum=0;
for(int i=0; i<N; i++)
{
int num=S[i];
sum += pow(2,N-1-i)*(num-48);
}
return sum;
}
string rot(int N, string S)
{
int temp;
temp = S[0];
for( int i=0; i<N;i++)
S[i]=S[i+1];
S[N-1]=temp;
return S;
}
int main() {
int t;
cin>>t;
while(t--)
{
int N,K;
cin>>N;
cin>>K;
char S[N];
for(int i=0; i<N; i++)
cin>>S[i];
string SS= S;
int mx_val=INT_MIN;
for(int i=0;i<N;i++)
{
string S1=rot(N,SS);
SS= S1;
int k_val=convt(N,SS);
if (k_val>mx_val)
mx_val=k_val;
}
int ki=0;
int j=0;
string S2=S;
while(ki!=K)
{
S2=rot(N,S2);
if (convt(N,S2)==mx_val)
ki++;
j++;
}
cout<<j<<endl;
}
}

Fill an array at index n with m times data without bit-fields

I try to send a maximum of 8 bytes of data. The first 4 bytes are always the same and involve defined commands and an address. The last 4 bytes should be variable.
So far I'm using this approach. Unfortunatly I was told to not use any for loops in this case.
// Construct data
local_transmit_buffer[0] = EEPROM_CMD_WREN;
local_transmit_buffer[1] = EEPROM_CMD_WRITE;
local_transmit_buffer[2] = High(MSQ_Buffer.address);
local_transmit_buffer[3] = Low(MSQ_Buffer.address);
uint_fast8_t i = 0;
for(i = 0; i < MSQ_Buffer.byte_lenght || i < 4; i++){ // assign data
local_transmit_buffer[i + 4] = MSQ_Buffer.dataPointer[i];
}
This is some test code I'm trying to solve my problem:
#include <stdio.h>
__UINT_FAST8_TYPE__ local_transmit_buffer[8];
__UINT_FAST8_TYPE__ MSQ_Buffer_data[8];
void print_local(){
for (int i = 0; i < 8; i++)
{
printf("%d ", local_transmit_buffer[i]);
}
printf("\n");
}
void print_msg(){
for (int i = 0; i < 8; i++)
{
printf("%d ", MSQ_Buffer_data[i]);
}
printf("\n");
}
int main(){
// assign all local values to 0
for (int i = 0; i < 8; i++)
{
local_transmit_buffer[i] = 0;
} print_local();
// assign all msg values to 1
for (int i = 0; i < 8; i++)
{
MSQ_Buffer_data[i] = i + 1;
} print_msg();
*(local_transmit_buffer + 3) = (__UINT_FAST32_TYPE__)MSQ_Buffer_data;
printf("\n");
print_local();
return 0;
}
The first loops fills up the local_transmit_buffer with 0's and the MSQ_Buffer with 0,1,2,...
local_transmit_buffer -> 0 0 0 0 0 0 0 0
MSQ_Buffer_data -> 1 2 3 4 5 6 7 8
Now i want to assign the first 4 values of MSQ_Buffer_data to local_transmit_buffer like this:
local_transmit_buffer -> 0 0 0 0 1 2 3 4
Is there another way of solving this problem without using for loops or a bit_field?
Solved:
I used the memcpy function to solve my problem
// uint_fast8_t i = 0;
// for(i = 0; i < MSQ_Buffer.byte_lenght || i < 4; i++){ // assign data
// local_transmit_buffer[i + 4] = MSQ_Buffer.dataPointer[i];
// }
// copy a defined number data from the message to the local buffer to send
memcpy(&local_transmit_buffer[4], &MSQ_Buffer.dataPointer, local_save_data_length);
Either just unroll the loop manually by typing out each line, or simply use memcpy. In this case there's no reason why you need abstraction layers, so I'd write the sanest possible code, which is just manual unrolling (and get rid of icky macros):
uint8_t local_transmit_buffer [8];
...
local_transmit_buffer[0] = EEPROM_CMD_WREN;
local_transmit_buffer[1] = EEPROM_CMD_WRITE;
local_transmit_buffer[2] = (uint8_t) ((MSQ_Buffer.address >> 8) & 0xFFu);
local_transmit_buffer[3] = (uint8_t) (MSQ_Buffer.address & 0xFFu);
local_transmit_buffer[4] = MSQ_Buffer.dataPointer[0];
local_transmit_buffer[5] = MSQ_Buffer.dataPointer[1];
local_transmit_buffer[6] = MSQ_Buffer.dataPointer[2];
local_transmit_buffer[7] = MSQ_Buffer.dataPointer[3];
It is not obvious why you can't use a loop though, this doesn't look like the actual EEPROM programming (where overhead code might cause hiccups), but just preparations for it. Start to question such requirements.
Also note that you should not use __UINT_FAST8_TYPE__ but uint8_t. Never use homebrewed types but always stdint.h. But you should not be using fast types for a RAM buffer used for EEPROM programming, because it cannot be allowed to contain padding, ever. This is a bug.

One of my value in array gives "0"

In my file includes two columns and I'm try to gather data from file. I need to compare two value in one column. For example, if array[5] is higher than array[4], do something. Here my code:
int control(double col2[], double col3[], int subscript){
double a, b, fcontrol ;
int k /* group */ ;
/* some necessary values for JD controlling */
a = col2[subscript] ;
b = col2[subscript-1] ;
/* for JD controlling */
fcontrol = a - b ;
printf("kontrol = %.12f a = %.12f b = %.12f\n", fcontrol, a, b) ;
/* if value of between two data is equal or higher than 10 hour return 1 */
if(fcontrol >= 0.416666666667){
return 1 ;
}
else{
return 0 ;
}
b is always 0. How can I fix it?
My terminal is :
kontrol = 258.426728989849 a = 258.426728989849 b = 0.000000000000
kontrol = 258.447161800788 a = 258.447161800788 b = 0.000000000000
kontrol = 258.467594711488 a = 258.467594711488 b = 0.000000000000
kontrol = 260.245248070103 a = 260.245248070103 b = 0.000000000000
kontrol = 260.265680861012 a = 260.265680861012 b = 0.000000000000
kontrol = 260.286113551461 a = 260.286113551461 b = 0.000000000000
kontrol = 260.306546441912 a = 260.306546441912 b = 0.000000000000
Here my all code :
/* TASK */
#include<stdio.h>
int kontrol(double col2[], double col3[], int subscript) ;
int main(){
int kolon1,
n = 0, /* for array */
j, z, /* for "for" loopr */
flag = 0 ;
int grup = 0 ;
double kolon2, kolon3,
col2[100000], col3[100000] ;
char ignore[100];
FILE *okuPtr ;
FILE *yazPtr ;
char oku_tbl[100] ;
sprintf(oku_tbl, "deneme.tbl") ;
/* error if file isnt opened*/
if ((okuPtr = fopen(oku_tbl, "r")) == NULL)
printf("%s Acilamadi", oku_tbl) ;
/* file is opened */
else{
char yaz_tbl[100] ;
sprintf(yaz_tbl, "deneme_data.tbl") ;
/* errof if file isnt opened */
if((yazPtr = fopen(yaz_tbl, "w")) == NULL)
printf("%s acilamadi\n", yaz_tbl) ;
/* file is opened */
else{
/* first read */
fscanf(okuPtr, "%d%lf%lf", &kolon1, &kolon2, &kolon3) ;
/* until end of file */
while (!feof(okuPtr)){
/* ignore first 3 line */
fgets(ignore, 100, okuPtr) ;
col2[n] = kolon2 ;
col3[n] = kolon3 ;
flag = control(col2, col3, n) ;
n++ ;
/* if flag == 1 */
if (flag == 1){
for (z = 0 ; z <= --n ; z++){
fprintf(yazPtr, "%d\t%.12f\t%.12f\n", grup, col2[z], col3[z]) ;
}
n = 0 ;
grup++ ;
}
/* yeni veri oku */
fscanf(okuPtr, "%d%lf%lf", &kolon1, &kolon2, &kolon3) ;
}
/* diziyi yazdir
for (j = 0 ; j <= n-1 ; j++){
printf("%d\t%-.12f\t%-.12f\n", k, col2[j], col3[j]) ;
} */
}
}
return 0 ;
}
int control(double col2[], double col3[], int subscript){
double a, b,
fcontrol ;
int k /* group */ ;
/* some necessary values for JD controlling */
a = col2[subscript] ;
b = col2[subscript-1] ;
/* for JD controlling */
fcontrol = a - b ;
printf("kontrol = %.12f a = %.12f b = %.12f\n", fcontrol, a, b) ;
/* if value of between two data is equal or higher than 10 hour return 1 */
if(fcontrol >= 0.416666666667){
return 1 ;
}
else{
return 0 ;
}
}
Problem is that when you call control for first time when n=0
flag = control(col2,col3, n);
But notice here b=col2[subscript-1] will actually be b=col2[-1] which is creating problem as array indexing start with 0 thus your program has this behaviour .
while (!feof(okuPtr))
It is always wrong. See here-Why is “while ( !feof (file) )” always wrong?
Instead use this -
while(fgets(ignore, 100, okuPtr))
{
/*Your code*/
}

Fastest and most efficient way to find the maximum no. that can be obtained by performing bitwise and on 2 DISTINCT elements of array

Given an array of non-negative integers, what is the fastest and most efficient way to find the maximum no. that can be obtained by performing bitwise and (i.e, & operator) on 2 DISTINCT elements of the array?
This is my code until now :
max = 0
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
temp = a[i] & a[j];
if(temp > max)
max = temp
}
}
This, of course, is the naive method. I am looking for a more efficient solution.
Maybe something like using a trie(actually a binary tree) to find max XOR of elements of array. The description for the max XOR solution can be found at http://threads-iiith.quora.com/Tutorial-on-Trie-and-example-problems?share=1
I hope I have got the question right. Here's my solution to it:
You have an array of integers, say that they are unsigned integers since we are dealing with bitwise operations. Let's think of them as a string of zeroes and ones in their binary representation and then put them on top of each other.
We now have their corresponding bits aligned vertically. Let's draw vertical lines, starting from the leftmost column. If we ever encounter more than or equal to two 1s in a column, then rule out every row that does not have the 1s. We are to disregard the ruled out ones while drawing our further vertical lines.
You see where this is going at?
This shall go on until we have only and exactly 2 lines left that hasn't been ruled out. If we ever end up with anything else than 2, then it means something went wrong:
Less than 2 means we had less than 2 lines initially
More than 2 means that...
If there are less than what we had initially, then the ones left should all be identical
If there are exactly as many as we had initially, then it can be that all are the same, or every possible pair is bitwise distinct, meaning that every single pair produces 0
Here's the code I've written that follows the logic I've described above:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <memory.h>
#define bit(_x_) (1U << (_x_))
void randomfillarray( unsigned int * arr, size_t size ) {
srand( time( NULL ) );
for ( int i = 0; i < size; i++ )
arr[i] = rand( );
}
int main( ) {
unsigned int arr[10];
size_t size = sizeof arr / sizeof * arr;
randomfillarray( arr, size );
unsigned int * resultantcouple = malloc( sizeof arr );
memcpy( resultantcouple, arr, sizeof arr );
for ( int i = 0; i < size; i++ )
printf( i ? " %u" : "%u", arr[i] );
putchar( '\n' );
int success = 0;
for ( unsigned int thebit = bit( sizeof( int ) * 8 - 1 ); thebit; thebit >>= 1 ) {
int count = 0;
int * indices = NULL;
for ( int i = 0; i < size; i++ ) {
if ( resultantcouple[i] & thebit ) {
indices = realloc( indices, ++count * sizeof * indices );
indices[count - 1] = i;
}
}
if ( count >= 2 ) {
size = count;
for ( int i = 0; i < size; i++ )
resultantcouple[i] = resultantcouple[indices[i]];
resultantcouple = realloc( resultantcouple, size * sizeof * resultantcouple );
}
if ( size == 2 ) {
success = 1;
break;
}
free( indices );
}
if ( success )
printf( "Success! %u and %u are the ones.", resultantcouple[0], resultantcouple[1] );
else
printf( "Failure! Either all pairs are bitwise distinct, or there are less than 2 elements, or something else..." );
putchar( '\n' );
return 0;
}
Here's the same during action: http://ideone.com/hRA8tn
I'm not sure if this is the best, but it should be better than testing all out.
First look at and understand the heapsort algorithm.
Turn the array into a heap which lets you access the two largest elements. This is done in linear time, O (n).
Take the two largest elements, x = largest, y = second largest. If y = 0, the solution is 0. If the highest bit in x and the highest bit in y are the same, the solution is x & y. Otherwise, clear the highest bit in x, fix the heap, and try again. The last step takes O (log n) steps, and if you are using k bit integers, like 32 or 64, it is repeated at most k times.
No extra space needed, and linear time.
Pseudo-code:
If n ≤ 1 there is no solution.
Turn a [0] to a [n-1] into a heap with a [0] as the largest element.
Repeat
Let x = a [0].
Let y = a [1].
If n ≥ 3 and a [2] > a [1] then let y = a [2].
If y = 0 then the solution is 0.
Determine b = the highest bit of x.
If (y & b) != 0 then the solution is x & y.
Replace a [0] with x & (~ b)
Turn a [0] to a [n-1] into a heap again by moving a [0] down.
This assumes that a [i] and a [j] are considered "distinct array elements" if i ≠ j. If you require instead that a [i] ≠ a [j] then things are slightly different. You'd have to remove duplicate entries in your array, but in case the largest elements are for example 31 and 15, you don't want to clear the highest bit in 31 and then remove it as a duplicate! So the code is more difficult.
Let mask = ~0. In the following, when creating a heap compare a [i] & mask, not a [i].
Turn a [0] to a [n-1] into a heap with a [0] as the largest element.
Repeat
If n ≤ 1 then there is no solution.
Let x = a [0].
Let y = a [1].
If n ≥ 3 and a [2] & mask > y & mask then let y = a [2].
If x = y then let n = n - 1, let a [0] = a [n], restore the heap, and continue.
If (y & mask) = 0 then the solution is 0.
Determine b = the highest bit of x & mask.
If (y & b) != 0 then the solution is x & y.
Replace mask with mask & ~b.
Restore the heap and continue.
Worst case is O (n log n), for example if all elements are 1 except one that is 0.
The following worked for me for our_n uints in uint our_a[our_n], without changing the array or copying it or anything else. The essence is that in one pass down the array it identifies the next bit that can be added to the result so far. Each pass only considers values which contain all the bits of the result so far:
uint result ;
uint passes ;
uint msb ;
uint pn ;
at->start_clock = times(&at->start_tms) ;
result = 0 ;
passes = 0 ;
msb = (UINT_MAX >> 1) + 1 ;
pn = our_n ;
do
{
uint seen_once ;
uint seen_again ;
passes += 1 ;
seen_once = 0 ;
seen_again = 0 ;
for (uint i = 0 ; i < pn ; ++i)
{
uint a ;
a = our_a[i] ;
if ((a & result) == result)
{
seen_again |= (a & seen_once) ;
seen_once |= a ;
} ;
} ;
assert((seen_again & result) == result) ;
seen_again ^= result ;
while (msb > seen_again)
msb >>= 1 ;
result |= msb ;
}
while (msb > 1) ;
So, this is O(p * n), where p is the number of passes: 1..32.
If it is OK to destroy the contents of the array, then the inner loop can be changed to:
k = 0 ;
for (uint i = 0 ; i < pn ; ++i)
{
uint a ;
a = our_a[i] ;
if ((a & result) == result)
{
our_a[k++] = a ;
seen_again |= (a & seen_once) ;
seen_once |= a ;
} ;
} ;
pn = k ;
Of course, the first pass is now doing rather more work than it need to, so doing that separately saves a bit more.

Resources