【问题标题】:How do I check to see if two (or more) elements of an array/vector are the same?如何检查数组/向量的两个(或多个)元素是否相同?
【发布时间】:2015-03-24 06:10:42
【问题描述】:

对于我的一个家庭作业问题,我们必须编写一个函数来创建一个包含 n 个介于 1 和 365 之间的随机数的数组。(完成)。然后,检查这些n 生日是否相同。有比做几个循环或几个逻辑表达式更短的方法吗?

谢谢!

代码到目前为止,还没有完成!!

 function = [prob] bdayprob(N,n)
 N = input('Please enter the number of experiments performed: N = ');
 n = input('Please enter the sample size: n = ');
 count = 0;

 for(i=1:n)
   x(i) = randi(365);
   if(x(i)== x)
     count = count + 1
 end

return 

【问题讨论】:

  • 分享您的代码,使用示例输入数据并与他们解释预期的输出?
  • @Divikar 好的,会的
  • 不幸的是,您的功能没有多大意义。 Nn 是您的函数的输入,但您可以通过交互方式(通过 input)向用户请求它们来覆盖这些值。此外,prob 是输出变量,但在代码中没有引用。 prob 应该是什么?当您发现生日不是唯一的试用版时,您应该怎么做?

标签: arrays matlab matrix element


【解决方案1】:

如果我正确解释了您的问题,您需要检查生成 n 整数或天数是否会产生 n 唯一 数字。鉴于您目前对 MATLAB 的了解,这很简单:

n = 30; %// Define sample size
N = 10; %// Define number of trials

%// Define logical array where each location tells you whether 
%// birthdays were repeated for a trial
check = false(1, N);

%// For each trial...
for idx = 1 : N
    %// Generate sample size random numbers
    days = randi(365, n, 1);

    %// Check to see if the total number of unique birthdays 
    %// are equal to the sample size
    check(idx) = numel(unique(days)) == n;
end

哇!让我们慢慢看代码好吗?我们首先定义样本量和试验次数。然后我们指定一个logical 数组,其中每个位置告诉您是否为该试验生成了重复的生日。现在,我们从一个循环开始,对于每个试验,我们生成从 1 到 365 的随机数,其大小为 n 或样本大小。然后我们使用unique 并找出从这个随机生成中生成的所有唯一整数。如果所有生日都是唯一的,则生成的唯一生日总数应等于样本大小。如果我们不这样做,那么我们就会重复。例如,如果我们生成[1 1 1 2 2] 的样本,unique 的输出将是[1 2],并且唯一元素的总数是 2。因为这个 等于 5 或样本量,然后我们知道生成的生日不是唯一的。但是,如果我们有 [1 3 4 6 7]unique 将给出相同的输出,并且由于输出长度与样本大小相同,我们知道所有的日子都是唯一的。

因此,我们检查该数字是否等于每次迭代的样本量。如果是,那么我们输出true。如果不是,我们输出false。当我最终运行这段代码时,这就是我得到check 的结果。我将样本大小设置为 30,试验次数设置为 10。

check =

     0     0     1     1     0     0     0     0     1     0

请注意,如果您增加样本量,您获得重复的概率会更高,因为randi 可以被视为带放回抽样。因此,样本量越大,得到重复值的机会就越大。我故意使样本量变小,以便我们可以看到有可能获得独特的日子。但是,如果您将其设置为 100 或 200 之类的值,您很可能会得到 check 全部为 false,因为每次试验很可能会有重复。

【讨论】:

    【解决方案2】:

    这里还有一些避免循环的方法。让

    n = 20; %// define sample size
    x = randi(365,n,1); %// generate n values between 1 and 365
    

    如果x 中有两个相同的值,则以下任何代码sn-ps 返回true(或1),否则返回false(或0):

    • 排序然后检查任意两个连续元素是否相同:

      result = any(diff(sort(x))==0);
      
    • 手动进行所有成对比较;删除自对和重复对;并检查剩余的比较是否为真:

      result = nnz(tril(bsxfun(@eq, x, x.'),-1))>0;
      
    • 计算不同值之间的距离,每对只考虑一次,然后检查是否有任何距离为0

      result = any(pdist(x(:))==0);
      
    • 找出最常见值(模式)的出现次数:

      [~, occurs] = mode(x);
      result = occurs>1;
      

    【讨论】:

    • 非常好的替代品。 +1。我特别喜欢使用mode。真是巧妙。
    • @rayryeng 谢谢!在您非常好的回答和解释之后,只剩下或多或少的异国替代品:-)
    【解决方案3】:

    我不知道我是否应该为您解决问题,但也许一些提示可能会引导您朝着正确的方向前进(除了我不是 matlab 专家,因此一般来说):

    也许不是,但你必须问问自己他们对你的期望是什么。您提出的解决方案要求您在两个嵌套循环中循环遍历数组,这意味着 n*(n-1)/2 次循环(即二次时间复杂度)。

    有多种方法可以提高问题的时间复杂度。最直接的方法是拥有一个 365 元素表,如果已经看到特定数字,您可以在其中跟踪 - 这只需要一个循环(即线性时间复杂度),但也许这也不是他们想要的.但也许这个解决方案有点临时?如果之前已经看到特定数字,我们基本上要寻找的是快速查找 - 存在允许在 O(1) 时间和 O(log n) 时间查找的内存效率更高的结构(如果你知道这些,你有工具库)。

    当然,在某些特殊情况下,您可以使用 pidgeonhole 原理更快地提供答案(请记住,您只要求确定两个或多个数字是否相等)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 2022-12-12
      • 2019-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多