【问题标题】:Find unique numbers in array在数组中查找唯一数字
【发布时间】:2013-02-06 23:28:53
【问题描述】:

好吧,我必须找出一个数组中有多少个不同的数字。

例如,如果数组是:1 9 4 5 8 3 1 3 5

输出应该是 6,因为 1,9,4,5,8,3 是唯一的,而 1,3,5 是重复的(不是唯一的)。

所以,到目前为止,这是我的代码.....认为无法正常工作。

#include <iostream>

using namespace std;

int main() {
    int r = 0, a[50], n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int j = 0; j < n; j++) {
        for (int k = 0; k < j; k++) {
            if (a[k] != a[j]) r++;
        }
    }
    cout << r << endl;
    return 0;
}

【问题讨论】:

  • 对数组进行排序,那么就很简单了。试着自己弄清楚它的复杂性与您的解决方案的复杂性相比如何。
  • 这对我来说似乎是家庭作业......但是是的,您可以对数组进行排序,也可以使用哈希表。
  • 似乎 SO 是完成最后一分钟作业的好地方。格式化问题,将其发布在 SO 上,???,得到答案!
  • @thang:似乎不是——考虑到这个问题的几乎所有答案都有不正确的算法或使用标准库来完成这项工作——这显然不是这个作业的内容......
  • 这是我找到的最好的逻辑。stackoverflow.com/questions/28320454/…

标签: c++ arrays for-loop numbers


【解决方案1】:

让我加入派对;)

你也可以使用哈希表:

#include <unordered_set>
#include <iostream>

int main() {

    int a[] = { 1, 9, 4, 5, 8, 3, 1, 3, 5 };
    const size_t len = sizeof(a) / sizeof(a[0]);

    std::unordered_set<int> s(a, a + len);

    std::cout << s.size() << std::endl;
    return EXIT_SUCCESS;

}

这并不重要,但这对于大型数组可能具有最佳性能。


如果最小元素和最大元素之间的差异相当小,那么您可以做得更快:

  • 创建一个跨越最小和最大元素范围的vector&lt;bool&gt;(如果您在编译时知道数组元素,我建议改为std::bitset,但是您可以只计算编译中的所有内容-无论如何使用模板元编程的时间)。
  • 对于输入数组的每个元素,在vector&lt;bool&gt;中设置相应的标志。
  • 完成后,只需计算vector&lt;bool&gt; 中trues 的数量。

【讨论】:

  • 感谢您的帮助,虽然这不是很基础,但感谢您的帮助。
【解决方案2】:

std::set 已经只包含唯一元素。

#include <set>

int main()
{
    int a[] = { 1, 9, 4, 5, 8, 3, 1, 3, 5 };

    std::set<int> sa(a, a + 9);
    std::cout << sa.size() << std::endl;
}

【讨论】:

  • 是“9”的条目数还是最大值?
  • @Ben 不,这是数组的大小
【解决方案3】:

这个怎么样?

#include <list>

int main()
{
    int a[] = {1, 9, 4, 5, 8, 3, 1, 3, 5};

    std::list<int> la(a, a+9);
    la.sort();
    la.unique();
    std::cout << la.size() << std::endl;

    return 0;
}

【讨论】:

  • 你也可以使用std::set :P
  • 好吧,我的问题是我还没有研究过向量,我必须只使用循环/数组来做这个。有什么帮助吗?
  • 需要先排序,再统计相邻元素。
  • la.unique() 方法的正确性是否取决于首先运行 sort()?
【解决方案4】:

既然您已经声明您不能使用标准库并且必须使用循环,那么让我们试试这个解决方案。

#include <iostream>

using namespace std; // you're a bad, bad boy!

int main() 
{
    int r = 0, a[50], n;

    cout << "How many numbers will you input? ";
    cin >> n;

    if(n <= 0)
    {
        cout << "What? Put me in Coach. I'm ready! I can do this!" << endl;
        return -1;
    }

    if(n > 50)
    {
        cout << "So many numbers! I... can't do this Coach!" << endl;
        return -1;
    }   

    cout << "OK... Enter your numbers now." << endl;

    for (int i = 0; i < n; i++)
        cin >> a[i];


    cout << "Let's see... ";

    // We could sort the list but that's a bit too much. We will choose the
    // naive approach which is O(n^2), but that's OK. We're still learning!

    for (int i = 0; i != n; i++) 
    { // Go through the list once.      
        for (int j = 0; j != i; j++)
        { // And check if this number has already appeared in the list:
            if((i != j) && (a[j] == a[i]))
            { // A duplicate number!        
                r++; 
                break;
            }
        }
    }

    cout << "I count " << n - r << " unique numbers!" << endl;

    return 0;
}

我敦促您不要将此代码作为您的作业提交 - 至少不要在不理解的情况下提交。你只会伤害自己,而且你的老师很可能会知道你并没有写它:我以前做过评分员,当某人的代码质量神奇地提高时,这是相当明显的。

