1

「startNo」整数と「endNo」整数を持つ「numbers」オブジェクトの配列があるとします。

配列には複数の「数値」が存在する可能性があり、重複のない範囲のみを持つ変更されたオブジェクトを含む新しい配列を取得したいと思います。

例:アレイに次の場合:

number
( startNo:1 endNo:3)
( startNo:1 endNo:7)
( startNo:2 endNo:9)
( startNo:15 endNo:18)
( startNo:50 endNo:60)
( startNo:55 endNo:65)

次のような配列を取得したい:

number
( startNo:1 endNo:9)
( startNo:15 endNo:18)
( startNo:50 endNo:65)

私は構造体、fors、その他すべてを使ってさまざまなアプローチを試してみましたが、得られるのはマルチレベルの混乱だけです。

私はObjective-Cプラットフォームに取り組んでいます。

追加するには:startPageは大きな数にすることができ、endPageは小さな数にすることができます。

4

5 に答える 5

2

これは古典的なアルゴリズムコースの質問です。

最初の(最小の)値の降順で配列を並べ替えます。開始セグメント、終了セグメントの2つの変数を追跡します。

毎ターン、配列を選択し、開始番号と終了番号を確認して、それがセグメント内にあるかどうかを判断します。

このようにして、重複を見つけることが可能です

幸運を

于 2013-03-14T10:02:12.897 に答える
2

クラスがMyNumbersであり、次のようになっていると仮定します。

@interface MyNumbers : NSObject
@property NSInteger startNumber;
@property NSInteger endNumber;

- (id)initWithStartNumber:(NSInteger)start withEnd:(NSInteger)end;

@end

そしてマージする方法:

- (void)yourMethod{

    MyNumbers *obj1=[[MyNumbers alloc]initWithStartNumber:1 withEnd:3];
    MyNumbers *obj2=[[MyNumbers alloc]initWithStartNumber:1 withEnd:7];
    MyNumbers *obj3=[[MyNumbers alloc]initWithStartNumber:2 withEnd:9];
    MyNumbers *obj4=[[MyNumbers alloc]initWithStartNumber:15 withEnd:18];
    MyNumbers *obj5=[[MyNumbers alloc]initWithStartNumber:50 withEnd:60];
    MyNumbers *obj6=[[MyNumbers alloc]initWithStartNumber:55 withEnd:65];

    NSArray *array=@[obj1,obj2,obj3,obj4,obj5,obj6];
    NSMutableArray *mergedArray=[NSMutableArray arrayWithObject:array[0]];

    for (NSInteger index=1; index<array.count; index++) {
        MyNumbers *currentNumber=array[index];
        MyNumbers *previousNumber=array[index-1];

        if (currentNumber.startNumber<=previousNumber.endNumber) {
            previousNumber.endNumber=currentNumber.endNumber;
            [mergedArray replaceObjectAtIndex:mergedArray.count-1 withObject:previousNumber];
        }
        else{
            [mergedArray addObject:currentNumber];
        }
    }

    for(MyNumbers *element in mergedArray){
        NSLog(@"startNo:%d endNo:%d",element.startNumber, element.endNumber);
    } 
}

出力:

2013-03-14 17:14:05.040継承[34234:303] startNo:1 endNo:9
2013-03-14 17:14:05.041継承[34234:303] startNo:15 endNo:18
2013-03-14 17:14:05.041継承[34234:303] startNo:50 endNo:65
于 2013-03-14T11:41:23.577 に答える
1

これを解決するための簡単なアプローチ:

  1. 新しい空の配列を作成します(名前をtmpとしましょう)。
  2. 最初の配列のstartNoendNoをtmpに配置します。
  3. 2番目の配列のstartNoendNoを取ります。次に、それらがtmp内のものと重複するかどうかを決定します。(重ならない場合は、tmpの最後に両方を挿入してください。)
  4. アレイごとに手順を繰り返します。
  5. tmpは、重複することなくすべての範囲を保持するようになりました。
于 2013-03-14T10:12:30.243 に答える
1

テストされていない簡単なアイデア:

1.最小の開始番号saysnと対応する終了番号sayenを取得します。

2. start noがsn未満の場合は、次のオブジェクトのチェックを続行し、startnoを無視します。また、終了番号がenより大きい場合は、新しい終了番号をenに格納します。

3.これはあなたにあなたのオブジェクトを与えるでしょう。

4.開始番号がenより大きい場合は、配列に追加する新しいオブジェクトを作成します。

これはうまくいくはずです。さらに問題がある場合は教えてください

于 2013-03-14T10:12:34.760 に答える
0

// C#言語で書かれています。ただし、概念は任意のプログラミング言語で実装できます。

public class Range
{
    public int startNo { get; set; }
    public int stopNo { get; set; }

    public Range(int start, int stop)
    {
        startNo = start;
        stopNo = stop;
    }
}

        public void GetUniqueRanges()
    {
        var rangeList = new List<Range>();
        rangeList.Add(new Range(7,4));
        rangeList.Add(new Range(3, 15));
        rangeList.Add(new Range(54, 35));
        rangeList.Add(new Range(45, 60));
        rangeList.Add(new Range(60,75));
        rangeList.Add(new Range(76,100));
        rangeList.Add(new Range(6,10));
        rangeList.Add(new Range(16,24));
        rangeList.Add(new Range(19,34));

        var sorted = new List<Range>();
        foreach (var range in rangeList)
        {
            var item = new Range(Math.Min(range.startNo, range.stopNo), Math.Max(range.startNo, range.stopNo));
            sorted.Add(item);
        }
        var result = new List<Range>();
        sorted = sorted.OrderBy(x => x.startNo).ToList();
        var counter = sorted.Count;
        for (var i = 0; i < counter; )
        {
            var item = new Range (sorted[i].startNo, sorted[i].stopNo );
            var j = i + 1;
            for (; j < counter; j++)
            {
                if (sorted[j].startNo <= item.stopNo)
                {
                    item.stopNo =Math.Max(item.stopNo, sorted[j].stopNo);
                }
                else
                {

                    break;
                }
            }
            i = j;
            result.Add(item);
        }
    }
于 2013-03-14T14:06:23.850 に答える