30423


## 質問

配列の要素に優先順位を付けてその順番で値を取得したいです。  
取得優先順位 876E5D4C3B2A1

[code]

    DataTable table = new DataTable();
    
    string[] number = new string[] { "E", "D", "C", "B", "A", "8", "7", "6", "5", "4", "3", "2", "1" };
    
        for (int i = 1; i < 8191; i++) {
                    //整数を2進数に変換 
                    //※ 1 = 0000000000001
                    string bitConvert = Convert.ToString(i, 2).PadLeft(13, '0');
                    var dRow = table.NewRow();
                    dRow[0] = i;
                    
                    StringBuilder getNo = new StringBuilder();
                
    
                    for (int s = 0; s < bitConvert .Length; s++) {
                        string st = bitConvert [s].ToString();
                        if (st == "0") continue;
                        if (st == "1") {
                            getNo.Append(number[s]);
                        }
                    }
    dRow[1] = getNo.ToString();
    
[/code]

1から255は期待通り取得できるのですが、256からはA~E入ってきます。  
例えば、  
for文のiが256ならA  
for文のiが257ならA1  
と取得ができるはずです。  
ここまでは期待値通りなので問題はなかったのですが、

258から少し特殊な方法で配列の要素を取得しないといけなくなりました。  
iが258のとき取得した結果配列の並びはA2になります。  
しかし、2Aにしたいです。  
271ならA4321となるのですが、期待値は432A1。

結論から言うと  
１の左にA２の左にB３の左にC４の左D５の左にEを並べたいです。  
876E5D4C3B2A1のような状態を作りたいです。  
今のプログラムだとEDCBA87654321という並びになってしまいます。

[ここ](http://ufcpp.net/study/algorithm/col_heap.html)などを参考にしたのですが、よくわかりませんでした。

どなたかご教授いただけますでしょうか？  
よろしくお願いします。


CC BY-SA 3.0
2016-11-15T08:52:41.020
30420
2016-11-15T09:50:51.550
2020-06-17T08:14:45.997
-1
19310
question
c# array
配列に優先度を付けて値を取得したい。


まず想定するソート順を定義します。

[code]

    string[] sorted = new string[] { "8", "7", "6", "E", "5", "D", "4", "C", "3", "B", "2", "A", "1" };
    
[/code]

この各要素に対して`number`でのインデックスを求めます。

[code]

    int[] indexes = sorted.Select(s => Array.IndexOf(number, s)).ToArray();
    
[/code]

`for`文では`sorted`についての繰り返し処理を行い、`indexes`を用いて`number`でのインデックスに変換してから処理を行います。

[code]

    for (int s = 0; s < sorted.Length; s++)
    {
        string st = bitConvert[indexes[s]].ToString();
        if (st == "0") continue;
        if (st == "1")
        {
            getNo.Append(sorted[s]);
        }
    }
    
[/code]

なお質問とは直接関係ありませんが、今回扱っている`number`の要素はすべて長さ1の`string`なので`char`に置き換えることが出来ます。そうすると`bitConvert[indexes[s]].ToString()`の`ToString()`が不要になります。  
また`bitConvert`自体もビット演算で直接計算すれば不要になります。

[code]

    DataTable table = new DataTable();
    
    // 各stringが一文字なのでcharに変更する。
    // charのリストなのでstringを代わりに使用する。
    string number = "EDCBA87654321";
    string sorted = "876E5D4C3B2A1";
    int[] indexes = sorted.Select(s => number.IndexOf(s)).ToArray();
    
    // インスタンス作成をループ外に移動
    StringBuilder getNo = new StringBuilder();
    
    for (int i = 1; i < 8191; i++)
    {
        var dRow = table.NewRow();
        dRow[0] = i;
    
        // StringBuilderを毎回Clearする。
        getNo.Clear();
    
        for (int s = 0; s < sorted.Length; s++)
        {
            // 文字列化しなくてもANDで計算可能
            // 右からindexes[s]ビットが0かどうか判定する
            if ((i & (1 << indexes[s])) > 0)
            {
                getNo.Append(sorted[s]);
            }
        }
    
        dRow[1] = getNo.ToString();
    }
    
[/code]


CC BY-SA 3.0
2016-11-15T09:39:50.243
30423
2016-11-15T09:50:51.550
2016-11-15T09:50:51.550
5750
5750
30420
answer