【讨论】:

  • 这解决了一个不同的问题:它只计算出现一次的值,而不是所有不同的值。
  • @joergb 你错了。再次阅读代码 - 告诉我n - r 的计算结果。真的不难弄清楚;如果需要,您甚至可以运行代码。
  • 我再次阅读了代码,现在我什至针对 OP 的测试输入运行它:对于指定的问题,使用该输入它返回 3,而不是 6。正如我所说:您的代码计算只出现一次的数字。 r 计算所有重复出现的数字实例——甚至是第一个。 OP 想要计数 all 不同的数字。使用 std::set 或 std::list 的解决方案是正确的。
  • 哇哦,你是对的。我完全误解了这个问题。将调整代码。
【解决方案5】:

我认为增加r值的位置不正确

#include <iostream>
using namespace std;

int main()
{
    int r=0,a[50],n;
    cin >>n;
    for(int i=0;i<n;i++)
    {
        cin >> a[i];
    }
    for (int j=0;j<n;j++)
    {   
        bool flag = true;  
        for(int k=;k<j;k++)
        {
            if(a[k]!=a[j])
            {
               flag = false;
               break;
            }
       }
       if (true == flag) 
       {
           r++;
       }
    }
    cout << r << endl;
    return 0;
}

不过,我的建议是使用更复杂的算法(这个算法有 O(N^2))。

【讨论】:

  • O(n^2) 复杂度和 if (true == flag)?后者特别可怕。
  • 不,我的意思是,你不知道为什么它没有按预期工作吗?
  • 不是真的,尤其是布尔值让我更加困惑。
  • 问题不在于布尔值。它处于主要状态。如果您将 flag 重命名为能够说明其含义的名称,您可能会发现它。
【解决方案6】:

这应该可行,但它可能不是最佳解决方案。

#include <iostream>

using namespace std;

int main()
{
int a[50],n;        
int uniqueNumbers; // this will be the total numbers entered and we will -- it
cin >>n;    
uniqueNumbers = n;  
for(int i=0;i<n;i++)
{
    cin >> a[i];
}   
for (int j=0;j<n;j++)
{   
    for(int k=0;k<n;k++)
    {
        /* 
        the and clause below is what I think you were missing.
        you were probably getting false positatives when j == k because a[1] will always == a[1] ;-)
        */
        if((a[k] == a[j]) && (k!=j)) 
        { uniqueNumebers--; }
    }       
}
cout << uniqueNumbers << endl;
return 0;
}

【讨论】:

    【解决方案7】:

    我们可以在这个程序中使用 C++ STL 向量。

      int main() 
      {
        int a[] = {1, 9, 4, 5, 8, 3, 1, 3, 5};
        vector<int>v(a, a+9);
    
        sort(v.begin(), v.end()); 
        v.erase(unique(v.begin(), v.end()), v.end()); 
    
        cout<<v.size()<<endl;
    
        return 0;
      }
    

    【讨论】:

      【解决方案8】:

      请干运行您的代码 在外部 for 循环中查看每个元素在内部循环中的计数不止一个。让我们说循环包含 1,2,3,4.1 ..... 元素在第二次迭代中干运行它,第三次迭代 1 是计数是因为 1 是 1!=2 以及 1!=3

      现在是解决时间!!

      #include<iostream>
      #include<vector>
      #include<algorithm>
      #define ll long long
      using namespace std;
      ll arr[1000007]={0};
      int main()
      {
        ios_base::sync_with_stdio(false);//used for fast i/o
          ll n;cin>>n;
            for(ll i=1;i<=n;i++)
              cin>>arr[i];
      
              sort(arr,arr+n);
      
             ll cnt=0;
                      for(ll i=1;i<=n-1;i++)
                        {
                         if(arr[i+1]-arr[i]==0)
                           cnt++;
                        }
                       cout<<n-cnt<<endl;
      
      
        cin.tie(NULL);
        return 0;
      }
      

      【讨论】:

        【解决方案9】:

        #include 使用命名空间标准;

        int find_unique(int arr[], int size){

        int ans = 0;
        for(int i = 0; i < size; i++){
            ans = ans^arr[i];  // this is bitwise operator .its call XOR  it's return only unique value..  
        
        }
        
        return ans;
        

        }

        void print_array(int arr[], int size){

        for(int i = 0; i < size; i++){
            cout << arr[i] << " ";
        }
        cout << endl;
        

        }

        int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); // 用于快速输入和输出....

        int arr[5] = {1, 3, 5, 3, 1};
        
        cout <<"Orginal array: " << endl;
        print_array(arr, 5);
        int result = find_unique(arr, 5);
        cout << result << endl;
        
        return 0;
        

        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-08
          • 1970-01-01
          • 1970-01-01
          • 2014-02-09
          • 1970-01-01
          • 2021-11-08
          • 2017-05-07
          相关资源
          最近更新 更多