问:
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;
}
}
}
答案 0 :(得分:5)
这不是最有效的,但它有一些值:
...
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;
}