如何从不同大小的数组中获取不同的值?

时间:2010-09-01 08:25:44

标签: c++

问:

arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9}

values[]={1,2,5,6,7,9}

问:

arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9}

values[]={1,2,5,6,7,9,101,1502}

这是我尝试但不工作的

   for(int i=0;i<(index-1);i++) { 
       if(data[i].age != data[i+1].age) { 
           c=new list; 
           c->value=data[i].age; 
           c->next=NULL; clas++; 
           if(age_head==NULL) { 
                p=c; age_head=c; 
           } 
           for(c=age_head;c!=NULL,c->next!=NULL;p=c,c=c->next) { 
               if(data[i].age!=c->value) 
                   found=false; 
               else 
                   found=true; 
           } 
           if((age_head!=NULL)&& (found=false)) { 
               p->next=c; c->next=NULL; 
           }
       }
   }

8 个答案:

答案 0 :(得分:5)

这不是最有效的,但它有一些值:

  1. 它使用STL对象
  2. 它使用了一个很酷的鲜为人知的模板技巧,可以在编译时了解C类数组的大小
  3. ...

    int a[] = {1,1,1,2,5,5,6,6,6,6,8,7,9} ;
    int b[] = {1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9} ;
    
    // function setting the set values
    template<size_t size>
    void findDistinctValues(std::set<int> & p_values, int (&p_array)[size])
    {
        // Code modified after Jacob's excellent comment
        p_values.clear() ;
        p_values.insert(p_array, p_array + size) ;
    
    }
    
    void foo()
    {
        std::set<int> values ;
    
        findDistinctValues(values, a) ;
        // values now contain {1, 2, 5, 6, 7, 8, 9}
    
        findDistinctValues(values, b) ;
        // values now contain {1, 2, 5, 6, 7, 8, 9, 101, 1502}
    }
    

    另一个版本可以返回该集合,而不是通过引用获取它。那就是:

    int a[] = {1,1,1,2,5,5,6,6,6,6,8,7,9} ;
    int b[] = {1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9} ;
    
    // function returning the set
    template<size_t size>
    std::set<int> findDistinctValues(int (&p_array)[size])
    {
        // Code modified after Jacob's excellent comment
        return std::set<int>(p_array, p_array + size) ;
    }
    
    void foo()
    {
        std::set<int> valuesOne = findDistinctValues(a) ;
        // valuesOne now contain {1, 2, 5, 6, 7, 8, 9}
    
        std::set<int> valuesTwo = findDistinctValues(b) ;
        // valuesTwo now contain {1, 2, 5, 6, 7, 8, 9, 101, 1502}
    }
    

答案 1 :(得分:4)

我在代码中发现的第一件事是

if((age_head!=NULL)&& (found=false)) {

使用赋值(=)而不是相等(==)。表达式应为

if((age_head!=NULL)&& (found==false)) {

然后,在这个循环中

       for(c=age_head;c!=NULL,c->next!=NULL;p=c,c=c->next) { 

您正在寻找列表中的值。但是,在当前形式中,当循环终止时,found将显示列表中的 last 元素是否等于c->value。您需要在循环条件中检查found(并且您需要AND表达式而不是用逗号分隔它们!):

       for(c=age_head, found = false; !found && c!=NULL && c->next!=NULL; ...) { 

逗号运算符的结果是内部最后一个子表达式的结果 - 这绝对不是你想要的。此外,使用逗号计算所有子表达式,如果c == NULL,则会导致取消引用空指针 - 而&&运算符会被懒惰地计算,因此c->next!=NULL仅在c != NULL时进行评估

接下来就是你需要在列表中搜索<​​em>之前将其添加到列表中的值!另请注意,您正在尝试检查两个不同的事物:实际的data元素与下一个元素不同,并且其值尚未添加到列表中。第二个条件更强 - 它将始终有效,而第一个条件仅在输入数据有序时才有效。所以你可以完全省略第一次检查。上述所有结果,加上一些简化和澄清,是

for(int i=0;i<index;i++) { 
   for(list* c=age_head, found=false; !found&&c&&c->next; p=c,c=c->next) { 
       if(data[i].age==c->value) 
           found=true; 
   } 
   if(!found) { 
       list* newc=new list;
       newc->value=data[i].age; 
       newc->next=NULL;
       clas++;
       if(age_head==NULL) {
           p=newc; age_head=newc;
       } else {
           p->next=newc; newc->next=NULL;
       }
   }
}

我仍然不保证你的链表处理逻辑是正确的:-)在目前的形式中,你的代码很难理解,因为不同的逻辑步骤没有分开。通过一些重构,代码可以看起来更清晰,例如。

for(int i=0;i<index;i++) { 
   if(!foundInList(data[i].age)) {
       addToList(data[i].age);
   }
}

当然,最简单和最有效的方法是使用STL容器/算法,如其他答案所示。但我认为在改善你的第一次尝试方面有更多的教育价值: - )

答案 2 :(得分:2)

如果无需对输出进行排序,则可以使用Hashtable。

E.g。像这样的东西:

#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH
#include <boost/unordered_set.hpp>
#include <vector>
using namespace std;
using namespace boost;

int main() {
  int arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9};
  size_t n = sizeof(arr1)/sizeof(int);
  unordered_set<int> h;
  for (size_t i = 0; i < n; ++i)
    h.insert(arr1[i]);
  vector<int> values;
  foreach(int a, h)
    values.push_back(a);
  return 0;
}

然后运行时在O(n)。

另一种方法是对数组进行排序,然后消除相邻的相同元素(仅需要STL)。但后来运行时在O(n log n):

#include <vector>
#include <algorithm>
using namespace std;

int main() {
  int arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9};
  size_t n = sizeof(arr1)/sizeof(int);

  sort(arr1, arr1+n);
  int *end = unique(arr1, arr1+n);

  vector<int> values(arr1, end);

  return 0;
}

