访问字符串作为数组,检查索引处的值并可能更改该索引处的字符。

3

我一直在尝试读取一个字符串,然后逐个字符运行一个随机数,如果生成了5,则将该字符从1更改为0或反之亦然。我觉得我已经接近成功了,这是我第三次尝试,但我在写入索引时遇到了轻微的问题,因为它告诉我只读。以下是我的代码:

string mutate = "1010";

for (int i = 0; i < 4; i++)
{
    int MutProbablity = random.Next(1, 1000);
    if (MutProbablity == 5)
    {
        if (mutate[i] == '0')
        {
            mutate[i] = '1';
        }
        else if (mutate[i] == '1')
        {
            mutate[i] = '0';
        }
    }
}

这是我的错误信息:

无法分配属性或索引器“string.this[int]”,因为它是只读的。

有人能告诉我如何解决这个问题,或者建议一种不同的方法来实现我的目标吗?

4个回答

11

.NET中的字符串是不可变的,因此您将无法修改任何字符,但是您可以通过首先将其转换为可变对象char[]来实现您的目标。

像这样:

var chars = mutate.ToCharArray();     // convert to char[]
for (int i = 0; i < 4; i++)
{
    int MutProbablity = random.Next(1, 1000);
    if (MutProbablity == 5)
    {
        if (chars[i] == '0')
        {
            chars[i] = '1';
        }
        else if (chars[i] == '1')
        {
            chars[i] = '0';
        }
    }
}

mutate = new String(chars);    // convert to back to string

另一种方法是使用 Linq(以及一长串三元运算符,有点丑陋)。

var new string(mutate.Select(c => 
    (random.Next(1, 1000) == 5) ? ((c == '0') ? '1' : (c == '1') ? '0' : c) : c).ToArray());

谢谢,我现在要尝试一下,我确信我之前尝试过类似的东西,但可能做错了!我会告诉你我的进展的! :) - deucalion0
第二种方法看起来有点混乱! :) 我以前从未使用过 Linq,不过我听说过。干杯! - deucalion0
2
@deucalion0 这只是一种更紧凑的做法,实际上我不建议在生产代码中使用它,因为它很难阅读,但出于完整性的考虑,我想包含它。 - p.s.w.g
谢谢,这个当然有效,我现在也知道如何处理字符和字符串了,所以谢谢!!!还要感谢你的完整性! :) - deucalion0

1
你的mutate字符串只由0和1组成吗?
StringBuilder可以用来改变字符串中的单个字符。
Random r = new Random();
StringBuilder b = new StringBuilder("0101");
for (int i = 0; i < 4; i++)
{
    int MutProbablity = r.Next(1, 1000);
    if (MutProbablity == 5)
    {
        b[i] = (b[i] == '0' ? '1' : '0');
    }
}
Console.WriteLine(b.ToString());

1
正如所述,字符串是不可变的,但是类StringBuilder实际上是一个可变字符串。创建一个自定义类,使用StringBuilder作为后备存储器,类似于以下内容:
class MyMutableString
{
  private StringBuilder backingStore ;
  private string        currentValue ;
  public MyMutableString()
  {
    this.backingStore = new StringBuilder() ;
    this.currentValue = this.backingStore.ToString() ;
    return ;
  }
  public MyMutableString( string initialValue )
  {
    this.backingStore = new StringBuilder( initialValue ) ;
    this.currentValue = this.backingStore.ToString() ;
  }

  public string Value
  {
    get
    {
        return this.currentValue ;
    }
    set
    {
      this.backingStore.Length = 0 ;
      this.backingStore.Append( value ) ;
      this.currentValue = this.backingStore.ToString() ;
    }
  }

  public void Mutate( int mutationThreshold , Dictionary<char,char> mutations )
  {
    int probability = GetNextRandomValue() ;
    if ( probability == mutationThreshold )
    {
      int replacementsMade = 0 ;
      for ( int i = 0 ; i < this.backingStore.Length ; ++i )
      {
        char c = this.backingStore[i] ;
        char r ;
        bool mutate = mutations.TryGetValue(c, out r ) ;
        if ( mutate )
        {
           this.backingStore[i] = r ;
           ++replacementsMade ;
        }
      }
      this.currentValue = this.backingStore.ToString() ;
    }
    return ;
  }

  private static readonly Random random = new Random() ;
  private int GetNextRandomValue()
  {
    int value = random.Next(1,1000) ;
    return value ;
  }

}

谢谢你的回答,我会把这段代码保存在我的工具箱里! :) 非常感谢! - deucalion0

1
尝试使用StringBuilder,它提供了单个字符更改和更多有用的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接