我遇到了这个: Simplest way to check if two integers have same sign?
如何将其扩展为两个以上的数字(不一定是整数)?比如说,检查4个数字是否具有相同的符号(+ ve或-ve)。
我不想尽可能使用位操作......只是逻辑条件。
感谢。
答案 0 :(得分:6)
我们假设数字被传递到vector<int>
。
遍历数组,检查两个后续数字是否具有相同的符号,如果不是第一个非等号符号则返回false。
答案 1 :(得分:2)
这样的东西?
if ( n1 > 0 && n2 > 0 ... && nN > 0 )
// all positives
else if ( n1 < 0 && n2 < 0 ... && nN < 0 )
// all negatives
else
// mixed signs
由于short-circuit evaluation,它会很快。
答案 2 :(得分:2)
除非我误解了这个问题,否则以下人员应该为数字向量做好工作:
#include <iostream>
#include <vector>
using namespace std;
template <typename T> int Sign( T t ) {
return t < 0 ? -1 : 1;
}
template <typename T> bool SameSign( std::vector <T> & v ) {
if ( v.size() == 0 ) {
throw "invalid size";
}
int sign = Sign( v[0] );
for ( int i = 1; i < v.size(); i++ ) {
if ( Sign( v[i]) != sign ) {
return false;
}
}
return true;
}
int main() {
std::vector <int> v;
v.push_back(1);
v.push_back(1);
v.push_back(-1);
bool same = SameSign( v );
std::cout << (same ? "same" : "not same") <<"\n";
}
答案 3 :(得分:2)
这是一个通用的实现。这将检查容器的元素是否都共享相同的属性。
一个版本将迭代器返回给第一个不匹配的元素,简洁版本只返回true或false。
因为它是通用的,你也可以检查它们是否都是偶数,例如:
// shared_property.hpp
#ifndef SHARED_PROPERTY_HPP
#define SHARED_PROPERTY_HPP
// checks if all elements share a single property
// if one element does not share a property,
// it returns an iterator to that element
template <typename Iter, typename Func>
Iter share_property(Iter first, Iter last, Func func)
{
for(; first != last; ++first)
{
if (!func(*first))
{
// differs
break;
}
}
return first;
}
// only indicates if all elements share a property
template <typename Iter, typename Func>
bool share_property_concise(Iter first, Iter last, Func func)
{
return share_property(first, last, func) == last;
}
#endif
示例程序:
#include "shared_property.hpp"
#include <functional>
#include <iostream>
#include <vector>
typedef std::vector<int> container;
void negative_test(void)
{
container negatives;
negatives.push_back(-1);
negatives.push_back(-2);
negatives.push_back(-3);
if (share_property_concise(negatives.begin(), negatives.end(),
std::bind2nd(std::less<int>(), 0)))
{
std::cout << "All elements are less than 0." << std::endl;
}
else
{
std::cout << "Not all elements are less than 0." << std::endl;
}
}
bool is_even(int i)
{
return i % 2 == 0;
}
void even_test(void)
{
container evens;
evens.push_back(2);
evens.push_back(4);
evens.push_back(10);
if (share_property_concise(evens.begin(), evens.end(),
is_even))
{
std::cout << "All elements are even." << std::endl;
}
else
{
std::cout << "Not all elements are even." << std::endl;
}
}
int main(void)
{
negative_test();
even_test();
}
它也适用于根据属性过滤容器:
#include "shared_property.hpp"
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>
typedef std::vector<int> container;
template <typename Iter, typename OutIter, typename Func>
Func filter_container(Iter first, Iter last, OutIter out, Func func)
{
first = share_property(first, last, func);
while (first != last)
{
*out++ = *first++;
first = share_property(first, last, func);
}
return func;
};
int make_number(void)
{
return std::rand() % 20 - 10;
}
void find_negatives(void)
{
container numbers;
std::generate_n(std::back_inserter(numbers), 20, make_number);
container negatives;
filter_container(numbers.begin(), numbers.end(), std::back_inserter(negatives),
std::bind2nd(std::greater<int>(), 0));
std::cout << "List: " << std::endl;
std::copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(std::cout, "\n"));
std::cout << std::endl;
std::cout << "Negatives:" << std::endl;
std::copy(negatives.begin(), negatives.end(),
std::ostream_iterator<int>(std::cout, "\n"));
}
int main(void)
{
std::srand(static_cast<unsigned>(std::time(0)));
find_negatives();
}
此算法将测试一组的一致性:
// consistent_property.hpp
#ifndef CONSISTENT_PROPERTY_HPP
#define CONSISTENT_PROPERTY_HPP
#include <boost/logic/tribool.hpp>
// checks if all elements consistently pass/fail a property
// if it returns indeterminate, then the results are mixed,
// otherwise all results pass or failed as indicated
template <typename Iter, typename Func>
boost::logic::tribool consistent_property(Iter first, Iter last, Func func)
{
bool result = func(*first++);
for(; first != last; ++first)
{
if (func(*first) != result)
{
// differs
return boost::logic::indeterminate;
}
}
return result;
}
#endif
这将检查一个容器中的属性是否一致,而不是它是否成立。也就是说,如果所有元素都没有通过属性,它将返回false,如果它们都执行,则返回true(与share_property_concise
相同的结果),如果结果混合则不确定。
以下是一个例子:
#include "consistent_property.hpp"
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
typedef std::vector<int> container;
void check_sign(void)
{
container positives;
positives.push_back(1);
positives.push_back(2);
positives.push_back(3);
boost::logic::tribool result =
consistent_property(positives.begin(), positives.end(),
std::bind2nd(std::greater<int>(), 0));
if (boost::logic::indeterminate(result))
{
std::cout << "Mixed signs." << std::endl;
}
else if (result)
{
std::cout << "All positive." << std::endl;
}
else
{
std::cout << "All negative." << std::endl;
}
}
int main(void)
{
check_sign();
}
最后,我提供了一个仿函数,可以获得不太具体的一致性结果。虽然上面将告诉一致性是否失败,传递或混合,但使用带有share_property
的仿函数只能确定集合是否一致或混合。你不能推断它是一致的。
这可能是解决原始问题的最简单方法。要有一个相同的标志,而不需要知道那个标志是什么,可以通过这种方式完成,给出一个快速的&amp;结果简单;或者它们都是相同的标志。
将以下内容添加到consistent_property.hpp
:
// the functor to determine if the property that all elements
// in a set share, is the property that they all pass or fail
// a secondary property. there is no way to deduce what the
// status was (if they all passed or all failed), only if
// all the elements were consistent. true indicates consistency,
// false indicates lack thereof
template <typename T, typename Func>
class consistent_shared_property_binder
{
public:
consistent_shared_property_binder(const Func& func) :
_func(func)
{
}
bool operator()(const T& t)
{
bool result = _func(t);
static bool status = result; // only initialized first run
return status == result;
}
private:
Func _func;
};
// bind a function to the functor
template <typename T, typename Func>
consistent_shared_property_binder<T, Func> consistent_property(Func func)
{
return consistent_shared_property_binder<T, Func>(func);
}
示例程序:
#include "consistent_property.hpp"
#include "shared_property.hpp"
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
typedef std::vector<int> container;
bool is_positive(int i)
{
return i > 0;
}
void check_sign_anonymous(void)
{
container positives;
positives.push_back(-1);
positives.push_back(-2);
positives.push_back(-3);
if (share_property_concise(positives.begin(), positives.end(),
consistent_property<int>(is_positive)))
{
std::cout << "All the same sign." << std::endl;
}
else
{
std::cout << "Mixed signs." << std::endl;
}
}
int main(void)
{
check_sign_anonymous();
}
我想我已经完成了。 :P
(注意:如果有人看到更好的方法做某事,或者有错误,请告诉我!)
答案 4 :(得分:1)
signof()
将返回-1表示任何负数,0表示0表示,1表示任何正数。
编辑:
如果signof()
或signbit()
不存在,您可以尝试使用按位运算来确定。对于负32位整数,(number >> 31)
将返回1
。
答案 5 :(得分:1)
以下是多个值的示例。您只需要从两值情况中创建相同符号比较的连通图:
(a<0) == (b<0) && (b<0) == (c<0) && (c<0) == (d<0) && ...
通过连接,我的意思是用“b”检查“a”,然后用“c”检查“b”等。