【问题标题】:for loops clone outputfor 循环克隆输出
【发布时间】:2014-04-09 13:43:20
【问题描述】:

我对 C# 很陌生,您可能会从我的问题中注意到。我一直在制作“Røverspråk”翻译器来学习一些基础知识。 “Røverspråk”有点像 Pig Latin:规则是每个辅音都与辅音 + “o” + 辅音交换。到目前为止一切顺利,这部分有效。当我尝试将其翻译回来时,我的问题就出现了。

“totimom”应该返回“tim”,而是返回:"ttttttttttttttttttttttttttttttttttttttiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiimmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"。所以它返回每个字母 38 次 - 与我的 konsonant-string(挪威 konsonants)中的数量相同;

字符串 kons = "BCDFGHJKLMNPQRSTVWZbcdfghjklmnpqrstvwz";

为什么每次返回 38 次?据我所知,for 循环就像在我的翻译器中一样是分开的。给我带来麻烦的代码:

 public void OversettTilbake(string vok, string kons)
    {
        string nyText = textBox2.Text.ToString().ToLower();

        for (int e = 0; e < nyText.Length; e++)
        {
            for (int f = 0; f < kons.Length; f++)
            {
                if (nyText[e] == kons[f])
                {
                    newText2.Add(nyText[e].ToString());
                    e = e + 2;
                }

            }
            for (int g = 0; g < kons.Length; g++)
            {
                if (nyText[e] != kons[g])
                {
                    newText2.Add(nyText[e].ToString());
                }
            }

        }
    }

有效的翻译器:

 public int Oversetter(string text, string vok, string kons)
    {
        int Count = 0;
        char tom = ' ';

        for (int e = 0; e < text.Length; e++)
        {
            for (int i = 0; i < kons.Length; i++)
            {
                if (text[e] == kons[i])
                {
                    newText.Add((text[e]).ToString() + "o" + (text[e]).ToString().ToLower());
                    Count = Count + 1;
                }

            }
            for (int i = 0; i < vok.Length; i++)
            {
                if (text[e] == vok[i])
                {

                    newText.Add((text[e]).ToString());
                    Count = Count + 1;
                }
            }
            if (text[e] == tom)
            {
                newText.Add(text[e].ToString() + (text[e].ToString()));
            }
            for (int i = 0; i < tegn.Length; i++)
            {
                if (text[e] == tegn[i])
                {
                    newText.Add((text[e]).ToString());
                }
            }

        }

        return Count;
    }

编辑:感谢您在这里提供的所有精彩输入。我真的学到了很多。 @cahinton 的这个解决方案似乎工作得很好,对我来说理解和实施并不难:

for(var e = 0; e < nyText.Length; e += 1) {
newText2.Add(nyText[e].ToString);
if(kons.Contains(nyText[e])) {
    e += 2;
}

}

EDIT2:我没有必要的声誉在这里投票。但是感谢你们所有人一百万次!我预计在下周内会得到一两个答案,所以我不得不说我被这里的社区淹没了。再次感谢!

【问题讨论】:

  • 从不,neverNEVER 更改 for 循环中的循环变量!请改用while 循环。
  • @ThorstenDittmar 从来没有?如果我想跳过下一个元素怎么办?我需要一个额外的布尔值,现在你禁止我做i++;
  • 您好!感谢您的快速回复。不过,您能详细说明一下吗?
  • @Gusdor 我知道有时有理由跳过元素,但在那种情况下(即使它是一个 while 循环的替代品)你不应该使用for,而是真正的@987654329 @ 环形。当您更改 for 变量时,某些语言甚至无法编译。
  • @ThorstenDittmar 所以“从不,从不”实际上并不意味着有时,取决于语言,但在这种情况下可能不是。顶级建议...这个问题被标记为 c#,其中更改范围变量是合法的。

标签: c# .net for-loop


【解决方案1】:

由于您的 g 循环,您得到了所有重复项。对于每个不匹配的辅音,您正在将您正在查看的字符添加到您的目标字符串中。代码可以这样简化:

for(var e = 0; e < nyText.Length; e += 1) {
    newText2.Add(nyText[e].ToString());
    if(kons.Contains(nyText[e])) {
        e += 2;
    }
}

您可以通过将 kons 从 String 更改为 HashSet 的字符来提高 Contains 查找性能:

HashSet<char> kons = new HashSet<char>() {'B', 'C', 'D', /* etc... */ };

【讨论】:

  • 这绝对完美!而且对我来说理解起来并不复杂。我之前尝试过这样的事情,但还没有意识到skip 2。很抱歉,我没有支持投票的声誉,但我完全感谢你!
