Objective Cで配列をランダム化する正規の方法はありますか?Objective CでNSArrayをランダムに正規化する方法
答えて
マイユーティリティライブラリは、それを行うにはNSMutableArrayの上で、このカテゴリを定義します。
@interface NSMutableArray (ArchUtils_Shuffle)
- (void)shuffle;
@end
// Chooses a random integer below n without bias.
// Computes m, a power of two slightly above n, and takes random() modulo m,
// then throws away the random number if it's between n and m.
// (More naive techniques, like taking random() modulo n, introduce a bias
// towards smaller numbers in the range.)
static NSUInteger random_below(NSUInteger n) {
NSUInteger m = 1;
// Compute smallest power of two greater than n.
// There's probably a faster solution than this loop, but bit-twiddling
// isn't my specialty.
do {
m <<= 1;
} while(m < n);
NSUInteger ret;
do {
ret = random() % m;
} while(ret >= n);
return ret;
}
@implementation NSMutableArray (ArchUtils_Shuffle)
- (void)shuffle {
// http://en.wikipedia.org/wiki/Knuth_shuffle
for(NSUInteger i = [self count]; i > 1; i--) {
NSUInteger j = random_below(i);
[self exchangeObjectAtIndex:i-1 withObjectAtIndex:j];
}
}
@end
あなたはそれを呼び出すいつか前に、あなたが(例えばsrandom(time(NULL))
付き)乱数生成器にシードを確認してください。そうでなければ、出力はあまりランダムではありません。
それを愛する!共有してくれてありがとう。私はあなたのユーティリティライブラリの残りの部分について非常に不思議です。 – PEZ
ほとんどのものはアルゴリズムではありません。+ [NSArray arrayWithCount:numbers:]( "numbers"は2倍です)から - [UIView moveToSuperview:withFrame:animated:]、さらにキックのための単一オブジェクトのコアデータスタック。 –
これは私のためには機能しません。私はそれが "少し"シャッフルを意味しますが、いくつかの部分はまだ順序です。同じ配列を与えられても、最初のシャッフルは常に同じ結果を示します。したがって、実際にはランダムではありません。 –
あなたが求めているのであれば、SDKには何も組み込まれていません。
ただし、任意のランダム化アルゴリズムやシャッフルアルゴリズムを使用できます。異なるアルゴリズムは
http://en.wikipedia.org/wiki/Shuffling#Shuffling_algorithms
「インプレース」シャッフルアルゴリズムのために再構築したアルゴリズムについて
insertObject:atIndex:
removeObjectAtIndex:
を使用する可変配列で始まるなど、ランダム性、効率の点で異なるトレードオフを持っていますそれを元に戻し、新しい配列を作成します。
random()関数にsrandomdev()またはsrandom()を指定してください。
あなたが書いたことは、インスタンスメソッドとしては意味がありません。コードが存在するので、関数またはクラスメソッドでなければなりません。慣習的には、シャッフルされた新しい配列、またはシャッフルするNSMutableArrayインスタンスメソッドを返すNSArrayインスタンスメソッドでなければなりません。 – Chuck
本当に、私はここでコードをデモしていただけで、カテゴリに入れることを心配していませんでした。 random()関数をsrandomdev()またはsrandom()でシードすることについても言及していませんでした。 –
このコードはモジュロによってわずかに偏っています。詳しくは、http://en.wikipedia.org/wiki/Fisher-Yates_shuffle#Modulo_biasを参照してください。 –
NSArray
(つまりarrayWithRandomizedIndices
などのインスタンスメソッドを持つ)またはNSMutableArray
(つまりrandomizeIndices
のようなメソッドを持つ)にカテゴリを作成することはできません。
ここに私の図書館の例があります。カテゴリの一部はNSMutableArray
です。いくつかのエントリをシャッフルするのではなく、配列をランダムに並べ替えます。
- (void) randomizeIndices
{
if (self == nil || [self count] <= 1)
{
return;
}
int count = [self count];
NSMutableArray* copySelf = [NSMutableArray arrayWithArray:self];
NSMutableArray* mutableResultArray = [NSMutableArray alloc];
mutableResultArray = [mutableResultArray initWithCapacity:count];
[mutableResultArray autorelease];
int objectsMovedCount = 0;
for (int i = 0; i < count; i++)
{
int index = rand() % (count - objectsMovedCount);
id anObject = [copySelf objectAtIndex:index];
[mutableResultArray addObject:anObject];
[copySelf removeObjectAtIndex:index];
objectsMovedCount++;
}
[self setArray:mutableResultArray];
}
コールsrand(time(0));
または早期の方法でこのメソッドまたはを呼び出す前に、いくつかのように。
私の解決策は、(arc4randomを使用して)要素をランダム化して配列のコピー(オートレリース)を返すカテゴリメソッドです。
@interface NSArray (CMRandomised)
/* Returns a copy of the array with elements re-ordered randomly */
- (NSArray *)randomised;
@end
/* Returns a random integer number between low and high inclusive */
static inline int randomInt(int low, int high)
{
return (arc4random() % (high-low+1)) + low;
}
@implementation NSArray (CMRandomised)
- (NSArray *)randomised
{
NSMutableArray *randomised = [NSMutableArray arrayWithCapacity:[self count]];
for (id object in self) {
NSUInteger index = randomInt(0, [randomised count]);
[randomised insertObject:object atIndex:index];
}
return randomised;
}
@end
ここにあります!
@implementation NSArray (NGDataDynamics)
- (NSArray *)jumbled
{
NSMutableArray *jumbled = self.mutableCopy;
NSUInteger idx = self.count-1;
while(idx)
{
[jumbled exchangeObjectAtIndex:idx
withObjectAtIndex:arc4random_uniform(idx)];
idx--;
}
return jumbled;
}
@end
見られるように:Objective-Cのカテゴリ方法として
- (NSArray*)shuffleArray:(NSArray*)array {
NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:array];
for(NSUInteger i = [array count]; i > 1; i--) {
NSUInteger j = arc4random_uniform(i);
[temp exchangeObjectAtIndex:i-1 withObjectAtIndex:j];
}
return [NSArray arrayWithArray:temp];
}
NSArrayのランダムNSArray Randomization & Psychedelia
- 1. ランダム4x4 2D NSArray Objective-C
- 2. Objective-CでオブジェクトのNSArrayを返す正しい方法は何ですか?
- 3. objective-c、アニメーションブロックのランダム化
- 4. Objective CのNSArrayでconst char * argv []を変換する方法
- 5. Objective CでNSObjectsのNSArrayのプロパティを宣言する方法
- 6. objective-c空NSArrayエラー
- 7. Objective Cの正規表現
- 8. NSArrayのオブジェクトを削除する(Objective-C)
- 9. 正規化を逆にする方法
- 10. Objective-CオブジェクトをNSArrayからNSArrayに渡す
- 11. のObjective-C:作るNSArrayのすべて
- 12. Objective-Cで@encode()を使用してNSArrayを取得する方法
- 13. Objective-C NSArrayのゲッターとセッターでSwiftプロトコルを定義する方法
- 14. NSArrayの要素に基づいてメソッドを選択する方法(Objective-C)
- 15. cでSQLクエリテキストを正規化する
- 16. objective-cの文字列部分とNSArray値の一致方法
- 17. ヒストグラムを正規化する方法
- 18. コンパイル時にNSArrayを埋める方法は?以下のような何かをする方法をObjective-Cで
- 19. Objective-CでNSArrayの要素を追加するには?
- 20. Objective-C命名規則 - 明確化
- 21. 2d NSArray列挙型をobjective-c
- 22. 正規化VS.ノーマライズする方法
- 23. Python Pandasでjsonを正しく正規化する方法
- 24. Objective-Cのデリゲートプロパティを正しくサブクラス化する方法はありますか?
- 25. クラスを動的にサブクラス化し、Objective Cでサブクラスをインスタンス化する方法は?
- 26. iOS - Objective C、キー名でNSDictionaryのNSArrayをソートする
- 27. NSArrayを2次元でソートする - Objective-C
- 28. Objective C(NSRegularExpression)で正規表現を書くには?
- 29. Objective CでNSMutableArrayを初期化する方法は?
- 30. ネストされたNSArrayでNSArrayをソートする方法
の可能重複[NSMutableArrayのをシャッフルするための最良の方法は何?](のhttp:// stackoverflowの.com/questions/56648/whats-the-best-way-to-shuffle-an-nsmutablearray) – Senseful
おすすめは[Fisher-Yates](https://en.wikipedia.org/wiki/Fisher%E2%80%)です。 93Yates_shuffle)for NSMutableArray: 'for(NSUInteger i = self.count; i> 1; i--)[self exchangeObjectAtIndex:i - 1 with ObjectAtIndex:arc4random_uniform((u_int32_t)i)]; ' –