答案 3 :(得分:2)

使用STL轻松完成。

int array[] = { 1, 1, 2, 2, 1, 3, 3, 4, 5, 4, 4, 1, 1, 2 };
int nElements = sizeof(array)/sizeof(array[0]);
std::sort(&array[0], &array[nElements]);
int newSize = std::unique(&array[0], &array[nElements]) - &array[0];

答案 4 :(得分:0)

首先你需要对数组进行排序,而不是做这样的事情:

for(int i = 0; i < size -1; i++)
{
     if(array[i]!=array[i+1])
       unique++;

       // store it wherever you want to.
       stored.push(array[i]);
}

答案 5 :(得分:0)

#include <vector>
#include <algorithm>
#include <iostream>

int
main ()
{
  int array[] = { 1, 1, 2, 2, 1, 3, 3, 4, 5, 4, 4, 1, 1, 2 };
  std::vector < int >values;
  values.push_back (array[0]);
  for (int i = 1; i < sizeof (array) / sizeof (int); ++i)
    {
      std::vector < int >::iterator it =
        std::find (values.begin (), values.end (), array[i]);
      if (it == values.end ())
        values.push_back (array[i]);
    }

  std::cout << "Result:" << std::endl;
  for (int i = 0; i < values.size (); i++)
    std::cout << values[i] << std::endl;
}

答案 6 :(得分:0)

这似乎是Removing duplicates in an array while preserving the order in C++的副本 虽然问题的措辞不同,但结果是一样的。

答案 7 :(得分:0)

基于上述想法/代码,我能够完成在C ++数组中查找不同值的工作。感谢每一个在这个帖子上回复的人。

#include <set>
#include <iostream>
using namespace std;
// function setting the set values
template<size_t size>
void findDistinctValues(std::set<int> & p_values,int (&p_array)[size])
{
    // Code modified after Jacob's excellent comment
    p_values.clear() ;
    p_values.insert(p_array, p_array + size) ;

}

void findDistinctValues2( int arr[],int size)
{
  std::set<int> values_1 ;
  std::set<int>::iterator it_1;
  values_1.clear();
  values_1.insert(arr,arr+size);
  for (it_1=values_1.begin(); it_1!=values_1.end(); ++it_1)
    std::cout << ' ' << *it_1<<endl;

}

int main()
{
  int arr[] = {1,6100,4,94,93,-6,2,4,4,5,5,2500,5,4,5,2,3,6,1,15,16,0,0,99,0,0,34,99,6100,2500};
  std::set<int> values ;
  std::set<int>::iterator it;

  int arr_size = sizeof(arr)/sizeof(int); 
  printf("Total no of array variables: %d\n",arr_size);
  printf("Output from findDistinctValues (function 1)\n ");
  findDistinctValues(values, arr) ;
  for (it=values.begin(); it!=values.end(); ++it)
    std::cout << ' ' << *it<<endl;
  std::cout<<endl;    
  std::cout<<values.size()<<endl; //find the size of distict values

  printf("Output from findDistinctValues (function 2) \n "); 
  findDistinctValues2(arr,arr_size);

  getchar();
  return 0;
}