33

resize(int newsize)C++ で forを使用すると、これのが に設定され、インデックスが range で実行されるvector<T>ことを意味します。C# で同じことを行うには? プロパティを 変更するとのみが変更されますが、同じままであり、さらにインデックスはまだ range にあります。助けてください。sizevectornewsize[0..newsize)List<T>
List<T>CapacityCapacityCount[0..Count)

PS I can't refer to を持っているvector<T> tmpと想像してみてください。C# の場合、 ( ) を参照できませんが、設定した場合でも、cozはまだ5を参照できません。C# でサイズ変更の類推を見つけたいと思います。tmp.size() == 5tmp[9]tmp.resize(10)tmp[9]List<T> tmptmp.Count == 5tmp[9]IndexOutOfRangeExceptiontmp.Capacity=10tmp[9]tmp.Count

4

7 に答える 7

35

いいえ。ただし、拡張メソッドを使用して独自のメソッドを追加できます。以下は、std::vector<T>::resize()同じ時間複雑度を含め、 と同じ動作をします。唯一の違いは、C++ では でデフォルトを定義できることvoid resize ( size_type sz, T c = T() )と、テンプレートが機能する方法Tは、アクセス可能なパラメーターなしのコンストラクターを持たない a のデフォルトなしで呼び出しても問題ないことを意味します。C# ではそれができないため、代わりに、デフォルトで使用されていないケースに一致する制約のない 1 つのメソッドと、where new()それを呼び出す制約のある別のメソッドを作成する必要があります。

public static class ListExtra
{
    public static void Resize<T>(this List<T> list, int sz, T c)
    {
        int cur = list.Count;
        if(sz < cur)
            list.RemoveRange(sz, cur - sz);
        else if(sz > cur)
        {
            if(sz > list.Capacity)//this bit is purely an optimisation, to avoid multiple automatic capacity changes.
              list.Capacity = sz;
            list.AddRange(Enumerable.Repeat(c, sz - cur));
        }
    }
    public static void Resize<T>(this List<T> list, int sz) where T : new()
    {
        Resize(list, sz, new T());
    }
}

myList.Resize(23)orのmyList.Resize(23, myDefaultValue)ようなものは、C++ のベクトルに期待されるものと一致するようになりました。ただし、C++ ではポインターのベクトルがある場合があることに注意してください。C# では、いくつかの参照型のリストがあります。したがって、C++T()が null ポインターを生成する場合 (ポインターであるため)、ここでは、パラメーターなしのコンストラクターを呼び出すことを期待しています。そのため、2 番目のメソッドを次のように置き換えると、慣れ親しんだ動作に近くなる場合があります。

  public static void Resize<T>(this List<T> list, int sz)
  {
      Resize(list, sz, default(T));
  }

これは、値型 (パラメーターなしのコンストラクターを呼び出す) でも同じ効果がありますが、参照型では null で埋められます。その場合、クラス全体を次のように書き換えることができます。

public static class ListExtra
{
    public static void Resize<T>(this List<T> list, int sz, T c = default(T))
    {
        int cur = list.Count;
        if(sz < cur)
            list.RemoveRange(sz, cur - sz);
        else if(sz > cur)
            list.AddRange(Enumerable.Repeat(c, sz - cur));
    }
}

これは と の違いではなく、C++ と C# でのポインターの使用方法の違いでstd::vector<T>あることに注意してください。List<T>

于 2012-09-01T23:10:33.433 に答える
0

これが私の解決策です。

private void listResize<T>(List<T> list, int size)
{
   if (size > list.Count)
      while (size - list.Count > 0)
         list.Add(default<T>);    
   else if (size < list.Count)
      while (list.Count - size > 0)
         list.RemoveAt(list.Count-1);
}

sizeとが同じ場合list.Count、リストのサイズを変更する必要はありません。

パラメーターは、 、、またはその他の null 許容型のdefault(T)代わりに使用され、リスト内の空の項目を埋めます。これは、型(参照、値、構造体など) がわからないためです。null""0<T>

PSforループの代わりにwhileループを使用しましたが、問題が発生しました。リストのサイズが常に私が求めていたものであるとは限りません。小さかったです。なぜ何か考えはありますか?

それを確認してください:

private void listResize<T>(List<T> list, int size)
{
   if (size > list.Count)
      for (int i = 0; i <= size - list.Count; i++)
         list.Add(default(T));
   else if (size < list.Count)
      for (int i = 0; i <= list.Count - size; i++)
         list.RemoveAt(list.Count-1);
}
于 2014-05-28T06:40:10.173 に答える
0

設定List<T>.Capacityは を使用するようなものstd::vector<T>.reserve(..)です。多分List<T>.AddRange(..)あなたのニーズに合っています。

于 2012-09-01T21:33:42.240 に答える
0

ごめん。これはあなたが必要とするものですか? List.TrimExcess()

于 2012-09-01T21:36:08.040 に答える
-2

MSDNで読んだことはありませんか:-

リストは、サイズ変更可能な項目のコレクションです。リストは複数の方法で作成できますが、最も便利なクラスは List です。これにより、リストを厳密に型指定でき、コレクションを処理するために必要なすべての機能が含まれ、簡単に検索できます。

さらに遠く:-

容量 は、サイズ変更が必要になる前にリストに格納できる要素の数であり、カウントは実際にリスト内にある要素の数です。

容量は常に Count 以上です。要素の追加中に Count が Capacity を超えた場合、古い要素をコピーして新しい要素を追加する前に、内部配列を自動的に再割り当てすることにより、容量が増加します

于 2012-09-01T21:37:59.943 に答える
-7

リストのサイズは有限ではありません。

サイズが重要な理由はありますか?

おそらく、配列または辞書が要件に近いでしょう

于 2012-09-01T21:33:24.713 に答える