我需要对四个字符执行XOR
操作,其中每个字符都有一个位表示如下:
A = 00
G = 01
C = 10
T = 11
我需要创建一个XOR
两个字符组合在一起的表,它以下列方式为XOR
个字符对组合提供值。
XOR A G C T
A A G C T
G G A T C
C C T A G
T T C G A
要获得输出,您需要将每个字符转换为其位表示XOR
位,然后使用结果并将其转换回正确的字符。例如,通过XOR
C
和G
咨询表格的第三行和第二列:
C = 10
G = 01
C XOR G = 10 XOR 01 = 11 --> T
我最终希望将此规则应用于以5 x 5矩阵加扰字符。 举个例子:
A = 'GATT' 'AACT' 'ACAC' 'TTGA' 'GGCT'
'GCAC' 'TCAT' 'GTTC' 'GCCT' 'TTTA'
'AACG' 'GTTA' 'ACGT' 'CGTC' 'TGGA'
'CTAC' 'AAAA' 'GGGC' 'CCCT' 'TCGT'
'GTGT' 'GCGG' 'GTTT' 'TTGC' 'ATTA'
B = 'ATAC' 'AAAT' 'AGCT' 'AAGC' 'AAGT'
'TAGG' 'AAGT' 'ATGA' 'AAAG' 'AAGA'
'TAGC' 'CAGT' 'AGAT' 'GAAG' 'TCGA'
'GCTA' 'TTAC' 'GCCA' 'CCCC' 'TTTC'
'CCAA' 'AGGA' 'GCAG' 'CAGC' 'TAAA'
我想生成一个矩阵C
,以便A
的每个元素都与XOR
中的相应元素进行B
。
例如,考虑第一行和第一列:
A{1,1} XOR B{1,1} = GATT XOR ATAC = GTTG
如何为整个矩阵执行此操作?
答案 0 :(得分:2)
看起来你又要回来了!
首先,让我们定义函数letterXOR
,它接受两个4个字符的字符串,XOR
两个字符串对应于您拥有的那个表。 Recalling from our previous post,让我们设置一个查找表,其中唯一的两位字符串对应一个字母。我们可以使用collections.Map
类来帮助我们这样做。我们还需要使用collections.Map
类的逆查找表,其中给定一个字母,我们生成一个两位字符串。我们需要这样做,因为你想将每个字母转换成它的两位表示,我们需要反向查找来做到这一点。之后,我们单独XOR
位,然后使用正向查找表返回到我们开始的位置。就这样:
function [out] = letterXOR(A,B)
codebook = containers.Map({'00','11','10','01'},{'A','T','G','C'}); %// Lookup
invCodebook = containers.Map({'A','T','G','C'},{'00','11','10','01'}); %// Inv-lookup
lettersA = arrayfun(@(x) x, A, 'uni', 0); %// Split up each letter into a cell
lettersB = arrayfun(@(x) x, B, 'uni', 0);
valuesA = values(invCodebook, lettersA); %// Obtain the binary bit strings
valuesB = values(invCodebook, lettersB);
%// Convert each into a matrix
valuesAMatrix = cellfun(@(x) double(x) - 48, valuesA, 'uni', 0);
valuesBMatrix = cellfun(@(x) double(x) - 48, valuesB, 'uni', 0);
% XOR the bits now
XORedBits = arrayfun(@(x) bitxor(valuesAMatrix{x}, valuesBMatrix{x}), 1:numel(A), 'uni', 0);
%// Convert each bit pair into a string
XORedString = cellfun(@(x) char(x + 48), XORedBits, 'uni', 0);
%// Access lookup, then concatenate as a string
out = cellfun(@(x) codebook(x), XORedString);
让我们慢慢浏览上面的代码。 letterXOR
的输入应该是由A
,T
,G
和C
组成的字母字符数组。我们首先定义正向和反向查找。然后,我们将输入字符串A
和B
的每个字符拆分为单个字符的单元格数组,因为查找代码簿中的多个键需要它是这样的。然后我们弄清楚每个字符串中每个字符的位数。这些位实际上是字符串,因此我们需要做的是将每个位串转换为数字数组。我们只是将字符串转换为double
并减去48,这是0
的ASCII代码。转换为double
后,您将获得48或49,这就是我们需要减去48的原因。
因此,每对比特被转换为1 x 2
比特数组。然后,我们在1 x 2
和A
之间取每个B
位数组,使用bitxor
到XOR
位。此时的输出仍然是1 x 2
个数组。因此,我们需要将每个数组转换为一串位,然后使用我们的正向查找表来查找这些位的等效字符。在此之后,我们将所有字符连接在一起,以便为输出生成最终字符串。
确保将上述内容保存在名为letterXOR.m
的函数中。一旦我们有了这个,我们现在只需要使用一个cellfun
调用来对你的单元格数组中的每个四元素字符串进行异或,然后输出我们的最终矩阵。我们将使用arrayfun
来执行此操作,arrayfun
的输入将是5 x 5
矩阵,该列是主要定义的列。我们这样做是因为MATLAB可以使用单个值访问2D数组中的元素。此值是矩阵中元素的列主索引。我们定义一个从1到25的向量,然后使用reshape
将其转换为正确的2D形式。我们之所以需要这样做是因为我们希望确保输出矩阵(在您的示例中为C
)以相同的方式构造。就这样:
ind = reshape(1:25, 5, 5); %// Define column major indices
C = arrayfun(@(x) letterXOR(A{x},B{x}), ind, 'uni', 0); % // Get our output matrix
我们的最终输出C
是:
C =
'GTTG' 'AACA' 'ATCG' 'TTAC' 'GGTA'
'CCGT' 'TCGA' 'GACC' 'GCCC' 'TTCA'
'TATT' 'TTCT' 'ATGA' 'TGTT' 'ATAA'
'TGTC' 'TTAC' 'ATTC' 'AAAG' 'AGCG'
'TGGT' 'GTAG' 'AGTC' 'GTAA' 'TTTA'