【问题标题】:Replace byte 10 by 10 10用 10 10 替换字节 10
【发布时间】:2015-09-11 07:22:05
【问题描述】:

嗨,我想用 10 10 替换 10 字节 []。这是我的代码。 如果我的数据为“10 20 10 20 40 50 50 50 50 10 03”,我想将其替换为 “10 20 10 10 20 40 50 50 50 50 10 10 03” 注意:第一个字节未触及 请关注我的评论,我的想法是将字节数组推到 nxt 位置并添加另一个 10。

 foreach (var b in command.ToBytes()) 
                {

                   // var c = b;
                    transmitBuffer[count++] = b;  data is formed here
                    addedbuffer[addall++] = b;     duplication is made
                }
                if (addedbuffer[0] == 16 && addedbuffer[1] == 32 || addedbuffer[50] == 16 && addedbuffer[51] == 03)           /
                    {
/condition on which to enter here
                        addedbuffer[0] = 0;  //making 1st and 2nd value as null
                        addedbuffer[1] = 0;
                        for (int i = 0; i < addedbuffer.Length; i++) //till length i will chk 
                        {
                            if (addedbuffer[i] == 10) //replace 10  by 10 10 
                                addedbuffer[i] = 1010; // error,
                        }




        }

【问题讨论】:

  • 使用List&lt;byte&gt;而不是数组并调用List&lt;byte&gt;.Insert()
  • 如何设置位置,因为 10 可能出现在任何地方?
  • 按索引遍历列表。只要有 10,就在其后面插入另一个 10(但不要在新插入的后面插入另一个)。
  • 对不起,我有点迷路了,你能改变我的代码给我看看吗?
  • 添加一个新项目会改变列表的计数,所以你可能想去for (int index = list.Count; index &gt; 0; index--) { if (list[index] == 10) { list.Insert(index, 10); }}

标签: c# sequence


【解决方案1】:

你不能insertarray中(你可以用List&lt;T&gt;来做),所以看起来你必须创建一个new em> 数组; Linq 解决方案:

  Byte[] source = new Byte[] {
    20, 10, 20, 40, 50, 50, 50, 50, 10, 03
  };

  var result = source
    .SelectMany((item, index) => 
       item == 10 && index != 0 ? new Byte[] { item, item } : new Byte[] { item })
    .ToArray();

但是,使用 List&lt;Byte&gt;(为了插入 10)而不是 Byte[] 是更好的方法:

  List<Byte> list = List<Byte>() {
    20, 10, 20, 40, 50, 50, 50, 50, 10, 03
  };

  // In order not to read inserted 10's we loop backward 
  // i >= 1: 1st byte should be preserved as is even if its == 10
  for (int i = list.Count - 1; i >= 1; --i)
    if (list[i] == 10)
      list.Insert(i + 1, 10);

【讨论】:

  • 嗨,我的数据存储在“private readonly byte[] transmitBuffer;”我如何将它分配给您的解决方案中的新数组?
  • @Anil Gadiyar:只需assign,即transmitBuffer = transmitBuffer.SelectMany(...);
【解决方案2】:

将数组之类的序列(C# 中的IEnumerable&lt;T&gt;)视为可以转换为新序列的东西会有所帮助。就像将数字发送到函数时可以转换它们一样,序列也可以。

考虑我是否有一个定义为Add10If10(Byte b) 的函数。它可能看起来像这样:

public static Byte Add10If10(Byte b)
{
    if (b == 10)
    {
        return b + 10;
    }

    return b;
}

其中的数字会根据条件进行转换,结果要么大 10 要么相同。序列也可以这样做,您可以获取具有一定数量元素的序列,并对其进行转换以使其具有更多元素。结果是一个新序列:

public static IEnumerable<Byte> AddAdditional10If10(IEnumerable<Byte> values)
{
    foreach (var b in values)
    {
        if (b == 10)
        { 
            yield return 10;
        }

        yield return b;
    }
}

此函数每遇到 10 个,就会返回一个额外的 10 个。现在你有了正确的序列,你可以通过将其更改为数组来更改它的存储方式:

AddAdditional10If10(addedbuffer).ToArray();

【讨论】:

    【解决方案3】:

    这通过转换为字符串,使用String.Replace 并转换回来:

    byte[] source = new Byte[] { 20, 10, 20, 40, 50, 50, 50, 50, 10, 03 };
    
    string[] strArr = Array.ConvertAll(source, b => b.ToString());
    string[] replArr = String.Join(" ", strArr).Replace("10", "10 10").Split();
    
    byte[] newArr = Array.ConvertAll(replArr, str => Byte.Parse(str));
    

    编辑:

    另一种使用 LINQ 的方法 - 第一个和最后一个索引处的元素以及所有不等于 10 的元素都保持不变,对于所有剩余的 10s,它会返回 2 个10s 的序列:

    byte[] res = source.SelectMany((b, index) => index == 0 
                                                 || index == source.Length - 1      
                                                 || b != 10 ? 
                                   Enumerable.Repeat(b, 1) : Enumerable.Repeat(b, 2))
                       .ToArray();
    

    【讨论】:

    • 我想丢弃前 2 个字节和最后 2 个字节,我的意思是不能在前 2 个和最后 2 个字节中发生替换,但必须在任何地方休息 ..即使第一个字节中有 10 个它应该保持不变
    【解决方案4】:

    这是一种相当有效的方法(需要两次遍历输入数组,但不需要调整输出数组的大小):

    public static byte[] Replace10With1010ExcludingFirstByte(byte[] input)
    {
        //  Count 10s excluding first byte.
        int count = input.Skip(1).Count(b => b == 10);
    
        // Create output array of appropriate size.
        byte[] result = new byte[input.Length +  count];
    
        // Copy input to output, duplicating all 10s that are not the first byte.
    
        result[0] = input[0];
    
        for (int i = 1, j = 1; i < input.Length; ++i, ++j)
        {
            result[j] = input[i];
    
            if (input[i] == 10)
                result[++j] = 10;
        }
    
        return result;
    }
    

    使用您的原始数组调用它,并改用返回的数组。

    测试代码(用于控制台应用):

    byte[] input = {10, 20, 10, 20, 40, 50, 50, 50, 50, 10, 03};
    var result = Replace10With1010ExcludingFirstByte(input);
    Console.WriteLine(string.Join(", ", result));
    

    [编辑] 从你的一个 cmets 到另一个答案,你似乎也想从转换中排除最后一个字节。

    如果是这样,请改用此代码:

    public static byte[] Replace10With1010ExcludingFirstAndLastByte(byte[] input)
    {
        //  Count 10s excluding first and last byte.
        int count = input.Skip(1).Take(input.Length-2).Count(b => b == 10);
    
        // Create output array of appropriate size.
        byte[] result = new byte[input.Length +  count];
    
        // Copy input to output, duplicating all 10s that are not the first byte.
    
        result[0] = input[0];
    
        for (int i = 1, j = 1; i < input.Length; ++i, ++j)
        {
            result[j] = input[i];
    
            if ((input[i] == 10) && (i != (input.Length-1)))
                result[++j] = 10;
        }
    
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-23
      • 2011-12-05
      • 2023-03-04
      • 2021-05-12
      • 2021-12-30
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多