算法题:(1) 有一个集合R = [a, b, c, d, e, f, g, h, i, j, k, l, m, n, ],....请写出求解这样的一个子集的通用算法。

问题:(1) 有一个集合R = [a, b, c, d, e, f, g, h, i, j, k, l, m, n, ],
(2) 由一组R的真子集构成的集合Rn = [R1, R2, R3, R4, R5],其中
R1 = [ a, c, e, g, i, k, l, m]
R2 = [ b, c, d, h, k]
R3 = [ d, f, g, n]
R4 = [ b, f, g, i, j]
R5 = [ b, k, n]
(3) 给定一个目标集 C = [b, d, f, l, n], C为R的子集
[问题]求在Rn中找出个数最少的一个子集,这个子集的所有元素的并集为U,要求U ∩ C = C,且U ∪ C = U,请写出求解这样的一个子集的通用算法。

matlab实现code

%%
%author: qkk
%date: 20190917
%%
R = 'abcdefghijklmn'; % full Set
S = {'acegiklm', 'bcdhk', 'dfgn', 'bfgij', 'bkn'}; % set composed of subset of R
T = 'bdfln'; % target set
% convert data to binary Matrix and binary Vector
CR = zeros(1,length(R)) + 1;
numR = size(S,2);
CS = zeros(numR,length(R));
for i=1:numR
  SItem = S{i};
  for j=1:length(SItem)
     CS(i,strfind(R, SItem(j))) = 1;
  end
end
CT = zeros(1, length(R));
for i=1:length(T)
   CT(strfind(R,T(i))) = 1;
end
% call function
rIndex = SetDist(CR,CS,CT);
% output
disp('required subset:')
rIndex = sort(rIndex);
for i=1:length(rIndex)
   disp(S{rIndex(i)});
end

%%
% input demo:
% U = [1 1 1 1 1 1 1 1 1 1 1 1 1 1];
% S = [1 0 1 0 1 0 1 0 1 0 1 1 1 0;
%      0 1 1 1 0 0 0 1 0 0 1 0 0 0;
%      0 0 0 1 0 1 1 0 0 0 0 0 0 1;
%      0 1 0 0 0 1 1 0 1 1 0 0 0 0;
%      0 1 0 0 0 0 0 0 0 0 1 0 0 1];
% T = [0 1 0 1 0 1 0 0 0 0 0 1 0 1];
function index = SetDist(U, S, T)
% INPUT:
% -U: Full set,all elements equal 1, size: [1,|R|]
% -S: Multiple subset of U,each row represent a subset of U,value 1 denote
% the Subset contains the corresponding element, 0 otherwise, size:[|Rn|, |R|]
% -T: Target set,within value denote same means with S

% OUTPUT:
% -index: Index of required subset 
   
   if nargin ~= 3
      disp('Warning: Improper number of input parameter');
      return;
   end
   index = []; 
   [numR, numElm] = size(S);
   
   % check input
   if length(U) ~= size(S,2) || length(U) ~= length(T) ...
       || ~isempty(find(U ~= 1))
       disp('Warning: Improper input');
       return;
   end
       
   rowCount = zeros(numR,1); %each element denotes the length of intersetion between each row(R) of S and T
   colCount = zeros(1,numElm); % each element denotes the number of subset that contains the element in T
   
   %query if solution exist
   bitQ = sum(S)-T;
   if length(find(bitQ <0)) > 0
      disp('Warning: no solution!');
      return;
   end
   % solve: cycle until each element in T is contained by a subset
   while sum(T) ~= 0 
       satIndex = find(T == 1);
       colCount = sum(S(:,satIndex));
       for i=1:numR
          rowCount(i) = sum(S(i,:) & T);
       end
       sortColCount = sort(colCount);
       firstValIndex = find(colCount == sortColCount(1));
       if (sortColCount(1) == 1)
           adjustCols = satIndex(firstValIndex);
           for i=1:length(adjustCols)
              whichOne = find(S(:,adjustCols(i)) == 1);
              index = [index whichOne];
              % update S and T
              adjustColsOfi = find(S(whichOne,:) == 1);
              %S(:,adjustColsOfi) = 0;
              T(adjustColsOfi) = 0;
           end
       else
           maxRowCount = max(rowCount);
           mRCIndex = find(rowCount == maxRowCount);
           index = [index mRCIndex(1)];
           % update T
           resetIndex = find(S(mRCIndex(1),:)==1);
           T(resetIndex) = 0;
           %for i=1:length(resetIndex)
           %   S(:,resetIndex(i)) = 0;
           %end
       end
   end
end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MasterQKK 被注册

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值