0

数値の範囲があります。

範囲内の各数値が別の数値リストに存在することを確認したい。

for ループを使用していますが、アプリケーションの速度が低下します。

public void ShowResults()
{
    // The StartNumber and EndNumber is changed depends 
    // upon my requirement, They are not fixed.  
    int StartNumber = 1 ; 
    int EndNumber = 1000000;

    string[] list =
    {
        "1", "equal", "3", "perhaps", "6", "10", "378", 
        "1937", "28936", "26543", "937" .........,
        "understood" "99993"};

    for(int i = StartNumber; i<= EndNumber;i++)
    {
        List<int> resultList = new List<int>();
        int index = Array.IndexOf(list,i.ToString());
        if(index >= 0)
        {
            resultList.Add(i);
        }
    }
}
4

7 に答える 7

1

バイナリ検索を使用して、ある配列の要素を別の配列で見つけることができます。その場合、配列の1つ(バイナリ検索を実行する配列)を並べ替える必要があります。

        string[] arr = new string[]{
                    "1", "equal", "3", "perhaps", "6", "10", "378", 
                    "1937", "28936", "26543", "937",
                    "understood", "99993"
        };

        // Create sorted array
        int[] firstMillionNumbers = Enumerable.Range(1, 1000000).ToArray();

        // Parse out numbers only
        List<int> listINT = new List<int>();
        int num;
        foreach (string s in arr)
            if (int.TryParse(s, out num))
                listINT.Add(num);

        // Find elements of a list inside sorted array
        List<int> resultList = new List<int>();
        foreach(int num2 in listINT)
        {
            if (Array.BinarySearch(firstMillionNumbers, num2) >= 0)
                resultList.Add(num2);
        }
于 2012-08-03T10:48:43.000 に答える
0

これを試して、

if(list.Intersect(resultList).Count == resultList.Count)
{

}
于 2012-08-03T10:19:14.070 に答える
0

プログラミング言語ではなく、アルゴリズムの観点から答えようとしています..

o(n^2) の複雑さを引き起こしている 2 つの for ループを使用しようとしており、プログラムの速度が低下しています。比較する範囲がある場合は、リストを反復して各値を 2 つの単純な if でチェックしてみませんか? これにより、複雑さが o(n) に軽減されますね。

于 2012-08-03T10:22:08.810 に答える
0

一般に、多数の変数セットの反復処理は常に遅くなります。インデックス作成またはソート以外に、これを回避する実際の方法はありません (たとえば、ツリー内では、その大部分をスキップできます)。

ただし、反復ごとに新しいコードを再作成するため、サンプル コードはさらに遅くなりList<int>ます (結果が意味をなさないため、おそらくやりたくないことです)。

于 2012-08-03T10:37:07.053 に答える
0

質問に関するいくつかの問題。resultList を何百万回も作成するのはなぜですか (そして最後の値しかありません)。小さなリストを int にフィルタリングするのではなく、なぜ i.ToString を何百万回も呼び出すのですか?

わかりました、これは本当の問題ではないと言うつもりです。そして私の答えは、それが投稿された問題です。現実的な答えが欲しいなら、現実的な質問が必要です。

int StartNumber = 1 ; 
int EndNumber = 1000000;

string[] list =
{
    "1", "equal", "3", "perhaps", "6", "10", "378", 
    "1937", "28936", "26543", "937" .........,
    "understood" "99993"};

List<int> resultList = new List<int>();
int intOut;
foreach(string li in list)
{
   if (int32.TryParse(li, out intOut))
   {
       if(intOut >= StartNumber && intOut <= EndNumber) resultList.Add(intOut));
   }
}
于 2012-08-03T12:46:34.660 に答える
0

最初のリスト (「1」から「1000000」までのリスト) は動的に決定されるため、できることはあまりありません。しかし、あなたの2番目はどうですか?この文字列のリストが一定である場合、または少なくとも 1 回早期に生成される場合は、HashSet<string>ではなくを使用する必要がありstring[]ます。これにより、検索がはるかに高速になります。

// This will create an IEnumerable<string> with all numbers to search.
IEnumerable<string> stringsToFind = Enumerable.Range<int>(StartNumber, EndNumber-StartNumber).Select(number => number.ToString());

// This is all the strings in a HashSet. This should be done *beforehand*.
HashSet<string> strings = new HashSet<string>(new [] {  "1", "equal", "3", etc...};

// resultList contains all numbers (from stringToFind) that are in strings).
var resultList = strings.Intersect(stringsToFind);
于 2012-08-03T10:32:24.650 に答える
0

最初に、同様のコレクション (同じタイプの数値または文字列) が必要です。より小さなコレクションを選択して、2 番目のコレクションに採用する必要があります。list以下の例では、コレクションは数値のコレクションよりも小さいと想定しています。

それが良い解決策になるかどうかはわかりません。

var originalNumbers = new[] {1, 2, 3, 4, 5, 6};
string[] list =
    {
        "1", "equal", "3", "perhaps", "6", "10", "378",
        "1937", "28936", "26543", "937", "understood", "99993"
    };

IList<int> parsedNumbers = new List<int>();
foreach (var item in list)
{
    int temp;
    if(int.TryParse(item, out temp))
        parsedNumbers .Add(temp);

}

var result = parsedNumbers .Intersect(originalNUmbers);
于 2012-08-03T10:33:03.013 に答える