嘿,这是今天课堂上提出的一个技巧问题,我想知道是否有办法在数组中找到一个唯一的数字,通常的方法是使用两个for循环并获得与之不匹配的唯一数字所有其他我在C ++中使用std :: vectors作为我的数组,并想知道find是否能找到唯一的数字,因为我不知道数组中唯一的数字在哪里。
答案 0 :(得分:2)
假设我们知道向量至少有三个 元素(因为否则,这个问题没有意义), 只是寻找与第一个不同的元素。如果它 恰好是第二个,当然,我们必须检查第三个 看它是第一个还是第二个是独一无二的, 这意味着一些额外的代码,但粗略地说:
std::vector<int>::const_iterator
findUniqueEntry( std::vector<int>::const_iterator begin,
std::vector<int>::const_iterator end )
{
std::vector<int>::const_iterator result
= std::find_if(
next( begin ), end, []( int value) { return value != *begin );
if ( result == next( begin ) && *result == *next( result ) ) {
-- result;
}
return result;
}
(未经测试,但你明白了。)
答案 1 :(得分:1)
正如其他人所说,排序是一种选择。然后,您的唯一值将在任何一方具有不同的值。
这是使用std :: find在O(n ^ 2)时间内解决它的另一个选项(向量的一次迭代,但每次迭代遍历整个向量,减去一个元素。) - 不需要排序。
vector<int> findUniques(vector<int> values)
{
vector<int> uniqueValues;
vector<int>::iterator begin = values.begin();
vector<int>::iterator end = values.end();
vector<int>::iterator current;
for(current = begin ; current != end ; current++)
{
int val = *current;
bool foundBefore = false;
bool foundAfter = false;
if (std::find(begin, current, val) != current)
{
foundBefore = true;
}
else if (std::find(current + 1, end, val) != end)
{
foundAfter = true;
}
if(!foundBefore && !foundAfter)
uniqueValues.push_back(val);
}
return uniqueValues;
}
基本上这里发生的是,我正在运行::在当前元素之前查找向量中的元素,并在当前元素之后运行:: find元素。由于我的当前元素已经存储在'val'中的值(即,它已经在向量中已经存在),如果我在当前值之前或之后找到它,那么它不是唯一值。
无论有多少唯一值,都应该找到向量中不唯一的所有值。
这是运行它的一些测试代码,并看到:
void printUniques(vector<int> uniques)
{
vector<int>::iterator it;
for(it = uniques.begin() ; it < uniques.end() ; it++)
{
cout << "Unique value: " << *it << endl;
}
}
void WaitForKey()
{
system("pause");
}
int main()
{
vector<int> values;
for(int i = 0 ; i < 10 ; i++)
{
values.push_back(i);
}
/*for(int i = 2 ; i < 10 ; i++)
{
values.push_back(i);
}*/
printUniques(findUniques(values));
WaitForKey();
return -13;
}
作为额外奖励:
这是一个使用地图的版本,不使用std :: find,并且在O(nlogn)时间内完成工作 - n为for循环,log(n)为map :: find(),它使用红黑树。
map<int,bool> mapValues(vector<int> values)
{
map<int, bool> uniques;
for(unsigned int i = 0 ; i < values.size() ; i++)
{
uniques[values[i]] = (uniques.find(values[i]) == uniques.end());
}
return uniques;
}
void printUniques(map<int, bool> uniques)
{
cout << endl;
map<int, bool>::iterator it;
for(it = uniques.begin() ; it != uniques.end() ; it++)
{
if(it->second)
cout << "Unique value: " << it->first << endl;
}
}
并作出解释。迭代vector<int>
中的所有元素。如果当前成员不在地图中,请将其值设置为true
。如果地图中 ,请将值设置为false
。之后,值true
的所有值都是唯一的,而false
的所有值都有一个或多个重复值。
答案 2 :(得分:0)
假设您获得了一个数组size>=3
,其中包含一个值A
的实例,而所有其他值都是B
,那么您可以使用一个for循环执行此操作。
int find_odd(int* array, int length) {
// In the first three elements, we are guaranteed to have 2 common ones.
int common=array[0];
if (array[1]!=common && array[2]!=common)
// The second and third elements are the common one, and the one we thought was not.
return common;
// Now search for the oddball.
for (int i=0; i<length; i++)
if (array[i]!=common) return array[i];
}
修改强>
K如果5个数组中的2个以上不同,那该怎么办? - 超级
啊......这是一个不同的问题。所以你有一个大小为n
的数组,它不止一次包含公共元素c
,而所有其他元素只包含一次。目标是找到一组非共同(即唯一)元素吗?
然后你需要看看上面的西尔万的答案。我认为他正在回答一个不同的问题,但它会起作用。最后,您将拥有一个充满每个值计数的哈希映射。循环遍历哈希映射,每次看到值1时,您都会知道键是输入数组中的唯一值。
答案 3 :(得分:0)
此示例使用地图计算出现次数。唯一的号码只能看一次:
#include <iostream>
#include <map>
#include <vector>
int main ()
{
std::map<int,int> mymap;
std::map<int,int>::iterator mit;
std::vector<int> v;
std::vector<int> myunique;
v.push_back(10); v.push_back(10);
v.push_back(20); v.push_back(30);
v.push_back(40); v.push_back(30);
std::vector<int>::iterator vit;
// count occurence of all numbers
for(vit=v.begin();vit!=v.end();++vit)
{
int number = *vit;
mit = mymap.find(number);
if( mit == mymap.end() )
{
// there's no record in map for your number yet
mymap[number]=1; // we have seen it for the first time
} else {
mit->second++; // thiw one will not be unique
}
}
// find the unique ones
for(mit=mymap.begin();mit!=mymap.end();++mit)
{
if( mit->second == 1 ) // this was seen only one time
{
myunique.push_back(mit->first);
}
}
// print out unique numbers
for(vit=myunique.begin();vit!=myunique.end();++vit)
std::cout << *vit << std::endl;
return 0;
}
此示例中的唯一数字是20和40.不需要为此算法排序列表。
答案 4 :(得分:0)
如果你有两个以上的值(其中一个必须是唯一的),你可以通过在阵列中第一次迭代并填充一个具有关键字的地图,在时间和空间上在O(n)中完成值,并且值是键的出现次数。
然后你只需遍历地图就可以找到一个值1.这将是一个唯一的数字。
答案 5 :(得分:0)
你的意思是在一个只出现一次的向量中找到一个数字吗?如果简单的解决方案,嵌套循环。我认为std::find
或std::find_if
在这里非常有用。另一种选择是对矢量进行排序,这样您只需要找到两个不同的连续数字。它看起来有点过分,但它实际上是O(nlogn)而不是O(n ^ 2)作为嵌套循环:
void findUnique(const std::vector<int>& v, std::vector<int> &unique)
{
if(v.size() <= 1)
{
unique = v;
return;
}
unique.clear();
vector<int> w = v;
std::sort(w.begin(), w.end());
if(w[0] != w[1]) unique.push_back(w[0]);
for(size_t i = 1; i < w.size(); ++i)
if(w[i-1] != w[i]) unique.push_back(w[i]);
// unique contains the numbers that are not repeated
}