在 for 循环中使用 str.replace 而不会丢失最后一次迭代

Using str.replace in a for loop without losing last iteration

所以目前我正在编写一段代码,我得到一个字符串,需要计算字符串中每个字符出现的次数,如果它只出现一次,则用 x 替换它,如果出现次数超过一旦用y替换它。 EG:“分数”=>“yxxxxy”。

我当前的密码是

    public static string changeWord(string word)
    {
        var Pl = word;
        var pj = Pl;
        string alpha = "abcdefghijklmnopqrstuvwxyz";

        for (int i = 0; i < alpha.Length; i++)
        {
            var count = word.Count(x => x == alpha[i]);
            Console.WriteLine(count);

            if (count > 1)
            {
                Pl = word.Replace(alpha[i], 'y');
            }
            else if (count == 1)
            {
                Pl = word.Replace(alpha[i], 'x');
            }
        }

        return Pl;
    }
 

计数有效并显示每个字母的正确计数但仅更改代码中的最后一个所以“请”=>“Pleaxe”我不知道如何获取 .replace 以保留我的新字符串.

试试这个:

public static string changeWord(string word)
        {
            string alpha = "abcdefghijklmnopqrstuvwxyz";

            for (int i = 0; i < alpha.Length; i++)
            {
                var count = word.Count(x => x == alpha[i]);
                Console.WriteLine(count);

                if (count > 1)
                {
                    word = word.Replace(alpha[i], 'y');

                }
                else if (count == 1)
                {
                    word = word.Replace(alpha[i], 'x');

                }
            }

            return word;
        }

这个方法可以做你想要的工作

public static string changeWord(string word)
    {
        var wordToEdit = word;
        string alpha = "abcdefghijklmnopqrstuvwxyz";

        for (int i = 0; i < alpha.Length; i++)
        {
            var count = word.Count(x => x == alpha[i]);

            if (count > 0)
            {
                wordToEdit = wordToEdit.Replace(alpha[i], count == 1 ? 'x' : 'y');
            }
        }

        return wordToEdit;
    }

Replace 算法有问题:一旦将字母转换为 x,您就应该处理字母 x 本身,例如

initial:              box

after 'b' processed:  xox
after 'o' processed:  xxx # note, that x appeared 3 times now
after 'x' processed:  yyy
after 'y' processed:  yyy # we have 3 y's so they changed to themselves 

finally:              yyy # when xxx is expected

这就是为什么我建议使用 StringBuilderbuild new 字符串而不是更改现有的 word :

    public static string changeWord(string word) {
      if (string.IsNullOrEmpty(word))
        return word;

      StringBuilder sb = new StringBuilder(word);

      for (int i = 0; i < sb.Length; ++i)
        if (sb[i] >= 'a' && sb[i] <= 'z')
          sb[i] = word.Count(c => c == sb[i]) > 1 ? 'y' : 'x';

      return sb.ToString();
    }

longword的情况下,太多Count会很耗时;你可以尝试缓存它们:

    public static string changeWord(string word) {
      if (string.IsNullOrEmpty(word))
        return word;

      StringBuilder sb = new StringBuilder(word);

      Dictionary<char, int> counts = new Dictionary<char, int>();

      for (int i = 0; i < sb.Length; ++i)
        if (sb[i] >= 'a' && sb[i] <= 'z') {
          if (!counts.TryGetValue(sb[i], out int count)) {
            count = word.Count(c => c == sb[i]);

            counts.Add(sb[i], count);
          }

          sb[i] = count > 1 ? 'y' : 'x';
        }

      return sb.ToString();
    }