Say I have an array B:
B = [1];
I want to use a loop to create a layer of zeros around this array, creating a 2D array with the original 1 in the centre.
How can I do this?
If you have an array and want to create a layer of zeros around it you can use blkdiag:
A = zeros(padsize);
result = blkdiag(A,B,A);
If B is just a scalar and you want create a layer of padvals around it you can use repmat and indexing.
result = repmat(padavl,2*padsize+1);
result(padsize+1,padsize+1) = B;
Provided you have the image processing toolbox, use padarray:
B=1;
padvalue = 0; % Value to pad
padsize = 1; % Amount of rows/columns to pad
padarray(B,[padsize padsize ],padvalue ,'both')
ans =
0 0 0
0 1 0
0 0 0
If you don't have the image processing toolbox, it's easily done by hand:
[X,Y] = size(B); % Get sizes
padvalue = 0;
padsize = 1; % Amount of rows/columns to pad
A = padvalue*ones(X+2*padsize ,Y+2*padsize ); % Initialise with a size of 2 larger
A(2:end-1,2:end-1) = B % Fill with original B
A =
0 0 0
0 1 0
0 0 0
Using a loop is actually much more difficult in this case, but you could do it:
B = 1;
[X,Y] = size(B); % Get sizes
padvalue = 0;
A = padvalue*ones(X+2*padsize ,Y+2*padsize ); % Initialise with a size of 2 larger
for ii = 1:X
for jj = 1:Y
A(ii+padsize ,jj+padsize ) = B(ii,jj); % Grab correct element
end
end
You could concatenate a few ones arrays around the original matrix, I'll use the same padvalue and padsize syntax as Adriaan's answer for easy comparison:
padvalue = 0; % Value to pad around the outside
padsize = 1; % Depth of padding
B = 1; % Some matrix
[r,c] = size(B);
A = [ padvalue*ones(padsize,c+2*padsize);
[padvalue*ones(r,padsize), B, padvalue*ones(r,padsize)];
padvalue*ones(padsize,c+2*padsize) ];
Related
I've tried implementing Jacobi method for compressed sparse row format. But i couldnt obtain the output correctly. Below is the coding i tried. I'm trying with a 4 by 4 sparse matrix which is a tridiagonal matrix stored in compressed form before implementing Jacobi iterative method. Please help.
clear all;
close all;
clc;
H=4;
a=2;
b=-1;
c=-1;
A = diag(a*ones(1,H)) + diag(b*ones(1,H-1),1) + diag(c*ones(1,H-1),-1);%Matrix A
n = size(A,1); % no of rows
m = size(A,2); % no of columns
V = [];
C = [];
R = [];
counter=1;
R= [counter];
for i=1:n
for j=1:m
if (A(i,j) ~= 0)
V = [V A(i,j)];
C = [C j];
counter=counter+1;
end
R(i+1)=counter;
end
end
b = [9,18,24,3];
x_new = [1 ; 1 ; 1 ; 1];
eps = 1e-5; % 1 x 10^(-10).
error = 1000; % use any large value greater than eps to make sure that the loop can work
counter2=1;
while (error > eps)
x_old = x_new;
for i=1:length(R)-1 %modified
t = 0;
for j=R(i):R(i+1)-1 %modified
if (C(j)~=i) %not equal
t = t + x_old(C(j))*A(i,C(j)); %modified
end
end
x_new(i,1) = (b(i) - t)/A(i,C(j)); % is a row vector
end
error = norm(x_new-x_old);
counter2=counter2+1;
end
x_new % print x
Expected output is
[28.1987 47.3978 48.5979 25.7986]
this is the coding i tried and the expected output is above. Thank you for your time and consideration.
I am trying to get all possible combinations of a char*. This string consits of four values: two numbers and two different letters. For example:
char *text = "01ab";
There should be
so
different combinations for my example string, which seems to be true (done by hand):
Combinations for values: 0, 1, a, b:
0 0 a b 1 1 a b a 0 0 b b 0 0 a
0 0 b a 1 1 b a a 0 1 b b 0 1 a
0 1 a b 1 0 a b a 0 b 0 b 0 a 0
0 1 b a 1 0 b a a 0 b 1 b 0 a 1
0 a 0 b 1 a 1 b a 1 b 0 b 1 0 a
0 a 1 b 1 a 0 b a 1 b 1 b 1 1 a
0 a b 0 1 a b 1 a 1 0 b b 1 a 0
0 a b 1 1 a b 0 a 1 1 b b 1 a 1
0 b 0 a 1 b 1 a a b 0 0 b a 0 0
0 b 1 a 1 b 0 a a b 0 1 b a 0 1
0 b a 0 1 b a 1 a b 1 0 b a 1 0
0 b a 1 1 b a 0 a b 0 0 b a 1 1
My approach would be the same as the one I did by hand:
get all combinations with the first index of text at the start, then all combinations of the second index of text and so on. So something like this:
void printPasswordCombinations()
{
char *all_values = "01ab";
int len = strlen(all_values);
char *tmp_pwd = malloc(sizeof(len) * sizeof(char));
for(int i=0 ; i<len ; i++)
{
tmp_pwd[0] = all_values[i];
/* len-1, since the first index is already set. */
for(int j=0 ; j<len-1 ; j++)
{
}
}
printf("%s\n", tmp_pwd);
free(tmp_pwd);
}
Now I am a bit confused about how to continue after the first index of the combination. There are several examples for all combinations, but my problem seems to be a bit different, since my the numbers in the combination could be the same and only the letters have to be different.
How could I achieve to print all combinations to my console?
I implemented a function which calculates the amount of possible combinations, so just assume this is already done.
It would be nice if the algorithm would work for any amounts of numbers and letters, so for example all combinations of a text of lenght 6 with four different numbers and two different letters could also be calculated.
The language doesn't matter, any advice is appreciated.
Your problem can be solved by backtracking strategy. It will create all
possible combinations.
I know you want to remove duplicate combinations in case the two number are the same, to get rid of them, you can use a hash table to store generated combination, and then, each time you generate a new combination, bring it to the hash table to check if it was generated or not(if not, enter it to the hash table and print it out, ignore printing in vice versa). There for my pseudocode as follow (you can have a better way):
val characters = [/*4 characters*/]
val picked = [false,false,false,false]
val hashtable = empty
function genetate(string aCombin):
if aCombin.size == 4:
if(hashtable.contains(aCombin)):
//do nothing
else:
print(aCombin)
hashtable.add(aCombin)
for i in characters.size:
if(picked[i]==false):
picked[i]=true
aCombin.add(characters[i])
generate(aCombin)
picked[i]=false //backtrack
aCombine.popBack() //remove the last character
I used Javascript because it can run in browser and language doesn't matter. The below method uses recursion. Try it with '0123ab'.
'use strict';
const input = '01ab';
const reLetters = /[^0-9]/g;
const reDigits = /[0-9]/g;
const nLetters = input.replace(reDigits, '').length;
const nDigits = input.replace(reLetters, '').length;
const findComb = cur => {
if (cur.length === input.length)
return console.log(cur);
for (let l of input) {
if (l.match(reDigits)) {
if (cur.replace(reLetters, '').length === nDigits) continue;
} else {
if (cur.match(l) || cur.replace(reDigits, '').length === nLetters) continue;
}
findComb(cur + l);
}
}
findComb('');
Here is a version without "removing letters to count digits". it is about 20% more efficient. I used nodejs and '01234abc' as input to measure.
'use strict';
const input = '01ab';
const reLetters = /[^0-9]/g;
const reDigits = /[0-9]/g;
const maxLetters = input.replace(reDigits, '').length;
const maxDigits = input.replace(reLetters, '').length;
const findComb = (cur = '', nDigits = 0, nLetters = 0) => {
if (cur.length === input.length)
return console.log(cur);
for (let l of input) {
if (l.match(reDigits)) {
if (nDigits < maxDigits)
findComb(cur + l, nDigits + 1, nLetters);
} else {
if (cur.match(l)) continue;
if (nLetters < maxLetters)
findComb(cur + l, nDigits, nLetters + 1);
}
}
}
findComb();
Here it is without recursion. This is slowest of all, but can be improved.
'use strict';
const input = '01ab';
const reLetters = /[^0-9]/g;
const reDigits = /[0-9]/g;
const nLetters = input.replace(reDigits, '').length;
const nDigits = input.replace(reLetters, '').length;
let cur = '', l = undefined;
do {
l = input[input.indexOf(l) + 1];
if (l !== undefined) {
if (l.match(reDigits)) {
if (cur.replace(reLetters, '').length === nDigits) continue;
} else {
if (cur.match(l) ||
cur.replace(reDigits, '').length === nLetters) continue;
}
if (cur.length + 1 === input.length) {
console.log(cur + l);
} else {
cur = cur + l;
l = undefined;
}
} else {
l = cur[cur.length - 1];
cur = cur.slice(0, -1);
}
} while (cur != '' || l != undefined);
A recursive approach would be the easy way here.
Let's consider that you want to generate all strings with m letters, all of them distinct, taken from a letters[m] array, and n numbers, that can be repeated, taken from a numbers[N] array (n can be smaller, of same size of bigger than N, it does not really matter).
You can solve it this way then (pseudo code, C style):
void print_them_all(char *numbers, int nb_numbers_in_result, int n \
char *letters, bool *is_letter_used, int nb_letters_in_result, int m,
char *current_string){
if ((nb_numbers_in_result == n) && (nb_letters_in_result == m)){
// terminal case -> time to print the current string
printf("%s\n", current_string);
} else {
// string not completely built yet
// get the index where the next char will be added
current_index = nb_letters_in_result + nb_numbers_in_result;
if (nb_numbers_in_result < n){ // still possible to add a number
for (int i = 0; i < N; i++){
current_string[current_index] = numbers[i];
print_them_all(numbers, nb_numbers_in_result+1, n, \
letters, is_letter_used, nb_letters_in_result, m, \
current_string);
}
}
if (nb_letters_in_result < m){ // still possible to add a letter
for (int i = 0; i < m; i++) {
if (is_letter_used[i] == false){ // check the letter has not been added yet
// keep track that the letter has been added by 'marking' it
is_letter_used[i] = true;
// add it
current_string[i] = letters[i];
// recursive call
print_them_all(numbers, nb_numbers_in_result, n, \
letters, is_letter_used, nb_letters_in_result+1, m, \
current_string);
// now 'unmark' the letter
is_letter_used[i] = false;
}
}
}
}
}
To solve this kind of problem, the recursive approach is necessary. It works as follows:
if I have a string with k numbers in it already, k<n, then I can add any number to it, and I can continue (now my string will have k+1 numbers in it).
If I have a string with k letters in it already, k<m, then I can add any letter that was not added already (the array of booleans helps to make sure it is the case), and I can continue.
If my string is ready for print, print it.
The first call should be done with the boolean array initialized to false everywhere, and 0 for the values of nb_letters_in_result and nb_numbers_in_result, since you have not added any number or letter in your result string yet.
As for your result string, since you code in C, don't forget to allocate memory for it:
char *current_string = malloc((m+n+1) * sizeof(char));
and to null-terminate it:
current_string[m+n] = '\0';
I also found an interesting solution for my question.
Assume my example string 01ab.
First we want to create all combinations of the numbers 01 and the permutation of ab.
There are plenty examples of how to solves this.
So now we have all combinations of 01 and ab. I will call them producer combinations:
10 ab
01 ba
11
00
Now we want to combine all numbers with all letters but with the rule
The order of the numbers or letters must not be reserved for each combination
So if we combine 10 with ab we get:
10ab
1a0b
a10b
now we move b to the left side until it is about to swap its place with a, which is forbidden because of my rule. We do this for every combination:
10ab produces:
10ab
since b is already next to a.
1a0b produces:
1ab0
so we got one more combination.
a10b produces:
a1b0
ab10
so we got 2 more combinations.
Now we have all possible combinations for 01 and ab:
10ab
1a0b
a10b
1ab0
a1b0
ab10
Since our producer combinations contain 8 elements we have to do this step 8 times with all elements. The resulting combinations will always contain 6 elements like in my example which leads us to 48 elements in total as I calculated in my question.
Let's say an array a=[1,2,3,4,5,6,7,8], and a logical array b=[1,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1], how to get [1,1,1,1,2,3,2,1,1,1,2,3,4,5,6,7,8,8,8], where there is ones the array a continues in opposite direction where its was left at zeros, and for zeros it continues in opposite index direction from the index value it was left at ones.
array a=[1,2,3,4,5,6,7,8]
logical array b=[1,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1]
how to get [1,1,1,1,2,3,2,1,1,1,2,3,4,5,6,7,8,8,8]
i don't know if it's the most elegant way, but it works:
a = [1,2,3,4,5,6,7,8];
len = length(a);
b = [1,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1];
% find when b changes from 0 to 1
bb = [0 diff(b)];
c = b; c(c == 0) = -1;
c(bb == 1) = 0;
% cumsum finds initial indexes
d = cumsum(c);
% truncate indexes if exceeds array
while 1
ix = find(d < 1 | d > len,1,'first');
if isempty(ix)
break;
end
if d(ix) < 1
d(ix:end) = d(ix:end) + 1;
else
d(ix:end) = d(ix:end) - 1;
end
end
res = a(d)
This is the code that I had tried to find the consecutive zero which are in the order of 5 or more.
a=[0,0,0,0,0,0,0,0,9,8,5,6,0,0,0,0,0,0,3,4,6,8,0,0,9,8,4,0,0,7,8,9,5,0,0,0,0,0,8,9,0,5,8,7,0,0,0,0,0];
[x,y]=size(a);
for i=0:y
i+1;
k=1;
l=0;
n=i;
count=0;
while (a==0)
count+1;
break;
n+1;
end
if(count>=5)
v([]);
for l=k:l<n
v(m)=l+1;
m+1;
end
end
count=1;
i=n;
end
for i = o : i<m
i+1;
fprintf('index of continous zero more than 5 or equal=%d',v(i));
end
If you want to find the starting indices of runs of n or more zeros:
v = find(conv(double(a==0),ones(1,n),'valid')==n); %// find n zeros
v = v([true diff(v)>n]); %// remove similar indices, indicating n+1, n+2... zeros
In your example, this gives
v =
1 13 34 45
One-liner strfind approach to find the starting indices of 5 consecutive zeros -
out = strfind(['0' num2str(a==0,'%1d')],'011111')
Output -
out =
1 13 34 45
The above code could be generalised like this -
n = 5 %// number of consecutive matches
match = 0 %// match to be used
out = strfind(['0' num2str(a==match,'%1d')],['0' repmat('1',1,n)]) %// starting indices of n consecutive matches
If you are looking to find all the indices where the n consecutive matches were found, you can add this code -
outb = strfind([num2str(a==match,'%1d'),'0'],[repmat('1',1,n) '0'])+n-1
allind = find(any(bsxfun(#ge,1:numel(a),out') & bsxfun(#le,1:numel(a),outb')))
If you want to find the general case of a "run of n or more values x in vector V", you could do the following:
% your particular case:
n = 5;
x = 0;
V = [0,0,0,0,0,0,0,0,9,8,5,6,0,0,0,0, ...
0,0,3,4,6,8,0,0,9,8,4,0,0,7,8,9, ...
5,0,0,0,0,0,8,9,0,5,8,7,0,0,0,0,0];
b = (V == x); % create boolean array: ones and zeros
d = diff( [0 b 0] ); % turn the start and end of a run into +1 and -1
startRun = find( d==1 );
endRun = find( d==-1 );
runlength = endRun - startRun;
answer = find(runlength > n);
runs = runlength(answer);
disp([answer(:) runs(:)]);
This will display the start of the run, and its length, for all runs > n of value x.
I want to know a algorithm to find out the maximum xor value of three elements of an array.
I have read about the maximum xor for two elements from an array but cannot understand how to apply it on finding the maximum value of XOR taking 3 elements of an array . Can someone point out a hint ?
Required complexity : less than O(N^3) where N is the number of elements in the array.
Example:
A = [1,2,3,4]
All Possible Triplets :-
1^2^3 = 0
1^2^4 = 7
1^3^4 = 6
2^3^4 = 5
Thus, the maximum XOR value is 7.
Edit :
I have thought of a solution having complexity O(N^2 * log(MAX)) and it has solved my purpose :D .
MAX = Maximum Value in the Array
Well, I have found a solution with complexity O(N^2 * log(MAX)) where MAX is the largest value in the array .
Let there be 3 elements X,Y,Z fron the array A.
where X = A[i] , Y = A[j] , Z = A[k] and i != j != k
We want the maximum value of (X^Y^Z) .
Let us assume W = X*Y.
Then we would like to find such a Z which give maximum value for W^Z and Z != X and Z != Y
Now this has been reduced to the problem of finding "Two elements whose XOR is maximum" which can be done for a given W in O(log(MAX)) using a Trie .
Explanation for Trie :
Let us assume W = 10001 here W is in binary .
Now we know 1^0 = 1 , 0^0 = 0 , 1^1 = 0 , so the maximum value we
can get for W^Z is when Z is 01110 because
W^Z will give = 11111.
But it is not necessary to have 15 or Base2(11111) in our array so
we would take the best possible option available.
So we will create a Trie of all the elements of the array
according to their binary representation.
If A = [1,2,7] , then 1 = 001 , 2 = 010 , 7 = 111 in
binary .
Then the Trie will look like :-
Top
/ \
0 1
/ \ \
0 1 1
\ / \
1 0 1
Now to lets assume W = 7 , and we want to find Z such that
W^Z is maximum (when Z = 000 ) then we will start at the Top and look if we have branch leading to 0 since the first bit of 7 is 1
, then we will down through that branch and then again look if we have
branch leading to 0 at 2nd bit , again we find it , then for the last
time we search for branch leading to a 0 at 3rd bit but we do not find
it , so we go down through the other branch which gives us Z =
001. Thus, the maximum W^Z will be 7^1 = 6 . Now , the
complexity of finding Z will be maximum height of the Trie which
will be log(MAX).
Thus , we have N*(N-1)/2 number of W's and for each W we can find the Maximum value of W^Z and if we take the Maximum from all the values of W^Z we will have our answer.
With three nested loop:
int max2=0,max3=0;
for (int i=0;i<arr.size();i++)
for (int j=0;j<arr.size();j++)
for (int k=0;k<arr.size();k++)
{
if (arr[i]^arr[j]>max2) // for 2 elements
max2 = arr[i]^arr[j];
if (arr[i]^arr[j]^arr[k]>max3) // for 3 elements
max3 = arr[i]^arr[j]^arr[k];
}
int max = max2; // for both
if (max3>max2)
max = max3;
following will do the O(N^3), but in an more optimized approach - not testing same combination more than once, not testing element against itself,
and somewhat optimized evaluation (xoring the first two elements once for all possible third elements)
Number of Xor operations performed will be:
n(n-1)(n-2)/6 + n(n-1)/2
Complexity is still n(n-1)(n-2)/6 ===> O(N^3) though.
unsigned int maxXor3(unsigned int* element, int len)
{
unsigned int max = 0;
unsigned int xor2 = 0;
unsigned int xor3 = 0;
int j = k = 0;
for (int i = 0 ; i < len ; i++)
{
for (j = i + 1 ; j < len ; j++)
{
xor2 = element[i] ^ element[j];
for(k = j + 1; k < len; k++)
{
xor3 = xor2 ^ element[k];
if (xor3 > max)
max = xor3;
}
}
}
return max;
}