Separate strings and make a group from cell array - string

Cell_in = {'a1','b1','b3','c3','c1','d3'}; % something like this
Cell_out = {'a1','b1','c1';
'b3','c3','d3';...
}
And so on, how can this be done?

Case 1: Consistent sizes
%%// Input (different from question for a better demo)
Cell_in = {'airplane1','bat1','ball3','cat3','coal1','doggie3'};
ids = cellfun(#(x) x(end), Cell_in,'uni',0)
[~,ind] = sort(ids)
Cell_out = reshape(Cell_in(ind),[],numel(unique(ids)))' %%// Output
Output
Cell_out =
'airplane1' 'bat1' 'coal1'
'ball3' 'cat3' 'doggie3'
Case 2: Inconsistent sizes
Cell_in = {'airplane1','bat1','ball3','cat3','coal1','doggie3','cat2','ball2'};
ids = cellfun(#(x) x(end), Cell_in,'uni',0)
unique_ids_num = cellfun(#str2num,unique(ids))
ids_num = cellfun(#str2num,ids)
counts = histc(ids_num,sort(unique_ids_num))
Cell_out = cell(numel(unique_ids_num),max(counts));
for k =1:numel(counts) %%// Maybe accumarray can work here
Cell_out(k,1:counts(k)) = Cell_in(ids_num==unique_ids_num(k));
end
Output
Cell_out =
'airplane1' 'bat1' 'coal1'
'cat2' 'ball2' []
'ball3' 'cat3' 'doggie3'

Using regexp, as suggested by kyamagu, followed by accumarray to do the grouping:
[~,~,ic] = unique(cell2mat(regexp(Cell_in(:), '\d+$', 'match', 'once')));
[ic,inds] = sort(ic); % to ensure stable ordering of output
co = accumarray(ic,inds,[],#(x){Cell_in(x)});
Cell_out = vertcat(co{:});

Related

Swap two characters in the cell array of strings

I have a cell array of string and I want to swap A and B in a percentage of the cell array , like 20%, 30% of the total number of strings in the cell array
For example :
A_in={ 'ABCDE'
'ACD'
'ABCDE'
'ABCD'
'CDE' };
Now, we need to swap A and B in 40% of the sequences in A (2/5 sequences ). There are some sequences which do not contain A and B so we just skip them, and we will swap the sequences which contain AB . The pickup sequences in A are chosen randomly. I appropriate someone can tell me how to do this . The expected output is:
A_out={ 'ABCDE'
'ACD'
'BACDE'
'BACD'
'CDE' }
Get the random precent index with randsample and swap with strrep
% Input
swapStr = 'AB';
swapPerc = 0.4; % 40%
% Get index to swap
hasPair = find(~cellfun('isempty', regexp(A_in, swapStr)));
swapIdx = randsample(hasPair, ceil(numel(hasPair) * swapPerc));
% Swap char pair
A_out = A_in;
A_out(swapIdx) = strrep(A_out(swapIdx), swapStr, fliplr(swapStr));
you can use strfind, like:
A_in={ 'ABCDE';
'ACD';
'ABCDE';
'ABCD';
'CDE' };
ABcells = strfind(A_in,'AB');
idxs = find(~cellfun(#isempty,ABcells));
n = numel(idxs);
perc = 0.6;
k = round(n*perc);
idxs = randsample(idxs,k);
A_out = A_in;
A_out(idxs) = cellfun(#(a,idx) [a(1:idx-1) 'BA' a(idx+2:end)],A_in(idxs),ABcells(idxs),'UniformOutput',false);

Set variable to Memory Address in Python 3.5

How would I convert these lines (originally python-2.7) to Python-3.5:
DELETE = 0x00010000L
READ_CONTROL = 0x00020000L
WRITE_DAC = 0x00040000L
WRITE_OWNER = 0x00080000L
SYNCHRONIZE = 0x00100000L
STANDARD_RIGHTS_REQUIRED = 0x000F0000L
STANDARD_RIGHTS_READ = READ_CONTROL
STANDARD_RIGHTS_WRITE = READ_CONTROL
STANDARD_RIGHTS_EXECUTE = READ_CONTROL
STANDARD_RIGHTS_ALL = 0x001F0000L
SPECIFIC_RIGHTS_ALL = 0x0000FFFFL
These lines just retrun Syntax error on python-3.5
Python 3 no longer has a distinction between a long and regular int.
Just remove the L at the end of the hex literals and you are good to go:
>>> STANDARD_RIGHTS_ALL = 0x001F0000
>>> STANDARD_RIGHTS_ALL
2031616
>>> hex(STANDARD_RIGHTS_ALL )
'0x1f0000'

Lua String concatenation

I am working on Lua and I have this kind of code
MapMessage(Process["ks.MSH"][1], MsgIn, mg)
MapEvent(Process["ks.EVN"][1], MsgIn, mg)
MapPatient(Process["ks.PID"][1], MsgIn, mg)
MapVisit(Process["ks.PV1"][1],MsgIn,mg)
In above statements, MapMessage, MapEvent, MapPatient, MapVisit are the functions and ks.MSH, ks.EVN, ks.PID, ks.PV1 are the tables in the database.
Now, I want to automate a part of this process using gmatch function provided in lua and I have this so far
for u in string.gmatch(S, "([^,%s]+)"), 1 do
l[k] = u
_G["Map"..l[k]](Process["ks[l[k]]"][1], R[1])
k=k+1
end
but the concatenation part in the third line of above code is not really making it ks.MSH, ks.PID, ks.PV1 e.t.c, so please suggest what needs to be there in place of (Process["ks[l[k]]"][1]to get s.MSH, ks.PID, ks.PV1 e.t.c
Since your string contains "MSH, PID, PV1, EVN", you'd have to use a hash-table or a lookup table. The program would be something like this:
S = "MSH, PID, PV1, EVN"
tLookup = {
MSH = "Message",
EVN = "Event",
PID = "Patient",
PV1 = "Visit",
}
for u in S:gmatch "([^,%s]+)" do
sNameOfFunction = tLoopup[u]
_G[ "Map"..sNameOfFunction ] ( Process["ks."..u][1], MsgIn, mg )
k=k+1
end
Or even something like this:
S = "MSH, PID, PV1, EVN"
tLookup = {
MSH = _G.MapMessage,
EVN = _G.MapEvent,
PID = _G.MapPatient,
PV1 = _G.MapVisit,
}
for u in S:gmatch "([^,%s]+)" do
tLoopup[u] ( Process["ks."..u][1], MsgIn, mg )
k = k+1
end
Here is what finally worked, thanks Egor and hjpotter92 :)
ks = {MSH = "ks.MSH", EVN = "ks.EVN", PID = "ks.PID", PV1 = "ks.PV1", PV2 = "ks.PV2"}
S = tostring(R[1].AllSegmentsList)
l = {}
k = 1
for u in string.gmatch(S, "([^,%s]+)") do
l[k] = u
_G["Map"..l[k]](Process[ks[l[k]]][1], MsgIn, mg)
k=k+1
end

Return all subsequences of a String

I'm trying to write pseudo-code and an algorithm in Matlab, to return all the subsequences of a string.
So the string X = {ABCD} will return XSubSequence = {A, B, C, D, AB, AC, AD, BC, BD, CD, ABC, ABD, BCD, ABCD}, order does not matter of course.
clear
x = 'ABC';
XSize = length(x);
count = 1;
i=1;
for i=1:XSize
ZSubSequence{count} = x(i);
count = count + 1;
for j=i+1:XSize
temp = strcat(x(i),x(j));
ZSubSequence{count} = temp;
count = count + 1;
for k=i+2:XSize
if j ~= k
temp = strcat(x(i), x(j), x(k));
ZSubSequence{count} = temp;
count = count + 1;
end
end
end
end
Is there any way to make this more dynamic, so I can add X of any size and it will be able to deal with it?
You might want to consider a completely different approach.
This this is a binary representation of decimal numbers from 1 to 2^length(x)-1. Meaning for your example 1100=12 will be AB and 0011=3 will be CD, 1000 will be A and 1111=2^4-1=15 will be ABCD and so on.
You might want to create this sequence and then translate it into the input output you have.
Example code:
x = 'ABCD';
XSize = length(x);
seq=dec2bin([1:2^XSize-1]);
And now all have left is translate it back to letters
for i=1:1:2^XSize-1
for j=1:1:XSize
if seq(i,j)=='1'
seq(i,j)=x(j);
else
seq(i,j)='_';
end
end
end
Obviously the '_' should be removed and the output formatted the way you want them to be.
This should do it. It only has one loop (no nesting), so it shoud be pretty fast.
x = 'ABCD';
n = length(x);
subseq = x.';
for ii = 2:n
subseq = strvcat(subseq, x(nchoosek(1:n,ii)));
end
subseq_deblanked = deblank(mat2cell(subseq, ones(size(subseq,1),1), n));
The results are:
subseq: char matrix where each row contains a subsequence padded with blank spaces.
subseq_deblanked: cell array of strings with the blank spaces removed, as you specified

match check in matlab

i have strings like these:
s{1,2} = 'string';
s{2,2} = 'string2';
and in workspace structure like this
U.W.string = [2 2.5 3]
I want to check (in loop) s{1,2} or s{2,2} or s{i,2} matches any structure with the same name. If so, assign values from this structure to some variable var(i). How can it be done?
Use isfields to check, if a string is the name of a field in a struct. Then use the syntax struct.(name), where name is a string to access the field. Your code might look something like:
test = struct('hello', 'world', 'count', 42, 'mean', 10);
fields = {'test', 'count';
'hello', 'text';
'more', 'less'};
values = {pi, 'dummy', -1};
for row = 1 : size(fields, 1)
for column = 1 : size(fields, 2)
if isfield(test, fields{row, column})
test.(fields{row, column}) = values{row};
end
end
end
This converts the initial struct
test =
hello: 'world'
count: 42
mean: 10
to this one
test =
hello: 'dummy'
count: 3.1416
mean: 10
A shorter implementation is achieved by removing the inner loop and giving a cell-array to isfields:
for row = 1 : size(fields, 1)
%# Note the parenthesis instead of curly braces in the next statement.
match = isfield(test, fields(row, :));
if any(match)
test.(fields{row, match}) = values{row};
end
end
Use isfield(structName,fieldName). This should do the trick:
strings{1,1} = 'foo';
strings{1,2} = 'bar';
strings{1, 3} = 'foobar';
U.W.foo = 1;
U.W.foobar = 5;
for idx = 1:length(strings)
if(isfield(U.W,strings{1,idx}))
expression = sprintf('outvar(idx) = U.W.%s',strings{1,idx});
eval(expression);
end
end

Resources