1

整数のセットに一定量だけ変更された整数が含まれているかどうかを確認する効率的な方法を知っている人はいますか?

たとえば、私は持っています:

int1 = 10;
int2 = 20;
int3 = 30;

そして、これら3つの整数のいずれかが変化するかどうかを知りたい30

これで、呼び出しがトリガーされる必要がなくなりましたint140最初は、このようなことをするだけだと思っていました。

if (abs((int1+int2+int3)-(newInt1+newInt2+newInt3)) >= 30) {

しかし、これにより多くの問題が発生する可能性があります...

  • 偽のトリガー (たとえば、新しい各 int 値が 10 ずつ増加し、NET の変化が 30 を超えますが、個々の int が 30 を超えるとは限りません)
  • トリガーされていない反応 (たとえば、新しい整数値の 1 つが 50 増加したため、それを呼び出す必要がありますが、別の新しい整数値を 50 減少させます (再び呼び出す必要があります)。ただし、正味の変化は 0 です-50+50=0) 。

誰かがこれを行う効率的な方法を持っていますか? (はい、OR ステートメントを使用して各値を個別に確認できることは明らかです...)

これまでのところ、これは私の最高の突き刺しです

if ((((abs(int1-newInt1))>=30)+((abs(int2-newInt2))>=30)+((abs(int3-newInt3))>=30))>0) {

ただし、これは基本的に OR ステートメントを使用する場合と同じです (おそらく、OR ステートメントよりも少し時間がかかります。

4

2 に答える 2

1

それよりも速くなることはないと思います。数億の整数を扱っていない限り、パフォーマンスが大幅に低下することはありません。


ただし、「賢く」なりたいと思うかもしれません。何らかの方法で 2 つの合計を「チェックサム」するとどうなるでしょうか。たとえば、すべての古い数値と新しい数値に n 番目の素数を掛けてから、新しい合計と古い合計の差を 4index番目の素数で割った値が必要な量であるかどうかを確認します。

int sum(int arr[], size_t n)
{
    int n = 0;
    for (int i = 0; i < n; i++)
        n += primes[i] * arr[i];

    return n;
}

int primes[3] = { 2, 3, 5 }; // or more
int olds[3] = { 10, 20, 30 };
int news[3] = { 40, 20, 30 };

int nth = 0; // check first
int change_expected = 30;
int oldsum = sum(olds, 3);
int newsum = sum(news, 3);
if ((newsum - oldsum) / primes[nth] == change_expected) {
    // 1st value changed as expected
}

これには、素朴なアプローチよりも多くの時間と CPU サイクルがかかることに注意してください。

于 2013-05-14T13:15:14.493 に答える
0

目的の -cを使用しているため、いつでも目的どおりのオブジェクトを作成できます (例の下のクラスを参照)。このようにすることの主な利点は、整数が設定されるたびにすべての整数をチェックする必要がないことです。変更された各番号をチェックして、変更が多すぎるかどうかを確認するだけです。

使用例:

// myNumbers.confined will be true until you create a number, and THEN change it by 30 or more.
ARConfinedNumbers *myNumbers = [ARConfinedNumbers new];
[myNumbers addNumber:10];
[myNumbers addNumber:20];
[myNumbers addNumber:30];

[myNumbers replaceNumberAtIndex:0 withObject:40];

// No longer confined because we have changed 10 to 40
if (!myNumbers.confined)
    NSLog(@"Not confined.");

// Reset
[myNumbers setConfined:YES];

これを行うために私が書いたクラスは次のとおりです。iOS/MacOS 向けにプログラミングしていると仮定してを使用したことに注意してくださいNSArray。これらのクラスを使用していない場合は、NSArray を別のものに置き換えることができます。ただし、これは優れた出発点となるはずです。

ARConfinedNumbers.h:

#import <Foundation/Foundation.h>

@interface ARConfinedNumbers : NSObject

// confined is true if the numbers have not been changed by more than 30.
// This can be reset by setting it to YES.
@property (nonatomic, assign) BOOL confined;

// Methods to manipulate the set of numbers
// Add more array-type-methods as needed
- (void)addNumber:(int)number;
- (void)replaceNumberAtIndex:(NSUInteger)index withObject:(int)number;
- (int)numberAtIndex:(NSUInteger)index;
- (NSUInteger)count;

@end

ARConfinedNumbers.m

#import "ARConfinedNumbers.h"

/* Private Methods */
@interface ARConfinedNumbers()

@property (nonatomic, strong) NSMutableArray *numbers;

@end

@implementation ARConfinedNumbers

- (id)init
{
    self = [super init];
    if (self)
    {
        _confined = YES;
        _numbers = [NSMutableArray new];

    }
    return self;
}

- (void)addNumber:(int)number
{
    [self.numbers addObject:@(number)];
}

- (void)replaceNumberAtIndex:(NSUInteger)index withObject:(int)number
{
    if (index < self.numbers.count)
    {
        if (number)
        {
            int existingNumber = [self.numbers[index] intValue];
            if (abs(existingNumber - number) >= 30)
                self.confined = NO;

            [self.numbers replaceObjectAtIndex:index withObject:@(number)];
        }
    }
}

- (int)numberAtIndex:(NSUInteger)index
{
    if (index < self.numbers.count)
        return [self.numbers[index] intValue];

    return 0;
}

- (NSUInteger)count
{
    return self.numbers.count;
}

@end
于 2013-07-18T03:40:47.040 に答える