【解决方案2】:

试试这个

public string OversettTilbake(string kons)
{
   string nyText = textBox2.Text.ToString().ToLower();

   for (int f = 0; f < kons.Length; f++)
     nyText = nyText.Replace((kons[f] + "o" + kons[f]), kons[f].ToString());

   return nyText;
}

【讨论】:

  • +1 呵呵,现在那是优雅了。尽管有很多字符串复制:-)
  • @ThorstenDittmar 谢谢先生。我的想法是,既然你在翻译时用bob 替换b,为什么不在翻译时用b 替换bob
  • 非常感谢!这看起来非常好。我已经尝试在 List 中使用 replace 进行相同的操作,但由于数组大小,它返回错误。不知道我可以用字符串替换。
  • @user3515529 - 您不是在替换 in 字符串,而是在生成新字符串。这就是为什么它说nyText = nyText.Replace(..),这就是Thorsten 的“字符串复制”注释背后的原因(那些旧字符串需要由系统清理)。
  • 嗯……不过,看起来它的翻译是对的。
【解决方案3】:

问题在于“g”循环:几乎每个辅音都会出现不匹配的情况。

改为修改“f”循环,将“found”布尔值设置为“true”(在循环之前初始化为“false”)。如果未找到辅音,则它是元音(或其他字符),因此您可以添加它(一次!)。

编辑

int e = 0;
while (e < nyText.Length) // changed 'for' into 'while'
{
    bool found = false;
    for (int f = 0; f < kons.Length; f++)
    {
        if (nyText[e] == kons[f])
        {
            newText2.Add(nyText[e].ToString());
            e = e + 3;
            found = true;
            break; // break out of the 'for' loop: no need to test further after a match
        }
    }

    // no need for an extra 'mismatch-loop'
    if (!found)
    {
       newText2.Add(nyText[e].ToString());
       e = e + 1;
    }
}

【讨论】:

  • 感谢您的回复!我在这里了解了您所说的基础知识,但我并不能真正将其实现到我的代码中。你能再给我一些提示吗?
【解决方案4】:

以下代码有效,甚至只需要一个循环,因为您可以使用IndexOf 在字符串中进行搜索。另请注意,由于您的辅音数组定义为包含大写和小写字母,因此没有理由将输入转换为小写。第三,不要在方法中使用TextBox,而应将要转换的字符串作为参数传递。

static string kons = "BCDFGHJKLMNPQRSTVWZbcdfghjklmnpqrstvwz";

public static string OversettTilbake(string nyText)
{
    int stringIndex = 0;

    string result = String.Empty;
    while (stringIndex < nyText.Length)
    {
        result += nyText[stringIndex];
        if (kons.IndexOf(nyText[stringIndex]) > -1)
        {
            stringIndex += 3;
        }
        else
        {
            stringIndex++;
        }
    }

    return result;
}

这样称呼

Console.WriteLine(OversettTilbake("Totimom"));

实际上,您的代码很容易简化为只使用一个循环,因为规则是将一个辅音替换为 3 个字母。因此,您需要做的就是每当遇到辅音时,将其添加到结果中并跳过两个字母。就是这样。

请注意,在TextBox.Text 上调用ToString 是不必要的,因为Text 已经是一个字符串。

【讨论】:

  • 非常感谢您的意见! ToLower 的原因是当我输入大写字母时程序会崩溃。不知道为什么,因为它们在 kons 数组中表示。再次感谢所有的建议。不知道我可以像那样使字符串全局化。
【解决方案5】:
var newText2 = new StringBuilder();
string nyText = "totesostot1";
const string kons = "BCDFGHJKLMNPQRSTVWZbcdfghjklmnpqrstvwz";

// Loop through each leter
for (int e = 0; e < nyText.Length; e++)
{
    // Print the letter
    newText2.Append(nyText[e].ToString(CultureInfo.InvariantCulture));

    // If the letter exists in kons, skip the next 2 letters
    if (kons.Any(t => nyText[e] == t))
    { 
         e = e + 2;
    }
}

Console.WriteLine(newText2);

将输出 test1。

【讨论】:

  • 这看起来很棒。谢谢你。然而,它远远超出了我目前的技能和知识,我试图只实现我能理解的。
  • @user3515529 基本上kons.Any(...) 结构与kons.IndexOf(...) &gt; -1 相同。它搜索“kons 中是否有任何字符t 等于nyText[e]”。
  • 啊!我懂了。非常感谢您的清理!在我的下一个翻译项目之前,我会尝试掌握这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多