如何检查数组/向量中的两个(或更多)元素是否相同?

时间:2015-03-24 06:10:42

标签: arrays matlab matrix element

对于我的一个作业问题,我们必须编写一个函数来创建一个包含1到365之间的n个随机数的数组。(完成)。然后,检查这些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 

3 个答案:

答案 0 :(得分:2)

如果我正确解释您的问题,您需要检查生成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.由于此不具有&#39}。 t 等于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,因为每次试用很可能会重复。{/ p>

答案 1 :(得分:1)

以下是一些避免循环的方法。让

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

如果true1(或x)中有两个相同的值,则以下任何代码段都会返回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;
    

答案 2 :(得分:0)

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

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

有许多方法可以改善问题的时间复杂性。最直截了当的是有一个365元素表,你可以跟踪一个特定的数字是否已经被看到 - 这只需要一个循环(即线性时间复杂度),但也许这不是他们&# 39;重新寻找。但也许这个解决方案有点特别?我们基本上寻找的是快速查找,如果之前已经看到一个特定的数字 - 存在更多的内存有效结构,允许在O(1)时间和O(log n)时间内查找(如果你知道这些你有一套工具可供使用。)

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